[clang] [compiler-rt] [codegen]Ensure __builtin_trap() has an unreachable (PR #197789)
Vy Nguyen via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 26 10:17:40 PDT 2026
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/197789
>From 48bc3a4580675833dc69afcb8d6a4328644b6ce2 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 14 May 2026 15:36:16 -0400
Subject: [PATCH 01/12] [codegen]Ensure __builtin_trap() has an unreachable
---
clang/lib/CodeGen/CGBuiltin.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 20f99f489c55f..678985ebb55e1 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4022,6 +4022,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
case Builtin::BI__builtin_trap:
EmitTrapCall(Intrinsic::trap);
+ if (Builder.GetInsertBlock()) {
+ Builder.CreateUnreachable();
+ // Dummy block for the ret void - it'll be clened up
+ llvm::BasicBlock *DeadBB = createBasicBlock("dead.trap");
+ EmitBlock(DeadBB);
+ }
return RValue::get(nullptr);
case Builtin::BI__builtin_verbose_trap: {
llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
>From b7c197092170a9a44030f950973ac941ca554d01 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 14 May 2026 20:22:07 -0400
Subject: [PATCH 02/12] set no ret
---
clang/lib/CodeGen/CGBuiltin.cpp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 678985ebb55e1..c907bd829d149 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4020,15 +4020,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Function *F = CGM.getIntrinsic(Intrinsic::clear_cache, {CGM.DefaultPtrTy});
return RValue::get(Builder.CreateCall(F, {Begin, End}));
}
- case Builtin::BI__builtin_trap:
+ case Builtin::BI__builtin_trap: {
EmitTrapCall(Intrinsic::trap);
+ Trap->setDoesNotReturn();
+ Trap->setDoesNotThrow();
+ Builder.CreateUnreachable();
if (Builder.GetInsertBlock()) {
- Builder.CreateUnreachable();
- // Dummy block for the ret void - it'll be clened up
+ // Dummy block for the ret void - it'll be cleaned up
llvm::BasicBlock *DeadBB = createBasicBlock("dead.trap");
EmitBlock(DeadBB);
}
return RValue::get(nullptr);
+ }
case Builtin::BI__builtin_verbose_trap: {
llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
if (getDebugInfo()) {
>From d2c974b04a8b9315d63127fa3b636ec0501b578a Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 14 May 2026 21:17:41 -0400
Subject: [PATCH 03/12] typo
---
clang/lib/CodeGen/CGBuiltin.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c907bd829d149..d01e00c7fd35d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4021,12 +4021,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(Builder.CreateCall(F, {Begin, End}));
}
case Builtin::BI__builtin_trap: {
- EmitTrapCall(Intrinsic::trap);
+ llvm::CallInst *Trap = EmitTrapCall(Intrinsic::trap);
Trap->setDoesNotReturn();
Trap->setDoesNotThrow();
Builder.CreateUnreachable();
if (Builder.GetInsertBlock()) {
- // Dummy block for the ret void - it'll be cleaned up
+ // Dummy block for the ret void - it'll be cleaned up.
llvm::BasicBlock *DeadBB = createBasicBlock("dead.trap");
EmitBlock(DeadBB);
}
>From ca1be1c1763d5fef010472f735b7aa835e3914fd Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Fri, 15 May 2026 08:47:31 -0400
Subject: [PATCH 04/12] update tests
---
clang/test/CodeGen/amdgpu-builtin-is-invocable.c | 4 +++-
clang/test/CodeGen/amdgpu-builtin-processor-is.c | 4 ++++
clang/test/CodeGen/attr-nomerge.cpp | 7 +++----
clang/test/CodeGen/pr53127.cpp | 2 ++
clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp | 1 +
clang/test/CodeGenCXX/trap-fnattr.cpp | 2 +-
6 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/clang/test/CodeGen/amdgpu-builtin-is-invocable.c b/clang/test/CodeGen/amdgpu-builtin-is-invocable.c
index 5c6d7b25f3bf1..b92215be472ab 100644
--- a/clang/test/CodeGen/amdgpu-builtin-is-invocable.c
+++ b/clang/test/CodeGen/amdgpu-builtin-is-invocable.c
@@ -20,7 +20,7 @@
// AMDGCN-GFX1010-SAME: ) #[[ATTR0:[0-9]+]] {
// AMDGCN-GFX1010-NEXT: [[ENTRY:.*:]]
// AMDGCN-GFX1010-NEXT: call void @llvm.trap()
-// AMDGCN-GFX1010-NEXT: ret void
+// AMDGCN-GFX1010-NEXT: unreachable
//
// AMDGCNSPIRV-LABEL: define spir_func void @foo(
// AMDGCNSPIRV-SAME: ) addrspace(4) #[[ATTR0:[0-9]+]] {
@@ -38,6 +38,8 @@
// AMDGCNSPIRV-NEXT: br i1 [[TOBOOL3]], label %[[IF_THEN]], label %[[IF_END:.*]]
// AMDGCNSPIRV: [[IF_THEN]]:
// AMDGCNSPIRV-NEXT: call addrspace(4) void @llvm.trap()
+// AMDGCNSPIRV-NEXT: unreachable
+// AMDGCNSPIRV: dead.trap:
// AMDGCNSPIRV-NEXT: br label %[[IF_END]]
// AMDGCNSPIRV: [[IF_END]]:
// AMDGCNSPIRV-NEXT: ret void
diff --git a/clang/test/CodeGen/amdgpu-builtin-processor-is.c b/clang/test/CodeGen/amdgpu-builtin-processor-is.c
index b2f04f11ecb54..70a00960b971c 100644
--- a/clang/test/CodeGen/amdgpu-builtin-processor-is.c
+++ b/clang/test/CodeGen/amdgpu-builtin-processor-is.c
@@ -14,6 +14,8 @@
// AMDGCN-GFX900-SAME: ) #[[ATTR0:[0-9]+]] {
// AMDGCN-GFX900-NEXT: [[ENTRY:.*:]]
// AMDGCN-GFX900-NEXT: call void @llvm.trap()
+// AMDGCN-GFX900-NEXT: unreachable
+// AMDGCN-GFX900: dead.trap:
// AMDGCN-GFX900-NEXT: ret void
//
// AMDGCN-GFX1010-LABEL: define dso_local void @foo(
@@ -45,6 +47,8 @@
// AMDGCNSPIRV-NEXT: br i1 [[TOBOOL7]], label %[[IF_THEN]], label %[[IF_END:.*]]
// AMDGCNSPIRV: [[IF_THEN]]:
// AMDGCNSPIRV-NEXT: call addrspace(4) void @llvm.trap()
+// AMDGCNSPIRV-NEXT: unreachable
+// AMDGCNSPIRV: dead.trap:
// AMDGCNSPIRV-NEXT: br label %[[IF_END]]
// AMDGCNSPIRV: [[IF_END]]:
// AMDGCNSPIRV-NEXT: ret void
diff --git a/clang/test/CodeGen/attr-nomerge.cpp b/clang/test/CodeGen/attr-nomerge.cpp
index 1cf5bb1619b31..312e8ed62d5d9 100644
--- a/clang/test/CodeGen/attr-nomerge.cpp
+++ b/clang/test/CodeGen/attr-nomerge.cpp
@@ -100,10 +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: call void @llvm.trap() #[[ATTR8:[0-9]+]]
+// CHECK: unreachable
// CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}}
// CHECK-DAG: attributes #[[ATTR1]] = {{{.*}}nomerge{{.*}}}
+// CHECK-DAG attributes #[[ATTR8]] = { nomerge noreturn nounwind }
diff --git a/clang/test/CodeGen/pr53127.cpp b/clang/test/CodeGen/pr53127.cpp
index 5a52b4860eecd..473f4444410c7 100644
--- a/clang/test/CodeGen/pr53127.cpp
+++ b/clang/test/CodeGen/pr53127.cpp
@@ -15,6 +15,8 @@ void operator delete(void*);
// CHECK-NEXT: br i1 [[CALL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK: cond.true:
// CHECK-NEXT: call void @llvm.trap()
+// CHECK-NEXT: unreachable
+// CHECK: dead.trap:
// CHECK-NEXT: br label [[COND_END:%.*]]
// CHECK: cond.false:
// CHECK-NEXT: br label [[COND_END]]
diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
index 80ea63e2a1e10..f0f46dcc9faf5 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
@@ -41,6 +41,7 @@ void call_var_args() {
}
// CHECK-LABEL: define dso_local void @"?call_var_args@@YAXXZ"()
+// FIXME all of these are after the trap so they should be gone.
// CHECK: call void {{.*varargs_zero.*}}(ptr inalloca(<{ %struct.A }>) %{{.*}})
// CHECK: call void {{.*varargs_one.*}}(ptr inalloca(<{ i32, %struct.A }>) %{{.*}})
// CHECK: call void {{.*varargs_two.*}}(ptr inalloca(<{ i32, i32, %struct.A }>) %{{.*}})
diff --git a/clang/test/CodeGenCXX/trap-fnattr.cpp b/clang/test/CodeGenCXX/trap-fnattr.cpp
index ed7162fc43a6c..0b377813fa89b 100644
--- a/clang/test/CodeGenCXX/trap-fnattr.cpp
+++ b/clang/test/CodeGenCXX/trap-fnattr.cpp
@@ -30,7 +30,7 @@ int test_add_overflow(int a, int b) {
return a + b;
}
-// TRAPFUNC: attributes [[ATTR0]] = { {{.*}}"trap-func-name"="mytrap" }
+// TRAPFUNC: attributes [[ATTR0]] = { noreturn no unwind "trap-func-name"="mytrap" }
// TRAPFUNC: attributes [[ATTR1]] = { {{.*}}"trap-func-name"="mytrap" }
// NOOPTION-NOT: attributes [[ATTR2]] = { {{.*}}"trap-func-name"="mytrap" }
>From b77cd819e35a9041ac137decc3b55e905443f64f Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Mon, 1 Jun 2026 14:37:23 -0400
Subject: [PATCH 05/12] address review
---
clang/lib/CodeGen/CGBuiltin.cpp | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d01e00c7fd35d..dedee3e9db0e4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4021,15 +4021,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(Builder.CreateCall(F, {Begin, End}));
}
case Builtin::BI__builtin_trap: {
- llvm::CallInst *Trap = EmitTrapCall(Intrinsic::trap);
- Trap->setDoesNotReturn();
- Trap->setDoesNotThrow();
+ EmitTrapCall(Intrinsic::trap);
Builder.CreateUnreachable();
- if (Builder.GetInsertBlock()) {
- // Dummy block for the ret void - it'll be cleaned up.
- llvm::BasicBlock *DeadBB = createBasicBlock("dead.trap");
- EmitBlock(DeadBB);
- }
+ EmitBlock(createBasicBlock());
return RValue::get(nullptr);
}
case Builtin::BI__builtin_verbose_trap: {
>From 3d12f1fdc5ed61c7d5167adb0e9201c705ccdb49 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Mon, 1 Jun 2026 14:55:33 -0400
Subject: [PATCH 06/12] updated attr-nomerge test
---
clang/test/CodeGen/attr-nomerge.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang/test/CodeGen/attr-nomerge.cpp b/clang/test/CodeGen/attr-nomerge.cpp
index 312e8ed62d5d9..473aa9aa32c8b 100644
--- a/clang/test/CodeGen/attr-nomerge.cpp
+++ b/clang/test/CodeGen/attr-nomerge.cpp
@@ -42,7 +42,8 @@ void foo(int i, A *ap, B *bp) {
A *newA = new B();
delete newA;
- [[clang::nomerge]] __builtin_trap();
+ // [[clang::nomerge]] __builtin_trap();
+ [[clang::nomerge]] __debugbreak();
[[clang::nomerge]] __debugbreak();
[[clang::nomerge]] __builtin_verbose_trap("check null", "Argument must not be null.");
}
@@ -100,9 +101,10 @@ 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() #[[ATTR8:[0-9]+]]
-// CHECK: unreachable
+// CHECK: call void @llvm.debugtrap() #[[ATTR0]]
+// CHECK: call void @llvm.debugtrap() #[[ATTR0]]
+// CHECK: call void @llvm.trap() #[[ATTR0]]
+// CHECK: call void @_ZN1AD1Ev(ptr {{.*}}) #[[ATTR1]]
// CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}}
// CHECK-DAG: attributes #[[ATTR1]] = {{{.*}}nomerge{{.*}}}
-// CHECK-DAG attributes #[[ATTR8]] = { nomerge noreturn nounwind }
>From c9f22a240a4c4ae391df630b7a763580618b97b1 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Wed, 3 Jun 2026 12:25:45 -0400
Subject: [PATCH 07/12] have EmitTrapCall() automatically add the unreachable
---
clang/lib/CodeGen/CGBuiltin.cpp | 2 --
clang/lib/CodeGen/CGExpr.cpp | 10 +++++++++-
clang/lib/CodeGen/CodeGenFunction.h | 3 ++-
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index dedee3e9db0e4..afd9a359dfdd5 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4022,8 +4022,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
case Builtin::BI__builtin_trap: {
EmitTrapCall(Intrinsic::trap);
- Builder.CreateUnreachable();
- EmitBlock(createBasicBlock());
return RValue::get(nullptr);
}
case Builtin::BI__builtin_verbose_trap: {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 8ca4ee64136c8..167963cc6419d 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4597,7 +4597,8 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
EmitBlock(Cont);
}
-llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
+llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID,
+ bool MayReturn, bool MayThrow) {
llvm::CallInst *TrapCall =
Builder.CreateCall(CGM.getIntrinsic(IntrID));
@@ -4609,6 +4610,13 @@ llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
if (InNoMergeAttributedStmt)
TrapCall->addFnAttr(llvm::Attribute::NoMerge);
+ if (!MayThrow)
+ TrapCall->setDoesNotThrow();
+ if (!MayReturn) {
+ TrapCall->setDoesNotReturn();
+ Builder.CreateUnreachable();
+ EmitBlock(createBasicBlock());
+ }
return TrapCall;
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 77ca3e0fee84f..ff107c75cf7ae 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -5393,7 +5393,8 @@ class CodeGenFunction : public CodeGenTypeCache {
/// Emit a call to trap or debugtrap and attach function attribute
/// "trap-func-name" if specified.
- llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID);
+ llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID,
+ bool MayReturn = false, bool MayThrow = false);
/// Emit a stub for the cross-DSO CFI check function.
void EmitCfiCheckStub();
>From 7b1f03eeafffff773919e56c4c1b9ffce31ae45e Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Wed, 3 Jun 2026 13:07:18 -0400
Subject: [PATCH 08/12] make debug_trap may return
---
clang/lib/CodeGen/CGBuiltin.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index afd9a359dfdd5..1f8b0a9654c2c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4037,7 +4037,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(nullptr);
}
case Builtin::BI__debugbreak:
- EmitTrapCall(Intrinsic::debugtrap);
+ EmitTrapCall(Intrinsic::debugtrap,/*MayReturn*/true);
return RValue::get(nullptr);
case Builtin::BI__builtin_unreachable: {
EmitUnreachable(E->getExprLoc());
>From d6470665ba0983b881e7e71a9eccbf7e3d1fd70d Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 25 Jun 2026 14:09:29 -0400
Subject: [PATCH 09/12] clean up more test failures
---
clang/lib/CodeGen/CGBuiltin.cpp | 2 +-
clang/lib/CodeGen/CGExpr.cpp | 11 ++++----
clang/lib/CodeGen/CodeGenFunction.h | 3 +--
.../CodeGen/amdgpu-builtin-is-invocable.c | 10 ++++---
.../CodeGen/amdgpu-builtin-processor-is.c | 10 ++++---
clang/test/CodeGen/attr-nomerge.cpp | 22 +++++++++++++---
clang/test/CodeGen/pr53127.cpp | 26 +++++++++----------
.../CodeGenCXX/microsoft-abi-byval-vararg.cpp | 13 ++++------
.../microsoft-vector-deleting-dtors2.cpp | 6 ++---
clang/test/CodeGenCXX/trap-fnattr.cpp | 6 ++---
clang/test/CodeGenCXX/vararg-non-pod.cpp | 2 +-
clang/test/DebugInfo/CXX/verbose-trap.cpp | 17 +++++++-----
clang/test/Headers/gpuintrin.c | 2 +-
.../spirv_target_codegen_noexceptions.cpp | 3 ++-
14 files changed, 77 insertions(+), 56 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1f8b0a9654c2c..afd9a359dfdd5 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4037,7 +4037,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(nullptr);
}
case Builtin::BI__debugbreak:
- EmitTrapCall(Intrinsic::debugtrap,/*MayReturn*/true);
+ EmitTrapCall(Intrinsic::debugtrap);
return RValue::get(nullptr);
case Builtin::BI__builtin_unreachable: {
EmitUnreachable(E->getExprLoc());
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 167963cc6419d..aac891ad29337 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4597,10 +4597,9 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
EmitBlock(Cont);
}
-llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID,
- bool MayReturn, bool MayThrow) {
- llvm::CallInst *TrapCall =
- Builder.CreateCall(CGM.getIntrinsic(IntrID));
+llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
+ llvm::Function *F = CGM.getIntrinsic(IntrID);
+ llvm::CallInst *TrapCall = Builder.CreateCall(F);
if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
@@ -4610,9 +4609,9 @@ llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID,
if (InNoMergeAttributedStmt)
TrapCall->addFnAttr(llvm::Attribute::NoMerge);
- if (!MayThrow)
+ if (F->doesNotThrow())
TrapCall->setDoesNotThrow();
- if (!MayReturn) {
+ if (F->doesNotReturn()) {
TrapCall->setDoesNotReturn();
Builder.CreateUnreachable();
EmitBlock(createBasicBlock());
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index ff107c75cf7ae..77ca3e0fee84f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -5393,8 +5393,7 @@ class CodeGenFunction : public CodeGenTypeCache {
/// Emit a call to trap or debugtrap and attach function attribute
/// "trap-func-name" if specified.
- llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID,
- bool MayReturn = false, bool MayThrow = false);
+ llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID);
/// Emit a stub for the cross-DSO CFI check function.
void EmitCfiCheckStub();
diff --git a/clang/test/CodeGen/amdgpu-builtin-is-invocable.c b/clang/test/CodeGen/amdgpu-builtin-is-invocable.c
index b92215be472ab..6cd7005504df1 100644
--- a/clang/test/CodeGen/amdgpu-builtin-is-invocable.c
+++ b/clang/test/CodeGen/amdgpu-builtin-is-invocable.c
@@ -19,8 +19,10 @@
// AMDGCN-GFX1010-LABEL: define dso_local void @foo(
// AMDGCN-GFX1010-SAME: ) #[[ATTR0:[0-9]+]] {
// AMDGCN-GFX1010-NEXT: [[ENTRY:.*:]]
-// AMDGCN-GFX1010-NEXT: call void @llvm.trap()
+// AMDGCN-GFX1010-NEXT: call void @llvm.trap() #[[ATTR2:[0-9]+]]
// AMDGCN-GFX1010-NEXT: unreachable
+// AMDGCN-GFX1010: [[BB0:.*:]]
+// AMDGCN-GFX1010-NEXT: ret void
//
// AMDGCNSPIRV-LABEL: define spir_func void @foo(
// AMDGCNSPIRV-SAME: ) addrspace(4) #[[ATTR0:[0-9]+]] {
@@ -37,9 +39,9 @@
// AMDGCNSPIRV-NEXT: [[TOBOOL3:%.*]] = icmp ne i1 [[TMP2]], false
// AMDGCNSPIRV-NEXT: br i1 [[TOBOOL3]], label %[[IF_THEN]], label %[[IF_END:.*]]
// AMDGCNSPIRV: [[IF_THEN]]:
-// AMDGCNSPIRV-NEXT: call addrspace(4) void @llvm.trap()
+// AMDGCNSPIRV-NEXT: call addrspace(4) void @llvm.trap() #[[ATTR3:[0-9]+]]
// AMDGCNSPIRV-NEXT: unreachable
-// AMDGCNSPIRV: dead.trap:
+// AMDGCNSPIRV: [[BB3:.*:]]
// AMDGCNSPIRV-NEXT: br label %[[IF_END]]
// AMDGCNSPIRV: [[IF_END]]:
// AMDGCNSPIRV-NEXT: ret void
@@ -55,10 +57,12 @@ void foo() {
//.
// AMDGCN-GFX1010: attributes #[[ATTR0]] = { convergent noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="gfx1010" }
// AMDGCN-GFX1010: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind memory(inaccessiblemem: write) }
+// AMDGCN-GFX1010: attributes #[[ATTR2]] = { noreturn nounwind }
//.
// AMDGCNSPIRV: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+16-bit-insts,+add-min-max-insts,+ashr-pk-insts,+atomic-buffer-global-pk-add-f16-insts,+atomic-buffer-pk-add-bf16-inst,+atomic-ds-pk-add-16-insts,+atomic-fadd-rtn-insts,+atomic-flat-pk-add-16-insts,+atomic-fmin-fmax-global-f32,+atomic-fmin-fmax-global-f64,+atomic-global-pk-add-bf16-inst,+bf16-cvt-insts,+bf16-pk-insts,+bf16-trans-insts,+bf8-cvt-scale-insts,+bitop3-insts,+ci-insts,+clusters,+cube-insts,+cvt-pknorm-vop2-insts,+dl-insts,+dot1-insts,+dot10-insts,+dot11-insts,+dot12-insts,+dot13-insts,+dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+f16bf16-to-fp6bf6-cvt-scale-insts,+f32-to-f16bf16-cvt-sr-insts,+fp4-cvt-scale-insts,+fp6bf6-cvt-scale-insts,+fp8-conversion-insts,+fp8-cvt-scale-insts,+fp8-insts,+fp8e5m3-insts,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx12-insts,+gfx1250-insts,+gfx8-insts,+gfx9-insts,+gfx90a-insts,+gfx940-insts,+gfx950-insts,+gws,+image-insts,+lerp-inst,+mai-insts,+mcast-load-insts,+permlane16-swap,+permlane32-swap,+pk-add-min-max-insts,+prng-inst,+qsad-insts,+s-memrealtime,+s-memtime-inst,+s-wakeup-barrier-inst,+sad-insts,+setprio-inc-wg-inst,+swmmac-gfx1200-insts,+swmmac-gfx1250-insts,+tanh-insts,+tensor-cvt-lut-insts,+transpose-load-f4f6-insts,+vmem-pref-insts,+vmem-to-lds-load-insts,+wavefrontsize32,+wavefrontsize64,+wmma-128b-insts,+wmma-256b-insts,+xf32-insts" }
// AMDGCNSPIRV: attributes #[[ATTR1:[0-9]+]] = { nounwind }
// AMDGCNSPIRV: attributes #[[ATTR2:[0-9]+]] = { cold noreturn nounwind memory(inaccessiblemem: write) }
+// AMDGCNSPIRV: attributes #[[ATTR3]] = { noreturn nounwind }
//.
// AMDGCN-GFX900: [[META0:![0-9]+]] = !{i32 1, !"amdhsa_code_object_version", i32 600}
// AMDGCN-GFX900: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
diff --git a/clang/test/CodeGen/amdgpu-builtin-processor-is.c b/clang/test/CodeGen/amdgpu-builtin-processor-is.c
index 70a00960b971c..162c99761373b 100644
--- a/clang/test/CodeGen/amdgpu-builtin-processor-is.c
+++ b/clang/test/CodeGen/amdgpu-builtin-processor-is.c
@@ -13,9 +13,9 @@
// AMDGCN-GFX900-LABEL: define dso_local void @foo(
// AMDGCN-GFX900-SAME: ) #[[ATTR0:[0-9]+]] {
// AMDGCN-GFX900-NEXT: [[ENTRY:.*:]]
-// AMDGCN-GFX900-NEXT: call void @llvm.trap()
+// AMDGCN-GFX900-NEXT: call void @llvm.trap() #[[ATTR2:[0-9]+]]
// AMDGCN-GFX900-NEXT: unreachable
-// AMDGCN-GFX900: dead.trap:
+// AMDGCN-GFX900: [[BB0:.*:]]
// AMDGCN-GFX900-NEXT: ret void
//
// AMDGCN-GFX1010-LABEL: define dso_local void @foo(
@@ -46,9 +46,9 @@
// AMDGCNSPIRV-NEXT: [[TOBOOL7:%.*]] = icmp ne i1 [[TMP4]], false
// AMDGCNSPIRV-NEXT: br i1 [[TOBOOL7]], label %[[IF_THEN]], label %[[IF_END:.*]]
// AMDGCNSPIRV: [[IF_THEN]]:
-// AMDGCNSPIRV-NEXT: call addrspace(4) void @llvm.trap()
+// AMDGCNSPIRV-NEXT: call addrspace(4) void @llvm.trap() #[[ATTR3:[0-9]+]]
// AMDGCNSPIRV-NEXT: unreachable
-// AMDGCNSPIRV: dead.trap:
+// AMDGCNSPIRV: [[BB5:.*:]]
// AMDGCNSPIRV-NEXT: br label %[[IF_END]]
// AMDGCNSPIRV: [[IF_END]]:
// AMDGCNSPIRV-NEXT: ret void
@@ -64,12 +64,14 @@ void foo() {
//.
// AMDGCN-GFX900: attributes #[[ATTR0]] = { convergent noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="gfx900" }
// AMDGCN-GFX900: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind memory(inaccessiblemem: write) }
+// AMDGCN-GFX900: attributes #[[ATTR2]] = { noreturn nounwind }
//.
// AMDGCN-GFX1010: attributes #[[ATTR0]] = { convergent noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="gfx1010" }
//.
// AMDGCNSPIRV: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+16-bit-insts,+add-min-max-insts,+ashr-pk-insts,+atomic-buffer-global-pk-add-f16-insts,+atomic-buffer-pk-add-bf16-inst,+atomic-ds-pk-add-16-insts,+atomic-fadd-rtn-insts,+atomic-flat-pk-add-16-insts,+atomic-fmin-fmax-global-f32,+atomic-fmin-fmax-global-f64,+atomic-global-pk-add-bf16-inst,+bf16-cvt-insts,+bf16-pk-insts,+bf16-trans-insts,+bf8-cvt-scale-insts,+bitop3-insts,+ci-insts,+clusters,+cube-insts,+cvt-pknorm-vop2-insts,+dl-insts,+dot1-insts,+dot10-insts,+dot11-insts,+dot12-insts,+dot13-insts,+dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+f16bf16-to-fp6bf6-cvt-scale-insts,+f32-to-f16bf16-cvt-sr-insts,+fp4-cvt-scale-insts,+fp6bf6-cvt-scale-insts,+fp8-conversion-insts,+fp8-cvt-scale-insts,+fp8-insts,+fp8e5m3-insts,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx12-insts,+gfx1250-insts,+gfx8-insts,+gfx9-insts,+gfx90a-insts,+gfx940-insts,+gfx950-insts,+gws,+image-insts,+lerp-inst,+mai-insts,+mcast-load-insts,+permlane16-swap,+permlane32-swap,+pk-add-min-max-insts,+prng-inst,+qsad-insts,+s-memrealtime,+s-memtime-inst,+s-wakeup-barrier-inst,+sad-insts,+setprio-inc-wg-inst,+swmmac-gfx1200-insts,+swmmac-gfx1250-insts,+tanh-insts,+tensor-cvt-lut-insts,+transpose-load-f4f6-insts,+vmem-pref-insts,+vmem-to-lds-load-insts,+wavefrontsize32,+wavefrontsize64,+wmma-128b-insts,+wmma-256b-insts,+xf32-insts" }
// AMDGCNSPIRV: attributes #[[ATTR1:[0-9]+]] = { nounwind }
// AMDGCNSPIRV: attributes #[[ATTR2:[0-9]+]] = { cold noreturn nounwind memory(inaccessiblemem: write) }
+// AMDGCNSPIRV: attributes #[[ATTR3]] = { noreturn nounwind }
//.
// AMDGCN-GFX900: [[META0:![0-9]+]] = !{i32 1, !"amdhsa_code_object_version", i32 600}
// AMDGCN-GFX900: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
diff --git a/clang/test/CodeGen/attr-nomerge.cpp b/clang/test/CodeGen/attr-nomerge.cpp
index 473aa9aa32c8b..6d33f942122fb 100644
--- a/clang/test/CodeGen/attr-nomerge.cpp
+++ b/clang/test/CodeGen/attr-nomerge.cpp
@@ -42,9 +42,15 @@ void foo(int i, A *ap, B *bp) {
A *newA = new B();
delete newA;
- // [[clang::nomerge]] __builtin_trap();
[[clang::nomerge]] __debugbreak();
[[clang::nomerge]] __debugbreak();
+}
+
+void foo_trap() {
+ [[clang::nomerge]] __builtin_trap();
+}
+
+void foo_verbose_trap() {
[[clang::nomerge]] __builtin_verbose_trap("check null", "Argument must not be null.");
}
@@ -101,10 +107,18 @@ void something_else_again() {
// CHECK: load ptr, ptr
// CHECK: %[[AG:.*]] = load ptr, ptr
// CHECK-NEXT: call void %[[AG]](ptr {{.*}}) #[[ATTR1]]
-// CHECK: call void @llvm.debugtrap() #[[ATTR0]]
-// CHECK: call void @llvm.debugtrap() #[[ATTR0]]
-// CHECK: call void @llvm.trap() #[[ATTR0]]
+// CHECK: call void @llvm.debugtrap() #[[ATTR1]]
+// CHECK: call void @llvm.debugtrap() #[[ATTR1]]
// CHECK: call void @_ZN1AD1Ev(ptr {{.*}}) #[[ATTR1]]
+// CHECK-LABEL: define dso_local void @_Z8foo_trapv()
+// CHECK: call void @llvm.trap() #[[ATTR_TRAP:[0-9]+]]
+// CHECK-NEXT: unreachable
+
+// CHECK-LABEL: define dso_local void @_Z16foo_verbose_trapv()
+// CHECK: call void @llvm.trap() #[[ATTR_TRAP]]
+// CHECK-NEXT: unreachable
+
// CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}}
// CHECK-DAG: attributes #[[ATTR1]] = {{{.*}}nomerge{{.*}}}
+// CHECK-DAG: attributes #[[ATTR_TRAP]] = {{{.*}}nomerge{{.*}}}
diff --git a/clang/test/CodeGen/pr53127.cpp b/clang/test/CodeGen/pr53127.cpp
index 473f4444410c7..a605abd8ec31a 100644
--- a/clang/test/CodeGen/pr53127.cpp
+++ b/clang/test/CodeGen/pr53127.cpp
@@ -8,15 +8,15 @@ void operator delete(void*);
// CHECK-LABEL: @_Z1fPiz(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8
-// CHECK-NEXT: [[L:%.*]] = alloca [1 x %struct.__va_list_tag], align 16
-// CHECK-NEXT: [[L2:%.*]] = alloca [1 x %struct.__va_list_tag], align 16
+// CHECK-NEXT: [[L:%.*]] = alloca [1 x [[STRUCT___VA_LIST_TAG:%.*]]], align 16
+// CHECK-NEXT: [[L2:%.*]] = alloca [1 x [[STRUCT___VA_LIST_TAG]]], align 16
// CHECK-NEXT: store ptr [[P:%.*]], ptr [[P_ADDR]], align 8
// CHECK-NEXT: [[CALL:%.*]] = call noundef zeroext i1 @_Z1ev()
// CHECK-NEXT: br i1 [[CALL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK: cond.true:
-// CHECK-NEXT: call void @llvm.trap()
+// CHECK-NEXT: call void @llvm.trap() #[[ATTR8:[0-9]+]]
// CHECK-NEXT: unreachable
-// CHECK: dead.trap:
+// CHECK: 0:
// CHECK-NEXT: br label [[COND_END:%.*]]
// CHECK: cond.false:
// CHECK-NEXT: br label [[COND_END]]
@@ -30,12 +30,12 @@ void operator delete(void*);
// CHECK-NEXT: br label [[COND_END4]]
// CHECK: cond.end4:
// CHECK-NEXT: [[CALL5:%.*]] = call noundef zeroext i1 @_Z1ev()
-// CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CALL5]] to i64
+// CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[CALL5]] to i64
// CHECK-NEXT: call void @llvm.assume(i1 true)
// CHECK-NEXT: [[CALL6:%.*]] = call noundef zeroext i1 @_Z1ev()
// CHECK-NEXT: br i1 [[CALL6]], label [[COND_TRUE7:%.*]], label [[COND_FALSE8:%.*]]
// CHECK: cond.true7:
-// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[L]], i64 0, i64 0
+// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x [[STRUCT___VA_LIST_TAG]]], ptr [[L]], i64 0, i64 0
// CHECK-NEXT: call void @llvm.va_start.p0(ptr [[ARRAYDECAY]])
// CHECK-NEXT: br label [[COND_END9:%.*]]
// CHECK: cond.false8:
@@ -44,8 +44,8 @@ void operator delete(void*);
// CHECK-NEXT: [[CALL10:%.*]] = call noundef zeroext i1 @_Z1ev()
// CHECK-NEXT: br i1 [[CALL10]], label [[COND_TRUE11:%.*]], label [[COND_FALSE14:%.*]]
// CHECK: cond.true11:
-// CHECK-NEXT: [[ARRAYDECAY12:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[L]], i64 0, i64 0
-// CHECK-NEXT: [[ARRAYDECAY13:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[L2]], i64 0, i64 0
+// CHECK-NEXT: [[ARRAYDECAY12:%.*]] = getelementptr inbounds [1 x [[STRUCT___VA_LIST_TAG]]], ptr [[L]], i64 0, i64 0
+// CHECK-NEXT: [[ARRAYDECAY13:%.*]] = getelementptr inbounds [1 x [[STRUCT___VA_LIST_TAG]]], ptr [[L2]], i64 0, i64 0
// CHECK-NEXT: call void @llvm.va_copy.p0(ptr [[ARRAYDECAY12]], ptr [[ARRAYDECAY13]])
// CHECK-NEXT: br label [[COND_END15:%.*]]
// CHECK: cond.false14:
@@ -54,8 +54,8 @@ void operator delete(void*);
// CHECK-NEXT: [[CALL16:%.*]] = call noundef zeroext i1 @_Z1ev()
// CHECK-NEXT: br i1 [[CALL16]], label [[COND_TRUE17:%.*]], label [[COND_FALSE18:%.*]]
// CHECK: cond.true17:
-// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[P_ADDR]], align 8
-// CHECK-NEXT: call void @llvm.prefetch.p0(ptr [[TMP1]], i32 0, i32 3, i32 1)
+// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8
+// CHECK-NEXT: call void @llvm.prefetch.p0(ptr [[TMP2]], i32 0, i32 3, i32 1)
// CHECK-NEXT: br label [[COND_END19:%.*]]
// CHECK: cond.false18:
// CHECK-NEXT: br label [[COND_END19]]
@@ -69,9 +69,9 @@ void operator delete(void*);
// CHECK-NEXT: br label [[COND_END23]]
// CHECK: cond.end23:
// CHECK-NEXT: [[CALL24:%.*]] = call noundef zeroext i1 @_Z1ev()
-// CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[CALL24]] to i64
-// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P_ADDR]], align 8
-// CHECK-NEXT: call void @_ZdlPv(ptr noundef [[TMP3]]) #[[ATTR8:[0-9]+]]
+// CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[CALL24]] to i64
+// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[P_ADDR]], align 8
+// CHECK-NEXT: call void @_ZdlPv(ptr noundef [[TMP4]]) #[[ATTR9:[0-9]+]]
// CHECK-NEXT: ret void
//
void f(int* p, ...)
diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
index f0f46dcc9faf5..84cfc24acdd3b 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
@@ -41,13 +41,10 @@ void call_var_args() {
}
// CHECK-LABEL: define dso_local void @"?call_var_args@@YAXXZ"()
-// FIXME all of these are after the trap so they should be gone.
-// CHECK: call void {{.*varargs_zero.*}}(ptr inalloca(<{ %struct.A }>) %{{.*}})
-// CHECK: call void {{.*varargs_one.*}}(ptr inalloca(<{ i32, %struct.A }>) %{{.*}})
-// CHECK: call void {{.*varargs_two.*}}(ptr inalloca(<{ i32, i32, %struct.A }>) %{{.*}})
-// CHECK: call void {{.*varargs_three.*}}(ptr inalloca(<{ i32, i32, i32, %struct.A }>) %{{.*}})
+// Passing non-POD to varargs ellipsis (...) traps. Since the trap is noreturn,
+// it is followed by unreachable, and subsequent dead code (like inalloca stack
+// allocations and varargs calls) is pruned and not emitted.
+// CHECK: call void @llvm.trap()
+// CHECK-NEXT: unreachable
// CHECK-LABEL: declare dso_local void @"?varargs_zero@@YAXZZ"(...)
-// CHECK-LABEL: declare dso_local void @"?varargs_one@@YAXHZZ"(i32 noundef, ...)
-// CHECK-LABEL: declare dso_local void @"?varargs_two@@YAXHHZZ"(i32 noundef, i32 noundef, ...)
-// CHECK-LABEL: declare dso_local void @"?varargs_three@@YAXHHHZZ"(i32 noundef, i32 noundef, i32 noundef, ...)
diff --git a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
index c6089bb5ecbba..4d7423fd6aab7 100644
--- a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
+++ b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
@@ -83,9 +83,9 @@ void TesttheTest() {
// CHECK: dtor.scalar:
// X64-NEXT: call void @"??1Test@@UEAA at XZ"(ptr noundef nonnull align 8 dead_on_return(8) dereferenceable(8) %this1)
// X86-NEXT: call x86_thiscallcc void @"??1Test@@UAE at XZ"(ptr noundef nonnull align 4 dead_on_return(4) dereferenceable(4) %this1)
-// CHECK-NEXT: %6 = and i32 %should_call_delete2, 1
-// CHECK-NEXT: %7 = icmp eq i32 %6, 0
-// CHECK-NEXT: br i1 %7, label %dtor.continue, label %dtor.call_delete
+// CHECK-NEXT: %7 = and i32 %should_call_delete2, 1
+// CHECK-NEXT: %8 = icmp eq i32 %7, 0
+// CHECK-NEXT: br i1 %8, label %dtor.continue, label %dtor.call_delete
// CHECK: dtor.call_delete:
// X64-NEXT: call void @"??3Test@@SAXPEAX at Z"(ptr noundef %this1)
// X86-NEXT: call void @"??3Test@@SAXPAX at Z"(ptr noundef %this1)
diff --git a/clang/test/CodeGenCXX/trap-fnattr.cpp b/clang/test/CodeGenCXX/trap-fnattr.cpp
index 0b377813fa89b..ef1525672779a 100644
--- a/clang/test/CodeGenCXX/trap-fnattr.cpp
+++ b/clang/test/CodeGenCXX/trap-fnattr.cpp
@@ -5,7 +5,7 @@
// TRAPFUNC: call void @llvm.trap() [[ATTR0:#[0-9]+]]
// NOOPTION-LABEL: define {{(dso_local )?}}void @{{_Z12test_builtinv|\"\?test_builtin@@YAXXZ\"}}
-// NOOPTION: call void @llvm.trap(){{$}}
+// NOOPTION: call void @llvm.trap()
void test_builtin(void) {
__builtin_trap();
@@ -15,7 +15,7 @@ void test_builtin(void) {
// TRAPFUNC: call void @llvm.trap() [[ATTR0]]
// NOOPTION-LABEL: define {{.*}}i32 @{{_Z13test_noreturnv|\"\?test_noreturn@@YAHXZ\"}}
-// NOOPTION: call void @llvm.trap(){{$}}
+// NOOPTION: call void @llvm.trap()
int test_noreturn(void) {
}
@@ -30,7 +30,7 @@ int test_add_overflow(int a, int b) {
return a + b;
}
-// TRAPFUNC: attributes [[ATTR0]] = { noreturn no unwind "trap-func-name"="mytrap" }
+// TRAPFUNC: attributes [[ATTR0]] = { noreturn nounwind "trap-func-name"="mytrap" }
// TRAPFUNC: attributes [[ATTR1]] = { {{.*}}"trap-func-name"="mytrap" }
// NOOPTION-NOT: attributes [[ATTR2]] = { {{.*}}"trap-func-name"="mytrap" }
diff --git a/clang/test/CodeGenCXX/vararg-non-pod.cpp b/clang/test/CodeGenCXX/vararg-non-pod.cpp
index 36891a4d28c8b..5e6d708ea0315 100644
--- a/clang/test/CodeGenCXX/vararg-non-pod.cpp
+++ b/clang/test/CodeGenCXX/vararg-non-pod.cpp
@@ -12,5 +12,5 @@ void vararg(...);
void test(X x) {
// CHECK: call void @llvm.trap()
vararg(x);
- // CHECK: ret void
+ // CHECK-NEXT: unreachable
}
diff --git a/clang/test/DebugInfo/CXX/verbose-trap.cpp b/clang/test/DebugInfo/CXX/verbose-trap.cpp
index 4a88df934ff7c..af5bd4119532a 100644
--- a/clang/test/DebugInfo/CXX/verbose-trap.cpp
+++ b/clang/test/DebugInfo/CXX/verbose-trap.cpp
@@ -1,19 +1,21 @@
// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++20 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
// CHECK-LABEL: define void @_Z2f0v()
-// CHECK: call void @llvm.trap(), !dbg ![[LOC17:.*]]
+// CHECK: call void @llvm.trap(){{.*}}, !dbg ![[LOC17:.*]]
// CHECK: declare void @llvm.trap() #[[ATTR1:.*]]
// CHECK-LABEL: define void @_Z2f1v()
-// CHECK: call void @llvm.trap(), !dbg ![[LOC23:.*]]
-// CHECK: call void @llvm.trap(), !dbg ![[LOC25:.*]]
+// CHECK: call void @llvm.trap(){{.*}}, !dbg ![[LOC23:.*]]
+
+// CHECK-LABEL: define void @_Z4f1_bv()
+// CHECK: call void @llvm.trap(){{.*}}, !dbg ![[LOC25:.*]]
// CHECK-LABEL: define void @_Z2f3v()
// CHECK: call void @_Z2f2IXadsoKcL_ZL8constCatEEEXadsoS0_L_ZL8constMsgEEEEvv()
// CHECK-LABEL: define internal void @_Z2f2IXadsoKcL_ZL8constCatEEEXadsoS0_L_ZL8constMsgEEEEvv
-// CHECK: call void @llvm.trap(), !dbg ![[LOC36:.*]]
+// CHECK: call void @llvm.trap(){{.*}}, !dbg ![[LOC36:.*]]
// CHECK: attributes #[[ATTR1]] = { cold {{.*}}}
@@ -32,12 +34,15 @@ void f0() {
// CHECK: ![[SUBPROG22:.*]] = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v",
// CHECK: ![[LOC23]] = !DILocation(line: 0, scope: ![[SUBPROG18]], inlinedAt: ![[LOC24:.*]])
-// CHECK: ![[LOC24]] = !DILocation(line: [[@LINE+5]], column: 3, scope: ![[SUBPROG22]])
+// CHECK: ![[LOC24]] = !DILocation(line: [[@LINE+6]], column: 3, scope: ![[SUBPROG22]])
+// CHECK: ![[SUBPROG_F1B:.*]] = distinct !DISubprogram(name: "f1_b", linkageName: "_Z4f1_bv",
// CHECK: ![[LOC25]] = !DILocation(line: 0, scope: ![[SUBPROG26:.*]], inlinedAt: ![[LOC27:.*]])
// CHECK: ![[SUBPROG26]] = distinct !DISubprogram(name: "__clang_trap_msg$category2$hello", scope: ![[FILESCOPE]], file: ![[FILESCOPE]], type: !{{.*}}, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: !{{.*}})
-// CHECK: ![[LOC27]] = !DILocation(line: [[@LINE+3]], column: 3, scope: ![[SUBPROG22]])
+// CHECK: ![[LOC27]] = !DILocation(line: [[@LINE+5]], column: 3, scope: ![[SUBPROG_F1B]])
void f1() {
__builtin_verbose_trap("category1", "Argument_must_not_be_null");
+}
+void f1_b() {
__builtin_verbose_trap("category2", "hello");
}
diff --git a/clang/test/Headers/gpuintrin.c b/clang/test/Headers/gpuintrin.c
index 8b6851c3bf084..48b2760943d50 100644
--- a/clang/test/Headers/gpuintrin.c
+++ b/clang/test/Headers/gpuintrin.c
@@ -1692,7 +1692,7 @@ __gpu_kernel void foo() {
// SPIRV-SAME: ) #[[ATTR1:[0-9]+]] {
// SPIRV-NEXT: [[ENTRY:.*:]]
// SPIRV-NEXT: call void @llvm.trap()
-// SPIRV-NEXT: ret void
+// SPIRV-NEXT: unreachable
//
//.
// AMDGPU: [[RNG2]] = !{i32 1, i32 0}
diff --git a/clang/test/OpenMP/spirv_target_codegen_noexceptions.cpp b/clang/test/OpenMP/spirv_target_codegen_noexceptions.cpp
index 42f8f3ea70f7d..c996dc5860b75 100644
--- a/clang/test/OpenMP/spirv_target_codegen_noexceptions.cpp
+++ b/clang/test/OpenMP/spirv_target_codegen_noexceptions.cpp
@@ -3,7 +3,8 @@
// RUN: FileCheck -implicit-check-not='{{invoke|throw|cxa}}' %s
void foo() {
// CHECK: call addrspace(9) void @llvm.trap()
- // CHECK-NEXT: call spir_func addrspace(9) void @__kmpc_target_deinit()
+ // CHECK-NEXT: unreachable
+ // CHECK: call spir_func addrspace(9) void @__kmpc_target_deinit()
#pragma omp target
throw "bad";
}
>From 6eee744b46e69c1f543e7012c5e7e894e7036515 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 25 Jun 2026 15:21:37 -0400
Subject: [PATCH 10/12] fix
compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
---
compiler-rt/test/profile/gcov-__gcov_flush-terminate.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c b/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
index 96cf4296524d1..3ba544dc680bc 100644
--- a/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
+++ b/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
@@ -18,6 +18,6 @@ int main(void) { // CHECK: 1: [[#@LINE]]:int main(void)
__gcov_reset(); // CHECK-NEXT: 1: [[#@LINE]]:
i = 42; // CHECK-NEXT: 1: [[#@LINE]]:
__builtin_trap(); // CHECK-NEXT: 1: [[#@LINE]]:
- i = 84; // CHECK-NEXT: 1: [[#@LINE]]:
- return 0; // CHECK-NEXT: 1: [[#@LINE]]:
+ i = 84; // CHECK-NEXT: -: [[#@LINE]]:
+ return 0; // CHECK-NEXT: -: [[#@LINE]]:
}
>From 27bf8c6b596402e7cb7a4134a7bf224a8cb018ba Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 25 Jun 2026 20:20:44 -0400
Subject: [PATCH 11/12] rename
---
clang/lib/CodeGen/CGBuiltin.cpp | 3 +--
clang/lib/CodeGen/CGExpr.cpp | 8 ++++----
compiler-rt/test/profile/gcov-__gcov_flush-terminate.c | 2 +-
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 3c9a3eb797523..475bfec6199fc 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4316,10 +4316,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Function *F = CGM.getIntrinsic(Intrinsic::clear_cache, {CGM.DefaultPtrTy});
return RValue::get(Builder.CreateCall(F, {Begin, End}));
}
- case Builtin::BI__builtin_trap: {
+ case Builtin::BI__builtin_trap:
EmitTrapCall(Intrinsic::trap);
return RValue::get(nullptr);
- }
case Builtin::BI__builtin_verbose_trap: {
llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
if (getDebugInfo()) {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 29de579c8c2c5..61ac380850f56 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4604,8 +4604,8 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
}
llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
- llvm::Function *F = CGM.getIntrinsic(IntrID);
- llvm::CallInst *TrapCall = Builder.CreateCall(F);
+ llvm::Function *TrapIntrinsic = CGM.getIntrinsic(IntrID);
+ llvm::CallInst *TrapCall = Builder.CreateCall(TrapIntrinsic);
if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
@@ -4615,9 +4615,9 @@ llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
if (InNoMergeAttributedStmt)
TrapCall->addFnAttr(llvm::Attribute::NoMerge);
- if (F->doesNotThrow())
+ if (TrapIntrinsic->doesNotThrow())
TrapCall->setDoesNotThrow();
- if (F->doesNotReturn()) {
+ if (TrapIntrinsic->doesNotReturn()) {
TrapCall->setDoesNotReturn();
Builder.CreateUnreachable();
EmitBlock(createBasicBlock());
diff --git a/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c b/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
index 3ba544dc680bc..3f8005114a097 100644
--- a/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
+++ b/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
@@ -1,5 +1,5 @@
/// https://bugs.llvm.org/show_bug.cgi?id=38067
-/// An abnormal exit does not clear execution counts of subsequent instructions.
+/// An abnormal exit should now clear execution counts of subsequent instructions.
// RUN: mkdir -p %t.dir && cd %t.dir
// RUN: %clang --coverage %s -o %t -dumpdir ./
// RUN: test -f gcov-__gcov_flush-terminate.gcno
>From 7338ad8adc5053a7927271321deb93c5d530c6f5 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 25 Jun 2026 20:35:12 -0400
Subject: [PATCH 12/12] add builtin-trap test
---
clang/test/CodeGen/builtin-trap.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 clang/test/CodeGen/builtin-trap.c
diff --git a/clang/test/CodeGen/builtin-trap.c b/clang/test/CodeGen/builtin-trap.c
new file mode 100644
index 0000000000000..5572636acdbf2
--- /dev/null
+++ b/clang/test/CodeGen/builtin-trap.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -O0 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -O1 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -emit-llvm -O0 %s -o - | FileCheck %s
+
+// CHECK-LABEL: define {{.*}}void @test_trap()
+void test_trap(void) {
+ // CHECK: call void @llvm.trap()
+ // CHECK-NEXT: unreachable
+ __builtin_trap();
+}
+
+// CHECK-LABEL: define {{.*}}void @test_debugtrap()
+void test_debugtrap(void) {
+ // CHECK: call void @llvm.debugtrap()
+ // CHECK-NOT: unreachable
+ __builtin_debugtrap();
+}
More information about the cfe-commits
mailing list