diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -57,6 +57,8 @@ setOperationAction(ISD::FP_TO_SINT, GRLenVT, Custom); setOperationAction(ISD::ROTL, GRLenVT, Expand); setOperationAction(ISD::CTPOP, GRLenVT, Expand); + setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal); + setOperationAction(ISD::TRAP, MVT::Other, Legal); setOperationAction({ISD::GlobalAddress, ISD::ConstantPool}, GRLenVT, Custom); diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -741,6 +741,17 @@ def : Pat<(or GPR:$rj, (not GPR:$rk)), (ORN GPR:$rj, GPR:$rk)>; def : Pat<(and GPR:$rj, (not GPR:$rk)), (ANDN GPR:$rj, GPR:$rk)>; +/// Traps + +// We lower `trap` to `break 0` as this is guaranteed to exist and work, even +// for LA32 Primary. +def : Pat<(trap), (BREAK 0)>; + +// We lower `debugtrap` also to `break 0` because so far the ISA does not +// provide a specific trap instruction/kind for specifically alerting the +// debugger. +def : Pat<(debugtrap), (BREAK 0)>; + /// Bit counting operations let Predicates = [IsLA64] in { diff --git a/llvm/test/CodeGen/LoongArch/trap.ll b/llvm/test/CodeGen/LoongArch/trap.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/trap.ll @@ -0,0 +1,38 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +; RUN: | FileCheck --check-prefix=LA32 %s +; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +; RUN: | FileCheck --check-prefix=LA64 %s + +;; Verify that we lower @llvm.trap() and @llvm.debugtrap() correctly. + +declare void @llvm.trap() +declare void @llvm.debugtrap() + +define void @test_trap() nounwind { +; LA32-LABEL: test_trap: +; LA32: # %bb.0: +; LA32-NEXT: break 0 +; LA32-NEXT: ret +; +; LA64-LABEL: test_trap: +; LA64: # %bb.0: +; LA64-NEXT: break 0 +; LA64-NEXT: ret + tail call void @llvm.trap() + ret void +} + +define void @test_debugtrap() nounwind { +; LA32-LABEL: test_debugtrap: +; LA32: # %bb.0: +; LA32-NEXT: break 0 +; LA32-NEXT: ret +; +; LA64-LABEL: test_debugtrap: +; LA64: # %bb.0: +; LA64-NEXT: break 0 +; LA64-NEXT: ret + tail call void @llvm.debugtrap() + ret void +}