Skip to content

Commit

Permalink
threads: fix semantic error in old Threads.Atomic
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Sep 1, 2021
1 parent 4598966 commit aa421ff
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
12 changes: 6 additions & 6 deletions base/atomics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -356,13 +356,13 @@ for typ in atomictypes
rt = "$lt, $lt*"
irt = "$ilt, $ilt*"
@eval getindex(x::Atomic{$typ}) =
llvmcall($"""
GC.@preserve x llvmcall($"""
%ptr = inttoptr i$WORD_SIZE %0 to $lt*
%rv = load atomic $rt %ptr acquire, align $(gc_alignment(typ))
ret $lt %rv
""", $typ, Tuple{Ptr{$typ}}, unsafe_convert(Ptr{$typ}, x))
@eval setindex!(x::Atomic{$typ}, v::$typ) =
llvmcall($"""
GC.@preserve x llvmcall($"""
%ptr = inttoptr i$WORD_SIZE %0 to $lt*
store atomic $lt %1, $lt* %ptr release, align $(gc_alignment(typ))
ret void
Expand All @@ -371,7 +371,7 @@ for typ in atomictypes
# Note: atomic_cas! succeeded (i.e. it stored "new") if and only if the result is "cmp"
if typ <: Integer
@eval atomic_cas!(x::Atomic{$typ}, cmp::$typ, new::$typ) =
llvmcall($"""
GC.@preserve x llvmcall($"""
%ptr = inttoptr i$WORD_SIZE %0 to $lt*
%rs = cmpxchg $lt* %ptr, $lt %1, $lt %2 acq_rel acquire
%rv = extractvalue { $lt, i1 } %rs, 0
Expand All @@ -380,7 +380,7 @@ for typ in atomictypes
unsafe_convert(Ptr{$typ}, x), cmp, new)
else
@eval atomic_cas!(x::Atomic{$typ}, cmp::$typ, new::$typ) =
llvmcall($"""
GC.@preserve x llvmcall($"""
%iptr = inttoptr i$WORD_SIZE %0 to $ilt*
%icmp = bitcast $lt %1 to $ilt
%inew = bitcast $lt %2 to $ilt
Expand All @@ -403,15 +403,15 @@ for typ in atomictypes
if rmwop in arithmetic_ops && !(typ <: ArithmeticTypes) continue end
if typ <: Integer
@eval $fn(x::Atomic{$typ}, v::$typ) =
llvmcall($"""
GC.@preserve x llvmcall($"""
%ptr = inttoptr i$WORD_SIZE %0 to $lt*
%rv = atomicrmw $rmw $lt* %ptr, $lt %1 acq_rel
ret $lt %rv
""", $typ, Tuple{Ptr{$typ}, $typ}, unsafe_convert(Ptr{$typ}, x), v)
else
rmwop === :xchg || continue
@eval $fn(x::Atomic{$typ}, v::$typ) =
llvmcall($"""
GC.@preserve x llvmcall($"""
%iptr = inttoptr i$WORD_SIZE %0 to $ilt*
%ival = bitcast $lt %1 to $ilt
%irv = atomicrmw $rmw $ilt* %iptr, $ilt %ival acq_rel
Expand Down
31 changes: 31 additions & 0 deletions src/llvm-alloc-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,21 @@ void Optimizer::checkInst(Instruction *I)
use_info.hasunknownmem = true;
return true;
}
if (isa<AtomicCmpXchgInst>(inst) || isa<AtomicRMWInst>(inst)) {
// Only store value count
if (use->getOperandNo() != isa<AtomicCmpXchgInst>(inst) ? AtomicCmpXchgInst::getPointerOperandIndex() : AtomicRMWInst::getPointerOperandIndex()) {
use_info.escaped = true;
return false;
}
use_info.hasload = true;
auto storev = isa<AtomicCmpXchgInst>(inst) ? cast<AtomicCmpXchgInst>(inst)->getNewValOperand() : cast<AtomicRMWInst>(inst)->getValOperand();
if (cur.offset == UINT32_MAX || !use_info.addMemOp(inst, use->getOperandNo(),
cur.offset, storev->getType(),
true, *pass.DL))
use_info.hasunknownmem = true;
use_info.refload = true;
return true;
}
if (isa<AddrSpaceCastInst>(inst) || isa<BitCastInst>(inst)) {
push_inst(inst);
return true;
Expand Down Expand Up @@ -1331,6 +1346,22 @@ void Optimizer::splitOnStack(CallInst *orig_inst)
store->eraseFromParent();
return;
}
else if (isa<AtomicCmpXchgInst>(user) || isa<AtomicRMWInst>(user)) {
auto slot_idx = find_slot(offset);
auto &slot = slots[slot_idx];
assert(slot.offset <= offset && slot.offset + slot.size >= offset);
IRBuilder<> builder(user);
Value *newptr;
if (slot.isref) {
assert(slot.offset == offset);
newptr = slot.slot;
}
else {
Value *Val = isa<AtomicCmpXchgInst>(user) ? cast<AtomicCmpXchgInst>(user)->getNewValOperand() : cast<AtomicRMWInst>(user)->getValOperand();
newptr = slot_gep(slot, offset, Val->getType(), builder);
}
*use = newptr;
}
else if (auto call = dyn_cast<CallInst>(user)) {
auto callee = call->getCalledOperand();
assert(callee); // makes it clear for clang analyser that `callee` is not NULL
Expand Down

0 comments on commit aa421ff

Please sign in to comment.