@@ -1479,12 +1479,19 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
14791479 if (type_is_ghost (elty))
14801480 return ghostValue (jltype);
14811481 AllocaInst *intcast = NULL ;
1482- if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy () && !elty-> isFloatingPointTy () ) {
1482+ if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy ()) {
14831483 const DataLayout &DL = jl_data_layout;
14841484 unsigned nb = DL.getTypeSizeInBits (elty);
14851485 intcast = ctx.builder .CreateAlloca (elty);
14861486 elty = Type::getIntNTy (jl_LLVMContext, nb);
14871487 }
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+ }
14881495 Type *ptrty = PointerType::get (elty, ptr->getType ()->getPointerAddressSpace ());
14891496 Value *data;
14901497 if (ptr->getType () != ptrty)
@@ -1493,7 +1500,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
14931500 data = ptr;
14941501 if (idx_0based)
14951502 data = ctx.builder .CreateInBoundsGEP (elty, data, idx_0based);
1496- Instruction *load ;
1503+ Value *instr ;
14971504 // TODO: can only lazy load if we can create a gc root for ptr for the lifetime of elt
14981505 // if (elty->isAggregateType() && tbaa == tbaa_immut && !alignment) { // can lazy load on demand, no copy needed
14991506 // elt = data;
@@ -1503,20 +1510,23 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
15031510 alignment = sizeof (void *);
15041511 else if (!alignment)
15051512 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);
15081515 if (aliasscope)
15091516 load->setMetadata (" alias.scope" , aliasscope);
15101517 if (isboxed)
1511- load = maybe_mark_load_dereferenceable (load, true , jltype);
1518+ maybe_mark_load_dereferenceable (load, true , jltype);
15121519 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);
15141524 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);
15171527 }
15181528 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 );
15201530 if (first_ptr)
15211531 null_pointer_check (ctx, first_ptr, nullcheck);
15221532 }
@@ -1526,9 +1536,9 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
15261536 // load->setMetadata(LLVMContext::MD_range, MDNode::get(jl_LLVMContext, {
15271537 // ConstantAsMetadata::get(ConstantInt::get(T_int8, 0)),
15281538 // 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);
15301540 }
1531- return mark_julia_type (ctx, load , isboxed, jltype);
1541+ return mark_julia_type (ctx, instr , isboxed, jltype);
15321542}
15331543
15341544static jl_cgval_t typed_store (jl_codectx_t &ctx,
@@ -1544,18 +1554,27 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
15441554 if (type_is_ghost (elty))
15451555 return oldval;
15461556 Value *intcast = nullptr ;
1547- if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy () && !elty-> isFloatingPointTy () ) {
1557+ if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy ()) {
15481558 const DataLayout &DL = jl_data_layout;
15491559 unsigned nb = DL.getTypeSizeInBits (elty);
15501560 if (!issetfield)
15511561 intcast = ctx.builder .CreateAlloca (elty);
15521562 elty = Type::getIntNTy (jl_LLVMContext, nb);
15531563 }
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+ }
15541571 Value *r;
15551572 if (!isboxed)
1556- r = emit_unbox (ctx, elty , rhs, jltype);
1573+ r = emit_unbox (ctx, realelty , rhs, jltype);
15571574 else
15581575 r = boxed (ctx, rhs);
1576+ if (realelty != elty)
1577+ r = ctx.builder .CreateZExt (r, elty);
15591578 Type *ptrty = PointerType::get (elty, ptr->getType ()->getPointerAddressSpace ());
15601579 if (ptr->getType () != ptrty)
15611580 ptr = ctx.builder .CreateBitCast (ptr, ptrty);
@@ -1578,18 +1597,19 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
15781597 instr->setMetadata (" noalias" , aliasscope);
15791598 if (tbaa)
15801599 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+ }
15931613 }
15941614 StoreInst *store = ctx.builder .CreateAlignedStore (r, ptr, Align (alignment));
15951615 store->setOrdering (Order);
@@ -1628,7 +1648,9 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
16281648 Current->addIncoming (instr, SkipBB);
16291649 ctx.builder .SetInsertPoint (BB);
16301650 }
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);
16321654 }
16331655 else if (cmp.isboxed ) {
16341656 Compare = boxed (ctx, cmp);
@@ -1676,21 +1698,26 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
16761698 if (tbaa)
16771699 tbaa_decorate (tbaa, store);
16781700 instr = ctx.builder .Insert (ExtractValueInst::Create (store, 0 ));
1679- Success = ctx.builder .CreateExtractValue ( store, 1 );
1701+ Success = ctx.builder .Insert ( ExtractValueInst::Create ( store, 1 ) );
16801702 Value *Done = Success;
16811703 if (needloop) {
16821704 if (isreplacefield) {
1705+ Value *realinstr = instr;
1706+ if (realelty != elty)
1707+ realinstr = ctx.builder .CreateTrunc (instr, realelty);
16831708 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 ()));
16851710 oldval = mark_julia_slot (intcast, jltype, NULL , tbaa_stack);
1711+ if (maybe_null_if_boxed)
1712+ realinstr = ctx.builder .CreateLoad (intcast);
16861713 }
16871714 else {
1688- oldval = mark_julia_type (ctx, instr , isboxed, jltype);
1715+ oldval = mark_julia_type (ctx, realinstr , isboxed, jltype);
16891716 }
16901717 Done = emit_guarded_test (ctx, ctx.builder .CreateNot (Success), false , [&] {
16911718 Value *first_ptr = nullptr ;
16921719 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 );
16941721 return emit_nullcheck_guard (ctx, first_ptr, [&] {
16951722 return emit_f_is (ctx, oldval, cmp);
16961723 });
@@ -1747,6 +1774,8 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
17471774 }
17481775 }
17491776 if (!issetfield) {
1777+ if (realelty != elty)
1778+ instr = ctx.builder .Insert (CastInst::Create (Instruction::Trunc, instr, realelty));
17501779 if (intcast) {
17511780 ctx.builder .CreateStore (instr, ctx.builder .CreateBitCast (intcast, instr->getType ()->getPointerTo ()));
17521781 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
20532082 emit_atomic_error (ctx, " getfield: atomic field cannot be accessed non-atomically" );
20542083 return jl_cgval_t (); // unreachable
20552084 }
2085+ if (order == jl_memory_order_unspecified) {
2086+ order = isatomic ? jl_memory_order_unordered : jl_memory_order_notatomic;
2087+ }
20562088 if (jfty == jl_bottom_type) {
20572089 raise_exception (ctx, literal_pointer_val (ctx, jl_undefref_exception));
20582090 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
21262158 if (needlock)
21272159 emit_lockstate_value (ctx, strct, true );
21282160 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
21302162 maybe_null, align, nullcheck);
21312163 if (needlock)
21322164 emit_lockstate_value (ctx, strct, false );
0 commit comments