@@ -1479,12 +1479,19 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
1479
1479
if (type_is_ghost (elty))
1480
1480
return ghostValue (jltype);
1481
1481
AllocaInst *intcast = NULL ;
1482
- if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy () && !elty-> isFloatingPointTy () ) {
1482
+ if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy ()) {
1483
1483
const DataLayout &DL = jl_data_layout;
1484
1484
unsigned nb = DL.getTypeSizeInBits (elty);
1485
1485
intcast = ctx.builder .CreateAlloca (elty);
1486
1486
elty = Type::getIntNTy (jl_LLVMContext, nb);
1487
1487
}
1488
+ Type *realelty = elty;
1489
+ if (Order != AtomicOrdering::NotAtomic && isa<IntegerType>(elty)) {
1490
+ unsigned nb = cast<IntegerType>(elty)->getBitWidth ();
1491
+ unsigned nb2 = PowerOf2Ceil (nb);
1492
+ if (nb != nb2)
1493
+ elty = Type::getIntNTy (jl_LLVMContext, nb2);
1494
+ }
1488
1495
Type *ptrty = PointerType::get (elty, ptr->getType ()->getPointerAddressSpace ());
1489
1496
Value *data;
1490
1497
if (ptr->getType () != ptrty)
@@ -1493,7 +1500,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
1493
1500
data = ptr;
1494
1501
if (idx_0based)
1495
1502
data = ctx.builder .CreateInBoundsGEP (elty, data, idx_0based);
1496
- Instruction *load ;
1503
+ Value *instr ;
1497
1504
// TODO: can only lazy load if we can create a gc root for ptr for the lifetime of elt
1498
1505
// if (elty->isAggregateType() && tbaa == tbaa_immut && !alignment) { // can lazy load on demand, no copy needed
1499
1506
// elt = data;
@@ -1503,20 +1510,23 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
1503
1510
alignment = sizeof (void *);
1504
1511
else if (!alignment)
1505
1512
alignment = julia_alignment (jltype);
1506
- load = ctx.builder .CreateAlignedLoad (data, Align (alignment), false );
1507
- cast<LoadInst>( load) ->setOrdering (Order);
1513
+ LoadInst * load = ctx.builder .CreateAlignedLoad (data, Align (alignment), false );
1514
+ load->setOrdering (Order);
1508
1515
if (aliasscope)
1509
1516
load->setMetadata (" alias.scope" , aliasscope);
1510
1517
if (isboxed)
1511
- load = maybe_mark_load_dereferenceable (load, true , jltype);
1518
+ maybe_mark_load_dereferenceable (load, true , jltype);
1512
1519
if (tbaa)
1513
- load = tbaa_decorate (tbaa, load);
1520
+ tbaa_decorate (tbaa, load);
1521
+ instr = load;
1522
+ if (elty != realelty)
1523
+ instr = ctx.builder .CreateTrunc (instr, realelty);
1514
1524
if (intcast) {
1515
- ctx.builder .CreateStore (load , ctx.builder .CreateBitCast (intcast, load ->getType ()->getPointerTo ()));
1516
- load = ctx.builder .CreateLoad (intcast);
1525
+ ctx.builder .CreateStore (instr , ctx.builder .CreateBitCast (intcast, instr ->getType ()->getPointerTo ()));
1526
+ instr = ctx.builder .CreateLoad (intcast);
1517
1527
}
1518
1528
if (maybe_null_if_boxed) {
1519
- Value *first_ptr = isboxed ? load : extract_first_ptr (ctx, load );
1529
+ Value *first_ptr = isboxed ? instr : extract_first_ptr (ctx, instr );
1520
1530
if (first_ptr)
1521
1531
null_pointer_check (ctx, first_ptr, nullcheck);
1522
1532
}
@@ -1526,9 +1536,9 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
1526
1536
// load->setMetadata(LLVMContext::MD_range, MDNode::get(jl_LLVMContext, {
1527
1537
// ConstantAsMetadata::get(ConstantInt::get(T_int8, 0)),
1528
1538
// ConstantAsMetadata::get(ConstantInt::get(T_int8, 2)) }));
1529
- load = ctx.builder .Insert ( CastInst::Create (Instruction::Trunc, load, T_int1) );
1539
+ instr = ctx.builder .CreateTrunc (instr, T_int1);
1530
1540
}
1531
- return mark_julia_type (ctx, load , isboxed, jltype);
1541
+ return mark_julia_type (ctx, instr , isboxed, jltype);
1532
1542
}
1533
1543
1534
1544
static jl_cgval_t typed_store (jl_codectx_t &ctx,
@@ -1544,18 +1554,27 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1544
1554
if (type_is_ghost (elty))
1545
1555
return oldval;
1546
1556
Value *intcast = nullptr ;
1547
- if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy () && !elty-> isFloatingPointTy () ) {
1557
+ if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy ()) {
1548
1558
const DataLayout &DL = jl_data_layout;
1549
1559
unsigned nb = DL.getTypeSizeInBits (elty);
1550
1560
if (!issetfield)
1551
1561
intcast = ctx.builder .CreateAlloca (elty);
1552
1562
elty = Type::getIntNTy (jl_LLVMContext, nb);
1553
1563
}
1564
+ Type *realelty = elty;
1565
+ if (Order != AtomicOrdering::NotAtomic && isa<IntegerType>(elty)) {
1566
+ unsigned nb = cast<IntegerType>(elty)->getBitWidth ();
1567
+ unsigned nb2 = PowerOf2Ceil (nb);
1568
+ if (nb != nb2)
1569
+ elty = Type::getIntNTy (jl_LLVMContext, nb2);
1570
+ }
1554
1571
Value *r;
1555
1572
if (!isboxed)
1556
- r = emit_unbox (ctx, elty , rhs, jltype);
1573
+ r = emit_unbox (ctx, realelty , rhs, jltype);
1557
1574
else
1558
1575
r = boxed (ctx, rhs);
1576
+ if (realelty != elty)
1577
+ r = ctx.builder .CreateZExt (r, elty);
1559
1578
Type *ptrty = PointerType::get (elty, ptr->getType ()->getPointerAddressSpace ());
1560
1579
if (ptr->getType () != ptrty)
1561
1580
ptr = ctx.builder .CreateBitCast (ptr, ptrty);
@@ -1578,18 +1597,19 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1578
1597
instr->setMetadata (" noalias" , aliasscope);
1579
1598
if (tbaa)
1580
1599
tbaa_decorate (tbaa, instr);
1581
- }
1582
- if (isreplacefield) {
1583
- oldval = mark_julia_type (ctx, instr, isboxed, jltype);
1584
- Value *first_ptr = nullptr ;
1585
- if (maybe_null_if_boxed)
1586
- first_ptr = isboxed ? instr : extract_first_ptr (ctx, instr);
1587
- Success = emit_nullcheck_guard (ctx, first_ptr, [&] {
1588
- return emit_f_is (ctx, oldval, cmp);
1589
- });
1590
- BasicBlock *BB = BasicBlock::Create (jl_LLVMContext, " xchg" , ctx.f );
1591
- ctx.builder .CreateCondBr (Success, BB, DoneBB);
1592
- ctx.builder .SetInsertPoint (BB);
1600
+ assert (realelty == elty);
1601
+ if (isreplacefield) {
1602
+ oldval = mark_julia_type (ctx, instr, isboxed, jltype);
1603
+ Value *first_ptr = nullptr ;
1604
+ if (maybe_null_if_boxed)
1605
+ first_ptr = isboxed ? instr : extract_first_ptr (ctx, instr);
1606
+ Success = emit_nullcheck_guard (ctx, first_ptr, [&] {
1607
+ return emit_f_is (ctx, oldval, cmp);
1608
+ });
1609
+ BasicBlock *BB = BasicBlock::Create (jl_LLVMContext, " xchg" , ctx.f );
1610
+ ctx.builder .CreateCondBr (Success, BB, DoneBB);
1611
+ ctx.builder .SetInsertPoint (BB);
1612
+ }
1593
1613
}
1594
1614
StoreInst *store = ctx.builder .CreateAlignedStore (r, ptr, Align (alignment));
1595
1615
store->setOrdering (Order);
@@ -1628,7 +1648,9 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1628
1648
Current->addIncoming (instr, SkipBB);
1629
1649
ctx.builder .SetInsertPoint (BB);
1630
1650
}
1631
- Compare = emit_unbox (ctx, elty, cmp, jltype);
1651
+ Compare = emit_unbox (ctx, realelty, cmp, jltype);
1652
+ if (realelty != elty)
1653
+ Compare = ctx.builder .CreateZExt (Compare, elty);
1632
1654
}
1633
1655
else if (cmp.isboxed ) {
1634
1656
Compare = boxed (ctx, cmp);
@@ -1676,21 +1698,26 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1676
1698
if (tbaa)
1677
1699
tbaa_decorate (tbaa, store);
1678
1700
instr = ctx.builder .Insert (ExtractValueInst::Create (store, 0 ));
1679
- Success = ctx.builder .CreateExtractValue ( store, 1 );
1701
+ Success = ctx.builder .Insert ( ExtractValueInst::Create ( store, 1 ) );
1680
1702
Value *Done = Success;
1681
1703
if (needloop) {
1682
1704
if (isreplacefield) {
1705
+ Value *realinstr = instr;
1706
+ if (realelty != elty)
1707
+ realinstr = ctx.builder .CreateTrunc (instr, realelty);
1683
1708
if (intcast) {
1684
- ctx.builder .CreateStore (instr , ctx.builder .CreateBitCast (intcast, instr ->getType ()->getPointerTo ()));
1709
+ ctx.builder .CreateStore (realinstr , ctx.builder .CreateBitCast (intcast, realinstr ->getType ()->getPointerTo ()));
1685
1710
oldval = mark_julia_slot (intcast, jltype, NULL , tbaa_stack);
1711
+ if (maybe_null_if_boxed)
1712
+ realinstr = ctx.builder .CreateLoad (intcast);
1686
1713
}
1687
1714
else {
1688
- oldval = mark_julia_type (ctx, instr , isboxed, jltype);
1715
+ oldval = mark_julia_type (ctx, realinstr , isboxed, jltype);
1689
1716
}
1690
1717
Done = emit_guarded_test (ctx, ctx.builder .CreateNot (Success), false , [&] {
1691
1718
Value *first_ptr = nullptr ;
1692
1719
if (maybe_null_if_boxed)
1693
- first_ptr = isboxed ? instr : extract_first_ptr (ctx, instr );
1720
+ first_ptr = isboxed ? realinstr : extract_first_ptr (ctx, realinstr );
1694
1721
return emit_nullcheck_guard (ctx, first_ptr, [&] {
1695
1722
return emit_f_is (ctx, oldval, cmp);
1696
1723
});
@@ -1747,6 +1774,8 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1747
1774
}
1748
1775
}
1749
1776
if (!issetfield) {
1777
+ if (realelty != elty)
1778
+ instr = ctx.builder .Insert (CastInst::Create (Instruction::Trunc, instr, realelty));
1750
1779
if (intcast) {
1751
1780
ctx.builder .CreateStore (instr, ctx.builder .CreateBitCast (intcast, instr->getType ()->getPointerTo ()));
1752
1781
instr = ctx.builder .CreateLoad (intcast);
@@ -2053,6 +2082,9 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
2053
2082
emit_atomic_error (ctx, " getfield: atomic field cannot be accessed non-atomically" );
2054
2083
return jl_cgval_t (); // unreachable
2055
2084
}
2085
+ if (order == jl_memory_order_unspecified) {
2086
+ order = isatomic ? jl_memory_order_unordered : jl_memory_order_notatomic;
2087
+ }
2056
2088
if (jfty == jl_bottom_type) {
2057
2089
raise_exception (ctx, literal_pointer_val (ctx, jl_undefref_exception));
2058
2090
return jl_cgval_t (); // unreachable
@@ -2126,7 +2158,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
2126
2158
if (needlock)
2127
2159
emit_lockstate_value (ctx, strct, true );
2128
2160
jl_cgval_t ret = typed_load (ctx, addr, NULL , jfty, tbaa, nullptr , false ,
2129
- needlock || order <= jl_memory_order_notatomic ? AtomicOrdering::NotAtomic : get_llvm_atomic_order (order), // TODO: we should use unordered for anything with CountTrackedPointers(elty).count > 0
2161
+ needlock ? AtomicOrdering::NotAtomic : get_llvm_atomic_order (order), // TODO: we should use unordered for anything with CountTrackedPointers(elty).count > 0
2130
2162
maybe_null, align, nullcheck);
2131
2163
if (needlock)
2132
2164
emit_lockstate_value (ctx, strct, false );
0 commit comments