-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[UBSAN] Preserve ubsan code with ubsan-unique-traps #83470
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
Conversation
Removing `TrapBB->getParent()->size()` added with llvm#65972. Counter as-is is not very unique after inlining https://godbolt.org/z/4KfEKq7zb (see m()).
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Vitaly Buka (vitalybuka) ChangesRemoving Full diff: https://github.com/llvm/llvm-project/pull/83470.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 59a7fe8925001c..ee5f3a2786a627 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3826,11 +3826,9 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
Builder.CreateCondBr(Checked, Cont, TrapBB);
EmitBlock(TrapBB);
- llvm::CallInst *TrapCall = Builder.CreateCall(
- CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
- llvm::ConstantInt::get(CGM.Int8Ty, ClSanitizeDebugDeoptimization
- ? TrapBB->getParent()->size()
- : CheckHandlerID));
+ llvm::CallInst *TrapCall =
+ Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
+ llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
diff --git a/clang/test/CodeGen/bounds-checking.c b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
// CHECK-LABEL: @f8
void f8(int i, int k) {
// NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
- // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+ // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
B[i] = '\0';
// NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
- // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+ // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
B2[k] = '\0';
}
|
From #65972 (comment) Is this something you have planned to fix? If not would replacing the .size() counter with perhaps a seeded random uint8 be acceptable? My use case prevents me from shipping the minimal runtime alongside the instrumentation so my goal was to create an improvement (definitely imperfect!) to the debugability of a production deployment of BoundsSan. This PR as is would revert that behavior entirely. |
I don't plan to do anything about it. |
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.
If you are going to remove this feature, I would rather you simply revert the old commit. There is no point leaving the flag in at this point.
I had explored earlier dealing with the optimization at a later time in the compilation pipeline, but got nowhere and this solution was ideal for my use case, binary size constraints limited any inlining so I never ran into the issue. I appreciate you cleaning this up! :)
Actually I am here because I want to use the flag to avoid merging basic blocks. However I am considering introducing a special intrinsic for that, the this patch will not be needed. |
I changed my design, so I don't need this patch. |
I would prefer leaving it as is, I will make a note to revisit this pending further testing on my end to see how useful it really is. Thank you :) |
abandoning |
llvm#65972 (continuation of https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, but did not proceed with that because of llvm#53011. Instead, it added a counter (based on TrapBB->getParent()->size()) to each ubsantrap call. However, this counter is not guaranteed to be unique after inlining, as shown by llvm#83470, which can result in ubsantraps being merged by the backend. llvm#101549 fixed has since fixed the nomerge limitation ("It sets nomerge flag for the node if the instruction has nomerge arrtibute."). This patch therefore takes advantage of nomerge instead of using the counter, guaranteeing that the ubsantraps are not merged. This patch is equivalent to llvm#83470 but also adds nomerge and updates the test that was precommitted in llvm#117649.
…considered harmful This testcase demonstrates that when nomerge is missing from ubsantrap intrinsics, they may be merged when inlining. This is based on the observation and testcase by Vitaly Buka in llvm#83470
…117649) This test (copied from #83470) demonstrates that UBSan does not add the nomerge annotation. This is significant because it can result in them being merged by the backend, even when -ubsan-unique-traps is enabled. N.B. #65972 (continuation of https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, but did not proceed with that because of #53011. #101549 fixed that limitation ("It sets nomerge flag for the node if the instruction has nomerge arrtibute."); planned upcoming work (#117651) will add nomerge for ubsan.
llvm#65972 (continuation of https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, but did not proceed with that because of llvm#53011. Instead, it added a counter (based on TrapBB->getParent()->size()) to each ubsantrap call. However, this counter is not guaranteed to be unique after inlining, as shown by llvm#83470, which can result in ubsantraps being merged by the backend. llvm#101549 fixed has since fixed the nomerge limitation ("It sets nomerge flag for the node if the instruction has nomerge arrtibute."). This patch therefore takes advantage of nomerge instead of using the counter, guaranteeing that the ubsantraps are not merged. This patch is equivalent to llvm#83470 but also adds nomerge and updates the test that was precommitted in llvm#117649.
…nomerge" (llvm#117804) This reverts commit c8bdb31. It was reverted because I forgot to update the auto-generated assertions after adding the target triple. Original commit message: This test (copied from llvm#83470) demonstrates that UBSan does not add the nomerge annotation. This is significant because it can result in them being merged by the backend, even when -ubsan-unique-traps is enabled. N.B. llvm#65972 (continuation of https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, but did not proceed with that because of llvm#53011. llvm#101549 fixed that limitation ("It sets nomerge flag for the node if the instruction has nomerge arrtibute."); planned upcoming work (llvm#117651) will add nomerge for ubsan.
…nomerge" (#117804) (#117805) This reverts commit c8bdb31. It was reverted because I forgot to update the auto-generated assertions after adding the target triple. Original commit message: This test (copied from #83470) demonstrates that UBSan does not add the nomerge annotation. This is significant because it can result in them being merged by the backend, even when -ubsan-unique-traps is enabled. N.B. #65972 (continuation of https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, but did not proceed with that because of #53011. #101549 fixed that limitation ("It sets nomerge flag for the node if the instruction has nomerge arrtibute."); planned upcoming work (#117651) will add nomerge for ubsan.
llvm#65972 (continuation of https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, but did not proceed with that because of llvm#53011. Instead, it added a counter (based on TrapBB->getParent()->size()) to each ubsantrap call. However, this counter is not guaranteed to be unique after inlining, as shown by llvm#83470, which can result in ubsantraps being merged by the backend. llvm#101549 fixed has since fixed the nomerge limitation ("It sets nomerge flag for the node if the instruction has nomerge arrtibute."). This patch therefore takes advantage of nomerge instead of using the counter, guaranteeing that the ubsantraps are not merged. This patch is equivalent to llvm#83470 but also adds nomerge and updates the test that was precommitted in llvm#117649.
…117651) #65972 (continuation of https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, but did not proceed with that because of #53011. Instead, it added a counter (based on TrapBB->getParent()->size()) to each ubsantrap call. However, this counter is not guaranteed to be unique after inlining, as shown by #83470, which can result in ubsantraps being merged by the backend. #101549 has since fixed the nomerge limitation ("It sets nomerge flag for the node if the instruction has nomerge arrtibute."). This patch therefore takes advantage of nomerge instead of using the counter, guaranteeing that the ubsantraps are not merged. This patch is equivalent to #83470 but also adds nomerge and updates tests (#117649: ubsan-trap-merge.c; #117657: ubsan-trap-merge.ll, ubsan-trap-nomerge.ll; catch-undef-behavior.c).
Removing
TrapBB->getParent()->size()
added with #65972. Counter as-isis not very unique after inlining https://godbolt.org/z/4KfEKq7zb (see
m()).