-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TSan] Fix atomicrmw xchg with pointer and floats #85228
Conversation
atomicrmw xchg also accepts pointer and floating-point values. To handle those, insert a necessary casts to and from integer. This is what we do for cmpxchg as well.
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-compiler-rt-sanitizer Author: Nikita Popov (nikic) Changesatomicrmw xchg also accepts pointer and floating-point values. To handle those, insert a necessary casts to and from integer. This is what we do for cmpxchg as well. Full diff: https://github.com/llvm/llvm-project/pull/85228.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
index 8ee0bca7e354f0..0f42ff79086994 100644
--- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
@@ -752,11 +752,12 @@ bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) {
const unsigned ByteSize = 1U << Idx;
const unsigned BitSize = ByteSize * 8;
Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize);
- Value *Args[] = {Addr,
- IRB.CreateIntCast(RMWI->getValOperand(), Ty, false),
+ Value *Val = RMWI->getValOperand();
+ Value *Args[] = {Addr, IRB.CreateBitOrPointerCast(Val, Ty),
createOrdering(&IRB, RMWI->getOrdering())};
- CallInst *C = CallInst::Create(F, Args);
- ReplaceInstWithInst(I, C);
+ Value *C = IRB.CreateCall(F, Args);
+ I->replaceAllUsesWith(IRB.CreateBitOrPointerCast(C, Val->getType()));
+ I->eraseFromParent();
} else if (AtomicCmpXchgInst *CASI = dyn_cast<AtomicCmpXchgInst>(I)) {
Value *Addr = CASI->getPointerOperand();
Type *OrigOldValTy = CASI->getNewValOperand()->getType();
diff --git a/llvm/test/Instrumentation/ThreadSanitizer/atomic.ll b/llvm/test/Instrumentation/ThreadSanitizer/atomic.ll
index 76afc4bf007c2d..8b387cd4962979 100644
--- a/llvm/test/Instrumentation/ThreadSanitizer/atomic.ll
+++ b/llvm/test/Instrumentation/ThreadSanitizer/atomic.ll
@@ -78,6 +78,26 @@ entry:
; CHECK-LABEL: atomic8_xchg_monotonic
; CHECK: call i8 @__tsan_atomic8_exchange(ptr %a, i8 0, i32 0), !dbg
+define void @atomic8_xchg_monotonic_ptr(ptr %a, ptr %b) nounwind uwtable {
+entry:
+ atomicrmw xchg ptr %a, ptr %b monotonic, !dbg !7
+ ret void, !dbg !7
+}
+; CHECK-LABEL: atomic8_xchg_monotonic_ptr
+; CHECK: [[ARG:%.*]] = ptrtoint ptr %b to i64, !dbg
+; CHECK: [[RES:%.*]] = call i64 @__tsan_atomic64_exchange(ptr %a, i64 [[ARG]], i32 0), !dbg
+; CHECK: [[CAST:%.*]] = inttoptr i64 [[RES]] to ptr, !dbg
+
+define void @atomic8_xchg_monotonic_float(ptr %a, float %b) nounwind uwtable {
+entry:
+ atomicrmw xchg ptr %a, float %b monotonic, !dbg !7
+ ret void, !dbg !7
+}
+; CHECK-LABEL: atomic8_xchg_monotonic_float
+; CHECK: [[ARG:%.*]] = bitcast float %b to i32, !dbg
+; CHECK: [[RES:%.*]] = call i32 @__tsan_atomic32_exchange(ptr %a, i32 [[ARG]], i32 0), !dbg
+; CHECK: [[CAST:%.*]] = bitcast i32 [[RES]] to float, !dbg
+
define void @atomic8_add_monotonic(ptr %a) nounwind uwtable {
entry:
atomicrmw add ptr %a, i8 0 monotonic, !dbg !7
|
CallInst *C = CallInst::Create(F, Args); | ||
ReplaceInstWithInst(I, C); | ||
Value *C = IRB.CreateCall(F, Args); | ||
I->replaceAllUsesWith(IRB.CreateBitOrPointerCast(C, Val->getType())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like replaceAllUsesWith/eraseFromParent
matches ReplaceInstWithInst
However, could we keep code consistent?
Replacing all places in a separate patch LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I changed this is that we now go through IRBuilder, which will insert the instructions itself, so we can no longer use ReplaceInstWithInst. This is also why the cmpxchg code does the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converted the remaining uses in 8a237ab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
atomicrmw xchg also accepts pointer and floating-point values. To handle those, insert necessary casts to and from integer. This is what we do for cmpxchg as well. Fixes llvm#85226. (cherry picked from commit ff2fb2a)
atomicrmw xchg also accepts pointer and floating-point values. To handle those, insert necessary casts to and from integer. This is what we do for cmpxchg as well. Fixes llvm#85226. (cherry picked from commit ff2fb2a)
atomicrmw xchg also accepts pointer and floating-point values. To handle those, insert a necessary casts to and from integer. This is what we do for cmpxchg as well.
Fixes #85226.