diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2225,6 +2225,24 @@ return true; } + case Intrinsic::trap: + case Intrinsic::debugtrap: + case Intrinsic::ubsantrap: { + StringRef TrapFuncName = + CI.getAttributes().getFnAttr("trap-func-name").getValueAsString(); + if (TrapFuncName.empty()) + break; // Use the default handling. + CallLowering::CallLoweringInfo Info; + if (ID == Intrinsic::ubsantrap) { + Info.OrigArgs.push_back({getOrCreateVRegs(*CI.getArgOperand(0)), + CI.getArgOperand(0)->getType(), 0}); + } + Info.Callee = + MachineOperand::CreateES(MF->createExternalSymbolName(TrapFuncName)); + Info.CB = &CI; + Info.OrigRet = {Register(), Type::getVoidTy(CI.getContext()), 0}; + return CLI->lowerCall(MIRBuilder, Info); + } #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ case Intrinsic::INTRINSIC: #include "llvm/IR/ConstrainedOps.def" diff --git a/llvm/test/CodeGen/AArch64/arm64-trap.ll b/llvm/test/CodeGen/AArch64/arm64-trap.ll --- a/llvm/test/CodeGen/AArch64/arm64-trap.ll +++ b/llvm/test/CodeGen/AArch64/arm64-trap.ll @@ -1,8 +1,19 @@ ; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s +; RUN: llc < %s -mtriple=arm64-eabi -global-isel | FileCheck %s define void @foo() nounwind { -; CHECK: foo +; CHECK-LABEL: foo ; CHECK: brk #0x1 tail call void @llvm.trap() ret void } declare void @llvm.trap() nounwind + +; CHECK-LABEL: {{\_?}}foo_trap_func: +; CHECK: bl trap_func + +define void @foo_trap_func() { + call void @llvm.trap() #0 + unreachable +} + +attributes #0 = { "trap-func-name"="trap_func" } diff --git a/llvm/test/CodeGen/AArch64/debugtrap.ll b/llvm/test/CodeGen/AArch64/debugtrap.ll --- a/llvm/test/CodeGen/AArch64/debugtrap.ll +++ b/llvm/test/CodeGen/AArch64/debugtrap.ll @@ -1,12 +1,13 @@ ; RUN: llc -mtriple=aarch64-windows %s -o -| FileCheck %s -; RUN: llc -mtriple=aarch64-windows -fast-isel %s -o - | FileCheck %s +; RUN: llc -mtriple=aarch64-windows -fast-isel %s -o - | FileCheck %s --check-prefix=FASTISEL ; RUN: llc -mtriple=aarch64-windows -global-isel %s -o - | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-gnu %s -o -| FileCheck %s ; RUN: llc -mtriple=arm64-apple-ios -global-isel %s -o - | FileCheck %s -; RUN: llc -mtriple=arm64-apple-macosx -fast-isel %s -o - | FileCheck %s +; RUN: llc -mtriple=arm64-apple-macosx -fast-isel %s -o - | FileCheck %s --check-prefix=FASTISEL ; CHECK-LABEL: test1: ; CHECK: brk #0xf000 +; FASTISEL: brk #0xf000 define void @test1() noreturn nounwind { entry: tail call void @llvm.debugtrap( ) @@ -14,3 +15,14 @@ } declare void @llvm.debugtrap() nounwind + +; CHECK-LABEL: test_trap_func: +; CHECK: bl {{.*}}wibble + +; FastISel doesn't handle trap-func-name for debugtrap. +; FASTISEL: brk +define void @test_trap_func() noreturn nounwind { +entry: + tail call void @llvm.debugtrap( ) "trap-func-name"="wibble" + ret void +} \ No newline at end of file diff --git a/llvm/test/CodeGen/AArch64/ubsantrap.ll b/llvm/test/CodeGen/AArch64/ubsantrap.ll --- a/llvm/test/CodeGen/AArch64/ubsantrap.ll +++ b/llvm/test/CodeGen/AArch64/ubsantrap.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=arm64-apple-ios %s -o - | FileCheck %s +; RUN: llc -mtriple=arm64-apple-ios -global-isel %s -o - | FileCheck %s define void @test_ubsantrap() { ; CHECK-LABEL: test_ubsantrap