Skip to content

Commit

Permalink
[LoongArch] Add support for llvm.trap and llvm.debugtrap
Browse files Browse the repository at this point in the history
Similar to D69390 for RISCV, use a guaranteed non-existing insn for
llvm.trap and the break insn for llvm.debugtrap.

Differential Revision: https://reviews.llvm.org/D134365
  • Loading branch information
xen0n authored and SixWeining committed Oct 13, 2022
1 parent f793597 commit f017e92
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
2 changes: 2 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Expand Up @@ -57,6 +57,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
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::BlockAddress, ISD::ConstantPool,
ISD::JumpTable},
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
Expand Up @@ -742,6 +742,21 @@ def : Pat<(not (or GPR:$rj, GPR:$rk)), (NOR GPR:$rj, GPR:$rk)>;
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 `amswap.w rd:$r0, rk:$r1, rj:$r0`, as this is guaranteed
// to trap with an INE (non-existent on LA32, explicitly documented to INE on
// LA64). And the resulting signal is different from `debugtrap` like on some
// other existing ports so programs/porters might have an easier time.
def PseudoUNIMP : Pseudo<(outs), (ins), [(trap)]>,
PseudoInstExpansion<(AMSWAP_W R0, R1, R0)>;

// We lower `debugtrap` to `break 0`, as this is guaranteed to exist and work,
// even for LA32 Primary. Also, because so far the ISA does not provide a
// specific trap instruction/kind exclusively for alerting the debugger,
// every other project uses the generic immediate of 0 for this.
def : Pat<(debugtrap), (BREAK 0)>;

/// Bit counting operations

let Predicates = [IsLA64] in {
Expand Down
26 changes: 26 additions & 0 deletions llvm/test/CodeGen/LoongArch/trap.ll
@@ -0,0 +1,26 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s
; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s

;; Verify that we lower @llvm.trap() and @llvm.debugtrap() correctly.

declare void @llvm.trap()
declare void @llvm.debugtrap()

define void @test_trap() nounwind {
; CHECK-LABEL: test_trap:
; CHECK: # %bb.0:
; CHECK-NEXT: amswap.w $zero, $ra, $zero
; CHECK-NEXT: ret
tail call void @llvm.trap()
ret void
}

define void @test_debugtrap() nounwind {
; CHECK-LABEL: test_debugtrap:
; CHECK: # %bb.0:
; CHECK-NEXT: break 0
; CHECK-NEXT: ret
tail call void @llvm.debugtrap()
ret void
}

0 comments on commit f017e92

Please sign in to comment.