https://github.com/ZequanWu created https://github.com/llvm/llvm-project/pull/101549
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 >From ea1e66a670cf689ef904b59165eae0a978b9bdc2 Mon Sep 17 00:00:00 2001 From: Zequan Wu <zequa...@google.com> Date: Thu, 1 Aug 2024 11:59:50 -0700 Subject: [PATCH] [Clang] Fix nomerge attribute not working with __builtin_trap(), __debugbreak(), __builtin_verbose_trap() --- clang/lib/CodeGen/CGExpr.cpp | 2 + clang/test/CodeGen/attr-nomerge.cpp | 8 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 4 +- llvm/test/CodeGen/X86/nomerge.ll | 92 +++++++++++++++++++ 4 files changed, 104 insertions(+), 2 deletions(-) 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" } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits