Author: Ambrose Leeb Date: 2026-09-04T19:24:34+02:00 New Revision: f5afe7a2ecb261b46800d60328d5943b4f80978a
URL: https://github.com/llvm/llvm-project/commit/f5afe7a2ecb261b46800d60328d5943b4f80978a DIFF: https://github.com/llvm/llvm-project/commit/f5afe7a2ecb261b46800d60328d5943b4f80978a.diff LOG: [NFC] [Clang] [CodeGen] Reduce code duplication when emitting trap calls (#221022) There are a number of places in codegen where we do this: ```c++ llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); TrapCall->setDoesNotReturn(); TrapCall->setDoesNotThrow(); Builder.CreateUnreachable(); Builder.ClearInsertionPoint(); ``` This patch adds a helper that does this and updates `EmitTrapCall()` to no longer create a new block after emitting the trap call. One test had to be updated because an unnecessary block was dropped. Before, we were generating this: ```llvm dtor.call_delete_after_array_destroy: ; preds = %dtor.vector.cont call void @llvm.trap() #7 unreachable 6: ; No predecessors! unreachable ``` The second block here is now no longer present, which caused some instruction renumbering. Added: Modified: clang/lib/CodeGen/CGClass.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenFunction.h clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index e51f3f9ac9cb4..ffa1304253519 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1424,11 +1424,7 @@ static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD, } } else { // No operators delete[] were found, so emit a trap. - llvm::CallInst *TrapCall = CGF.EmitTrapCall(llvm::Intrinsic::trap); - TrapCall->setDoesNotReturn(); - TrapCall->setDoesNotThrow(); - CGF.Builder.CreateUnreachable(); - CGF.Builder.ClearInsertionPoint(); + CGF.EmitTrapCallAndMakeUnreachable(); } CGF.EmitBranchThroughCleanup(CGF.ReturnBlock); @@ -1446,11 +1442,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { // in fact emit references to them from other compilations, so emit them // as functions containing a trap instruction. if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) { - llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); - TrapCall->setDoesNotReturn(); - TrapCall->setDoesNotThrow(); - Builder.CreateUnreachable(); - Builder.ClearInsertionPoint(); + EmitTrapCallAndMakeUnreachable(); return; } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 6e78ed6b7cabb..1ca649afb197a 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4622,7 +4622,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 EnsureInsertPoint) { llvm::Function *TrapIntrinsic = CGM.getIntrinsic(IntrID); llvm::CallInst *TrapCall = Builder.CreateCall(TrapIntrinsic); @@ -4639,11 +4640,25 @@ llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) { if (TrapIntrinsic->doesNotReturn()) { TrapCall->setDoesNotReturn(); Builder.CreateUnreachable(); - EmitBlock(createBasicBlock()); + if (EnsureInsertPoint) + EmitBlock(createBasicBlock()); + else + Builder.ClearInsertionPoint(); } return TrapCall; } +void CodeGenFunction::EmitTrapCallAndMakeUnreachable() { + llvm::CallInst *TrapCall = + EmitTrapCall(llvm::Intrinsic::trap, /*EnsureInsertPoint=*/false); + TrapCall->setDoesNotReturn(); + TrapCall->setDoesNotThrow(); + if (HaveInsertPoint()) { + Builder.CreateUnreachable(); + Builder.ClearInsertionPoint(); + } +} + Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 119aebb673789..7e7f9a072f765 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -3267,11 +3267,7 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver( // If no generic/default, emit an unreachable. Builder.SetInsertPoint(CurBlock); - llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); - TrapCall->setDoesNotReturn(); - TrapCall->setDoesNotThrow(); - Builder.CreateUnreachable(); - Builder.ClearInsertionPoint(); + EmitTrapCallAndMakeUnreachable(); } void CodeGenFunction::EmitAArch64MultiVersionResolver( @@ -3316,11 +3312,7 @@ void CodeGenFunction::EmitAArch64MultiVersionResolver( // If no default, emit an unreachable. Builder.SetInsertPoint(CurBlock); - llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); - TrapCall->setDoesNotReturn(); - TrapCall->setDoesNotThrow(); - Builder.CreateUnreachable(); - Builder.ClearInsertionPoint(); + EmitTrapCallAndMakeUnreachable(); } void CodeGenFunction::EmitX86MultiVersionResolver( @@ -3356,11 +3348,7 @@ void CodeGenFunction::EmitX86MultiVersionResolver( // If no generic/default, emit an unreachable. Builder.SetInsertPoint(CurBlock); - llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); - TrapCall->setDoesNotReturn(); - TrapCall->setDoesNotThrow(); - Builder.CreateUnreachable(); - Builder.ClearInsertionPoint(); + EmitTrapCallAndMakeUnreachable(); } // Loc - where the diagnostic will point, where in the source code this diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 7bdc79d86ea0a..3c8188c4cefdd 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -5441,9 +5441,13 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge = false, const TrapReason *TR = nullptr); - /// Emit a call to trap or debugtrap and attach function attribute - /// "trap-func-name" if specified. - llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID); + /// Emit a call to trap or debugtrap. If 'EnsureInsertPoint' is false, the + /// IR builder need not have a valid insert point after this returns. + llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID, + bool EnsureInsertPoint = true); + + /// Emit a call to '\@llvm.trap()' and clear the current insert point. + void EmitTrapCallAndMakeUnreachable(); /// Emit a stub for the cross-DSO CFI check function. void EmitCfiCheckStub(); diff --git a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp index 465010ef752cb..fc6ce1763c86c 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@XZ"(ptr noundef nonnull align 8 dead_on_return(8) dereferenceable(8) %this1) // X86-NEXT: call x86_thiscallcc void @"??1Test@@UAE@XZ"(ptr noundef nonnull align 4 dead_on_return(4) dereferenceable(4) %this1) -// 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-NEXT: %[[AND:[0-9]+]] = and i32 %should_call_delete2, 1 +// CHECK-NEXT: %[[ICMP:[0-9]+]] = icmp eq i32 %[[AND]], 0 +// CHECK-NEXT: br i1 %[[ICMP]], label %dtor.continue, label %dtor.call_delete // CHECK: dtor.call_delete: // X64-NEXT: call void @"??3Test@@SAXPEAX@Z"(ptr noundef %this1) // X86-NEXT: call void @"??3Test@@SAXPAX@Z"(ptr noundef %this1) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
