Skip to content

[Clang] Fix nomerge attribute not working with __builtin_trap(), __debugbreak(), __builtin_verbose_trap() #101549

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

Merged
merged 1 commit into from
Aug 1, 2024

Conversation

ZequanWu
Copy link
Contributor

@ZequanWu ZequanWu commented Aug 1, 2024

  1. It fixes the problem that llvm.trap() not getting the nomerge attribute.
  2. It sets nomerge flag for the node if the instruction has nomerge arrtibute.

This is a copy of https://reviews.llvm.org/D146164. This only attempts to fix nomerge for __builtin_trap(), __debugbreak(), __builtin_verbose_trap(), not working for non-trap builtins.

Fixes #53011

@ZequanWu ZequanWu requested a review from rnk August 1, 2024 19:09
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:X86 clang:codegen IR generation bugs: mangling, exceptions, etc. llvm:SelectionDAG SelectionDAGISel as well labels Aug 1, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 1, 2024

@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-llvm-selectiondag

Author: Zequan Wu (ZequanWu)

Changes
  1. It fixes the problem that llvm.trap() not getting the nomerge attribute.
  2. It sets nomerge flag for the node if the instruction has nomerge arrtibute.

This is a copy of https://reviews.llvm.org/D146164. This only attempts to fixe nomerge for __builtin_trap(), __debugbreak(), __builtin_verbose_trap(), not working for non-trap builtins.

Fixes #53011


Full diff: https://github.com/llvm/llvm-project/pull/101549.diff

4 Files Affected:

  • (modified) clang/lib/CodeGen/CGExpr.cpp (+2)
  • (modified) clang/test/CodeGen/attr-nomerge.cpp (+7-1)
  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+3-1)
  • (modified) llvm/test/CodeGen/X86/nomerge.ll (+92)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 5f58a64d8386c..9f18642ebbbf2 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3883,6 +3883,8 @@ llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
     TrapCall->addFnAttr(A);
   }
 
+  if (InNoMergeAttributedStmt)
+    TrapCall->addFnAttr(llvm::Attribute::NoMerge);
   return TrapCall;
 }
 
diff --git a/clang/test/CodeGen/attr-nomerge.cpp b/clang/test/CodeGen/attr-nomerge.cpp
index 7305fb73cf1dc..b643920adde49 100644
--- a/clang/test/CodeGen/attr-nomerge.cpp
+++ b/clang/test/CodeGen/attr-nomerge.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -fms-extensions -o - | FileCheck %s
 
 class A {
 public:
@@ -42,6 +42,9 @@ void foo(int i, A *ap, B *bp) {
 
   A *newA = new B();
   delete newA;
+  [[clang::nomerge]] __builtin_trap();
+  [[clang::nomerge]] __debugbreak();
+  [[clang::nomerge]] __builtin_verbose_trap("check null", "Argument must not be null.");
 }
 
 int g(int i);
@@ -97,6 +100,9 @@ void something_else_again() {
 // CHECK: load ptr, ptr
 // CHECK: %[[AG:.*]] = load ptr, ptr
 // CHECK-NEXT: call void %[[AG]](ptr {{.*}}) #[[ATTR1]]
+// CHECK: call void @llvm.trap() #[[ATTR0]]
+// CHECK: call void @llvm.debugtrap() #[[ATTR0]]
+// CHECK: call void @llvm.trap() #[[ATTR0]]
 // CHECK: call void  @_ZN1AD1Ev(ptr {{.*}}) #[[ATTR1]]
 
 // CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 9f5e6466309e9..a035fee6aafca 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7448,6 +7448,8 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
         break;
       default: llvm_unreachable("unknown trap intrinsic");
       }
+      DAG.addNoMergeSiteInfo(DAG.getRoot().getNode(),
+                             I.hasFnAttr(Attribute::NoMerge));
       return;
     }
     TargetLowering::ArgListTy Args;
@@ -7464,7 +7466,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
         DAG.getExternalSymbol(TrapFuncName.data(),
                               TLI.getPointerTy(DAG.getDataLayout())),
         std::move(Args));
-
+    CLI.NoMerge = I.hasFnAttr(Attribute::NoMerge);
     std::pair<SDValue, SDValue> Result = TLI.LowerCallTo(CLI);
     DAG.setRoot(Result.second);
     return;
diff --git a/llvm/test/CodeGen/X86/nomerge.ll b/llvm/test/CodeGen/X86/nomerge.ll
index efbadf5b6911f..d3e6feae87108 100644
--- a/llvm/test/CodeGen/X86/nomerge.ll
+++ b/llvm/test/CodeGen/X86/nomerge.ll
@@ -62,4 +62,96 @@ if.end:
 
 declare dso_local void @bar()
 
+define void @nomerge_trap(i32 %i) {
+; CHECK-LABEL: nomerge_trap:
+; CHECK:      # %bb.0: # %entry
+; CHECK:      # %bb.1: # %entry
+; CHECK:      # %bb.2: # %if.then
+; CHECK-NEXT: ud2
+; CHECK-NEXT: LBB1_3: # %if.then2
+; CHECK-NEXT: ud2
+; CHECK-NEXT: .LBB1_4: # %if.end3
+; CHECK-NEXT: ud2
+entry:
+  switch i32 %i, label %if.end3 [
+    i32 5, label %if.then
+    i32 7, label %if.then2
+  ]
+
+if.then:
+  tail call void @llvm.trap() #0
+  unreachable
+
+if.then2:
+  tail call void @llvm.trap() #0
+  unreachable
+
+if.end3:
+  tail call void @llvm.trap() #0
+  unreachable
+}
+
+declare dso_local void @llvm.trap()
+
+define void @nomerge_debugtrap(i32 %i) {
+; CHECK-LABEL: nomerge_debugtrap:
+; CHECK:      # %bb.0: # %entry
+; CHECK:      # %bb.1: # %entry
+; CHECK:      # %bb.2: # %if.then
+; CHECK-NEXT: int3
+; CHECK-NEXT: LBB2_3: # %if.then2
+; CHECK-NEXT: int3
+; CHECK-NEXT: .LBB2_4: # %if.end3
+; CHECK-NEXT: int3
+entry:
+  switch i32 %i, label %if.end3 [
+    i32 5, label %if.then
+    i32 7, label %if.then2
+  ]
+
+if.then:
+  tail call void @llvm.debugtrap() #0
+  unreachable
+
+if.then2:
+  tail call void @llvm.debugtrap() #0
+  unreachable
+
+if.end3:
+  tail call void @llvm.debugtrap() #0
+  unreachable
+}
+
+define void @nomerge_named_debugtrap(i32 %i) {
+; CHECK-LABEL: nomerge_named_debugtrap:
+; CHECK:      # %bb.0: # %entry
+; CHECK:      # %bb.1: # %entry
+; CHECK:      # %bb.2: # %if.then
+; CHECK-NEXT: callq trap_func@PLT
+; CHECK-NEXT: LBB3_3: # %if.then2
+; CHECK-NEXT: callq trap_func@PLT
+; CHECK-NEXT: .LBB3_4: # %if.end3
+; CHECK-NEXT: callq trap_func@PLT
+entry:
+  switch i32 %i, label %if.end3 [
+    i32 5, label %if.then
+    i32 7, label %if.then2
+  ]
+
+if.then:
+  tail call void @llvm.debugtrap() #1
+  unreachable
+
+if.then2:
+  tail call void @llvm.debugtrap() #1
+  unreachable
+
+if.end3:
+  tail call void @llvm.debugtrap() #1
+  unreachable
+}
+
+declare dso_local void @llvm.debugtrap()
+
 attributes #0 = { nomerge }
+attributes #1 = { nomerge "trap-func-name"="trap_func" }

@llvmbot
Copy link
Member

llvmbot commented Aug 1, 2024

@llvm/pr-subscribers-clang-codegen

Author: Zequan Wu (ZequanWu)

Changes
  1. It fixes the problem that llvm.trap() not getting the nomerge attribute.
  2. It sets nomerge flag for the node if the instruction has nomerge arrtibute.

This is a copy of https://reviews.llvm.org/D146164. This only attempts to fixe nomerge for __builtin_trap(), __debugbreak(), __builtin_verbose_trap(), not working for non-trap builtins.

Fixes #53011


Full diff: https://github.com/llvm/llvm-project/pull/101549.diff

4 Files Affected:

  • (modified) clang/lib/CodeGen/CGExpr.cpp (+2)
  • (modified) clang/test/CodeGen/attr-nomerge.cpp (+7-1)
  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+3-1)
  • (modified) llvm/test/CodeGen/X86/nomerge.ll (+92)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 5f58a64d8386c..9f18642ebbbf2 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3883,6 +3883,8 @@ llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
     TrapCall->addFnAttr(A);
   }
 
+  if (InNoMergeAttributedStmt)
+    TrapCall->addFnAttr(llvm::Attribute::NoMerge);
   return TrapCall;
 }
 
diff --git a/clang/test/CodeGen/attr-nomerge.cpp b/clang/test/CodeGen/attr-nomerge.cpp
index 7305fb73cf1dc..b643920adde49 100644
--- a/clang/test/CodeGen/attr-nomerge.cpp
+++ b/clang/test/CodeGen/attr-nomerge.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -fms-extensions -o - | FileCheck %s
 
 class A {
 public:
@@ -42,6 +42,9 @@ void foo(int i, A *ap, B *bp) {
 
   A *newA = new B();
   delete newA;
+  [[clang::nomerge]] __builtin_trap();
+  [[clang::nomerge]] __debugbreak();
+  [[clang::nomerge]] __builtin_verbose_trap("check null", "Argument must not be null.");
 }
 
 int g(int i);
@@ -97,6 +100,9 @@ void something_else_again() {
 // CHECK: load ptr, ptr
 // CHECK: %[[AG:.*]] = load ptr, ptr
 // CHECK-NEXT: call void %[[AG]](ptr {{.*}}) #[[ATTR1]]
+// CHECK: call void @llvm.trap() #[[ATTR0]]
+// CHECK: call void @llvm.debugtrap() #[[ATTR0]]
+// CHECK: call void @llvm.trap() #[[ATTR0]]
 // CHECK: call void  @_ZN1AD1Ev(ptr {{.*}}) #[[ATTR1]]
 
 // CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 9f5e6466309e9..a035fee6aafca 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7448,6 +7448,8 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
         break;
       default: llvm_unreachable("unknown trap intrinsic");
       }
+      DAG.addNoMergeSiteInfo(DAG.getRoot().getNode(),
+                             I.hasFnAttr(Attribute::NoMerge));
       return;
     }
     TargetLowering::ArgListTy Args;
@@ -7464,7 +7466,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
         DAG.getExternalSymbol(TrapFuncName.data(),
                               TLI.getPointerTy(DAG.getDataLayout())),
         std::move(Args));
-
+    CLI.NoMerge = I.hasFnAttr(Attribute::NoMerge);
     std::pair<SDValue, SDValue> Result = TLI.LowerCallTo(CLI);
     DAG.setRoot(Result.second);
     return;
diff --git a/llvm/test/CodeGen/X86/nomerge.ll b/llvm/test/CodeGen/X86/nomerge.ll
index efbadf5b6911f..d3e6feae87108 100644
--- a/llvm/test/CodeGen/X86/nomerge.ll
+++ b/llvm/test/CodeGen/X86/nomerge.ll
@@ -62,4 +62,96 @@ if.end:
 
 declare dso_local void @bar()
 
+define void @nomerge_trap(i32 %i) {
+; CHECK-LABEL: nomerge_trap:
+; CHECK:      # %bb.0: # %entry
+; CHECK:      # %bb.1: # %entry
+; CHECK:      # %bb.2: # %if.then
+; CHECK-NEXT: ud2
+; CHECK-NEXT: LBB1_3: # %if.then2
+; CHECK-NEXT: ud2
+; CHECK-NEXT: .LBB1_4: # %if.end3
+; CHECK-NEXT: ud2
+entry:
+  switch i32 %i, label %if.end3 [
+    i32 5, label %if.then
+    i32 7, label %if.then2
+  ]
+
+if.then:
+  tail call void @llvm.trap() #0
+  unreachable
+
+if.then2:
+  tail call void @llvm.trap() #0
+  unreachable
+
+if.end3:
+  tail call void @llvm.trap() #0
+  unreachable
+}
+
+declare dso_local void @llvm.trap()
+
+define void @nomerge_debugtrap(i32 %i) {
+; CHECK-LABEL: nomerge_debugtrap:
+; CHECK:      # %bb.0: # %entry
+; CHECK:      # %bb.1: # %entry
+; CHECK:      # %bb.2: # %if.then
+; CHECK-NEXT: int3
+; CHECK-NEXT: LBB2_3: # %if.then2
+; CHECK-NEXT: int3
+; CHECK-NEXT: .LBB2_4: # %if.end3
+; CHECK-NEXT: int3
+entry:
+  switch i32 %i, label %if.end3 [
+    i32 5, label %if.then
+    i32 7, label %if.then2
+  ]
+
+if.then:
+  tail call void @llvm.debugtrap() #0
+  unreachable
+
+if.then2:
+  tail call void @llvm.debugtrap() #0
+  unreachable
+
+if.end3:
+  tail call void @llvm.debugtrap() #0
+  unreachable
+}
+
+define void @nomerge_named_debugtrap(i32 %i) {
+; CHECK-LABEL: nomerge_named_debugtrap:
+; CHECK:      # %bb.0: # %entry
+; CHECK:      # %bb.1: # %entry
+; CHECK:      # %bb.2: # %if.then
+; CHECK-NEXT: callq trap_func@PLT
+; CHECK-NEXT: LBB3_3: # %if.then2
+; CHECK-NEXT: callq trap_func@PLT
+; CHECK-NEXT: .LBB3_4: # %if.end3
+; CHECK-NEXT: callq trap_func@PLT
+entry:
+  switch i32 %i, label %if.end3 [
+    i32 5, label %if.then
+    i32 7, label %if.then2
+  ]
+
+if.then:
+  tail call void @llvm.debugtrap() #1
+  unreachable
+
+if.then2:
+  tail call void @llvm.debugtrap() #1
+  unreachable
+
+if.end3:
+  tail call void @llvm.debugtrap() #1
+  unreachable
+}
+
+declare dso_local void @llvm.debugtrap()
+
 attributes #0 = { nomerge }
+attributes #1 = { nomerge "trap-func-name"="trap_func" }

Copy link
Collaborator

@rnk rnk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Richard had a comment on the original which I think it still relevant:

There are 496 calls to Builder.CreateCall in clang's CodeGen. Do they all need this change? If not, how can we be confident we've found all the ones that do? (From a quick check, at least MSVC's __fastfail builtin seems like it would also benefit from this handling.)

Would it be reasonable to make clang's CGBuilder do this for every call instruction we create?

I think we could still do this, but we should fix this long outstanding bug first.

@ZequanWu
Copy link
Contributor Author

ZequanWu commented Aug 1, 2024

Richard had a comment on the original which I think it still relevant:

There are 496 calls to Builder.CreateCall in clang's CodeGen. Do they all need this change? If not, how can we be confident we've found all the ones that do? (From a quick check, at least MSVC's __fastfail builtin seems like it would also benefit from this handling.)
Would it be reasonable to make clang's CGBuilder do this for every call instruction we create?

I think we could still do this, but we should fix this long outstanding bug first.

Yeah, it would be easier if there's one place to attach statement attributes on all expressions inside that statement.

@ZequanWu ZequanWu merged commit 5e84646 into llvm:main Aug 1, 2024
9 of 11 checks passed
@zeroomega
Copy link
Contributor

Hi,
We are seeing test failures on LLVM :: CodeGen/X86/nomerge.ll and LLVM :: MC/AArch64/local-bounds-single-trap.ll after this change was landed:

Error message:

Exit Code: 1

Command Output (stderr):
--
RUN: at line 2: /b/s/w/ir/x/w/llvm_build/bin/llc < /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/CodeGen/X86/nomerge.ll -mtriple=x86_64 -o - | /b/s/w/ir/x/w/llvm_build/bin/FileCheck /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/CodeGen/X86/nomerge.ll
+ /b/s/w/ir/x/w/llvm_build/bin/llc -mtriple=x86_64 -o -
+ /b/s/w/ir/x/w/llvm_build/bin/FileCheck /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/CodeGen/X86/nomerge.ll
/b/s/w/ir/x/w/llvm-llvm-project/llvm/test/CodeGen/X86/nomerge.ll:71:15: error: CHECK-NEXT: expected string not found in input
; CHECK-NEXT: LBB1_3: # %if.then2
              ^
<stdin>:50:5: note: scanning from here
 ud2
    ^
<stdin>:51:2: note: possible intended match here
.LBB2_3: # %if.then2
 ^
/b/s/w/ir/x/w/llvm-llvm-project/llvm/test/CodeGen/X86/nomerge.ll:102:15: error: CHECK-NEXT: expected string not found in input
; CHECK-NEXT: LBB2_3: # %if.then2
              ^
<stdin>:71:6: note: scanning from here
 int3
     ^
<stdin>:72:2: note: possible intended match here
.LBB3_3: # %if.then2
 ^
/b/s/w/ir/x/w/llvm-llvm-project/llvm/test/CodeGen/X86/nomerge.ll:131:15: error: CHECK-NEXT: expected string not found in input
; CHECK-NEXT: LBB3_3: # %if.then2
              ^
<stdin>:94:21: note: scanning from here
 callq trap_func@PLT
                    ^
<stdin>:95:2: note: possible intended match here
.LBB4_3: # %if.then2
 ^

Input file: <stdin>
Check file: /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/CodeGen/X86/nomerge.ll

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            .
            .
            .
           45:  je .LBB2_3 
           46: # %bb.1: # %entry 
           47:  cmpl $5, %edi 
           48:  jne .LBB2_4 
           49: # %bb.2: # %if.then 
           50:  ud2 
next:71'0          X error: no match found
           51: .LBB2_3: # %if.then2 
next:71'0      ~~~~~~~~~~~~~~~~~~~~~
next:71'1       ?                    possible intended match
           52:  ud2 
next:71'0      ~~~~~
           53: .LBB2_4: # %if.end3 
next:71'0      ~~~~~~~~~~~~~~~~~~~~
           54:  ud2 
next:71'0      ~~~~~
           55: .Lfunc_end2: 
next:71'0      ~~~~~~~~~~~~~
           56:  .size nomerge_trap, .Lfunc_end2-nomerge_trap 
next:71'0      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            .
            .
            .
           66:  je .LBB3_3 
           67: # %bb.1: # %entry 
           68:  cmpl $5, %edi 
           69:  jne .LBB3_4 
           70: # %bb.2: # %if.then 
           71:  int3 
next:102'0          X error: no match found
           72: .LBB3_3: # %if.then2 
next:102'0     ~~~~~~~~~~~~~~~~~~~~~
next:102'1      ?                    possible intended match
           73:  int3 
next:102'0     ~~~~~~
           74: .LBB3_4: # %if.end3 
next:102'0     ~~~~~~~~~~~~~~~~~~~~
           75:  int3 
next:102'0     ~~~~~~
           76: .Lfunc_end3: 
next:102'0     ~~~~~~~~~~~~~
           77:  .size nomerge_debugtrap, .Lfunc_end3-nomerge_debugtrap 
next:102'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            .
            .
            .
           89:  je .LBB4_3 
           90: # %bb.1: # %entry 
           91:  cmpl $5, %edi 
           92:  jne .LBB4_4 
           93: # %bb.2: # %if.then 
           94:  callq trap_func@PLT 
next:131'0                         X error: no match found
           95: .LBB4_3: # %if.then2 
next:131'0     ~~~~~~~~~~~~~~~~~~~~~
next:131'1      ?                    possible intended match
           96:  callq trap_func@PLT 
next:131'0     ~~~~~~~~~~~~~~~~~~~~~
           97: .LBB4_4: # %if.end3 
next:131'0     ~~~~~~~~~~~~~~~~~~~~
           98:  callq trap_func@PLT 
next:131'0     ~~~~~~~~~~~~~~~~~~~~~
           99: .Lfunc_end4: 
next:131'0     ~~~~~~~~~~~~~
          100:  .size nomerge_named_debugtrap, .Lfunc_end4-nomerge_named_debugtrap 
next:131'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            .
            .
            .
>>>>>>

--

and

Exit Code: 1

Command Output (stderr):
--
RUN: at line 1: /b/s/w/ir/x/w/llvm_build/bin/llc -O3 -mtriple arm64-linux -filetype asm -o - /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/MC/AArch64/local-bounds-single-trap.ll | /b/s/w/ir/x/w/llvm_build/bin/FileCheck /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/MC/AArch64/local-bounds-single-trap.ll -check-prefix CHECK-ASM
+ /b/s/w/ir/x/w/llvm_build/bin/llc -O3 -mtriple arm64-linux -filetype asm -o - /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/MC/AArch64/local-bounds-single-trap.ll
+ /b/s/w/ir/x/w/llvm_build/bin/FileCheck /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/MC/AArch64/local-bounds-single-trap.ll -check-prefix CHECK-ASM
/b/s/w/ir/x/w/llvm-llvm-project/llvm/test/MC/AArch64/local-bounds-single-trap.ll:24:14: error: CHECK-ASM: expected string not found in input
; CHECK-ASM: b.hi .LBB0_5
             ^
<stdin>:26:13: note: scanning from here
 cmp x9, #10
            ^
<stdin>:27:2: note: possible intended match here
 b.hi .LBB0_6
 ^

Input file: <stdin>
Check file: /b/s/w/ir/x/w/llvm-llvm-project/llvm/test/MC/AArch64/local-bounds-single-trap.ll

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            .
            .
            .
           21: // %bb.2: 
           22:  ldrsw x9, [sp, #8] 
           23:  adrp x10, B 
           24:  add x10, x10, :lo12:B 
           25:  strb wzr, [x10, x8] 
           26:  cmp x9, #10 
check:24'0                 X error: no match found
           27:  b.hi .LBB0_6 
check:24'0     ~~~~~~~~~~~~~~
check:24'1      ?             possible intended match
           28: // %bb.3: 
check:24'0     ~~~~~~~~~~
           29:  mov w8, #10 // =0xa 
check:24'0     ~~~~~~~~~~~~~~~~~~~~~
           30:  sub x8, x8, x9 
check:24'0     ~~~~~~~~~~~~~~~~
           31:  cbz x8, .LBB0_6 
check:24'0     ~~~~~~~~~~~~~~~~~
           32: // %bb.4: 
check:24'0     ~~~~~~~~~~
            .
            .
            .
>>>>>>

--

Failed builder task: https://ci.chromium.org/ui/p/fuchsia/builders/toolchain.ci/clang-base-linux-x64/b8740776112052324513/overview

Could you revert your change and reland it after fixing it please?

zeroomega added a commit that referenced this pull request Aug 1, 2024
…(), __debugbreak(), __builtin_verbose_trap() (#101549)"

This reverts commit 5e84646, which
broke 'nomerge.ll' test on llvm bots.
ZequanWu added a commit that referenced this pull request Aug 1, 2024
…p(), __debugbreak(), __builtin_verbose_trap() (#101549)"

This reverts commit 667598d and fixes failed tests: llvm/test/CodeGen/X86/nomerge.ll and llvm/test/MC/AArch64/local-bounds-single-trap.ll.
@ZequanWu
Copy link
Contributor Author

ZequanWu commented Aug 1, 2024

Thanks for reporting. Those tests are failed due to not updated properly. I relanded this change with updated tests: ae6dc64.

@dyung
Copy link
Collaborator

dyung commented Aug 2, 2024

Thanks for reporting. Those tests are failed due to not updated properly. I relanded this change with updated tests: ae6dc64.

Your updated change still seems to cause the test CodeGen/attr-nomerge.cpp to fail on AArch64 bots:

Can you either fix or revert if you need time to investigate?

@MaskRay
Copy link
Member

MaskRay commented Aug 2, 2024

Thanks for reporting. Those tests are failed due to not updated properly. I relanded this change with updated tests: ae6dc64.

Your updated change still seems to cause the test CodeGen/attr-nomerge.cpp to fail on AArch64 bots:

Can you either fix or revert if you need time to investigate?

Hopefully fixed by c5f1395. If not, perhaps a fixed -triple should be used instead.

@ZequanWu
Copy link
Contributor Author

ZequanWu commented Aug 2, 2024

Thanks for reporting. Those tests are failed due to not updated properly. I relanded this change with updated tests: ae6dc64.

Your updated change still seems to cause the test CodeGen/attr-nomerge.cpp to fail on AArch64 bots:

Can you either fix or revert if you need time to investigate?

Hopefully fixed by c5f1395. If not, perhaps a fixed -triple should be used instead.

Thanks for the fix!

@dyung
Copy link
Collaborator

dyung commented Aug 2, 2024

Thanks for reporting. Those tests are failed due to not updated properly. I relanded this change with updated tests: ae6dc64.

Your updated change still seems to cause the test CodeGen/attr-nomerge.cpp to fail on AArch64 bots:

Can you either fix or revert if you need time to investigate?

Hopefully fixed by c5f1395. If not, perhaps a fixed -triple should be used instead.

Thanks for the fix!

The test still appears to be failing after the fix.
https://lab.llvm.org/buildbot/#/builders/190/builds/3070

@ZequanWu
Copy link
Contributor Author

ZequanWu commented Aug 2, 2024

Thanks for reporting. Those tests are failed due to not updated properly. I relanded this change with updated tests: ae6dc64.

Your updated change still seems to cause the test CodeGen/attr-nomerge.cpp to fail on AArch64 bots:

Can you either fix or revert if you need time to investigate?

Hopefully fixed by c5f1395. If not, perhaps a fixed -triple should be used instead.

Thanks for the fix!

The test still appears to be failing after the fix. https://lab.llvm.org/buildbot/#/builders/190/builds/3070.

6c375ae should fix it.

thurstond added a commit to thurstond/llvm-project that referenced this pull request Nov 25, 2024
…e-trap.ll

llvm/test/MC/AArch64/local-bounds-single-trap.ll was introduced in https://github.com/llvm/llvm-project/pull/65972/files to demonstrate that nomerge did not work properly, which is documented in the header comment.

llvm#101549 fixed nomerge for trap builtins and llvm@ae6dc64 updated the test assertions, but not the header comment. This patch updates the header comment accordingly.
thurstond added a commit to thurstond/llvm-project that referenced this pull request Nov 26, 2024
This test demonstrates that UBSan does not add the nomerge annotation. This is significant because it results in them being merged by the backend.

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 will add nomerge for ubsan.
thurstond added a commit to thurstond/llvm-project that referenced this pull request Nov 26, 2024
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.
thurstond added a commit that referenced this pull request Nov 26, 2024
…single-trap.ll (#117642)

llvm/test/MC/AArch64/local-bounds-single-trap.ll was introduced in
#65972 to demonstrate that
nomerge did not work properly, which is documented in the header
comment.

#101549 fixed nomerge for trap
builtins and
ae6dc64
updated the test assertions, but not the header comment. This patch
updates the header comment accordingly.
thurstond added a commit that referenced this pull request Nov 26, 2024
…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.
thurstond added a commit to thurstond/llvm-project that referenced this pull request Nov 26, 2024
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.
thurstond added a commit to thurstond/llvm-project that referenced this pull request Nov 26, 2024
…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.
thurstond added a commit that referenced this pull request Nov 26, 2024
…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.
thurstond added a commit to thurstond/llvm-project that referenced this pull request Nov 26, 2024
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.
thurstond added a commit that referenced this pull request Nov 27, 2024
…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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make [[clang::nomerge]] work for trap intrinsics such as __debugbreak and __builtin_trap
6 participants