[llvm] [GlobalISel] Introduce G_TRAP, G_DEBUGTRAP, G_UBSANTRAP (PR #84941)
Evgenii Kudriashov via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 12 09:24:17 PDT 2024
https://github.com/e-kud created https://github.com/llvm/llvm-project/pull/84941
None
>From c0f95151a3f9927f811340721a48cf002f8d60ef Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Mon, 11 Mar 2024 18:44:58 -0700
Subject: [PATCH] [GlobalISel] Introduce G_TRAP, G_DEBUGTRAP, G_UBSANTRAP
---
llvm/docs/GlobalISel/GenericOpcode.rst | 35 +++++++--
llvm/docs/LangRef.rst | 6 ++
.../llvm/CodeGen/GlobalISel/IRTranslator.h | 4 +
.../CodeGen/GlobalISel/MachineIRBuilder.h | 5 ++
llvm/include/llvm/Support/TargetOpcodes.def | 5 ++
llvm/include/llvm/Target/GenericOpcodes.td | 22 ++++++
.../Target/GlobalISel/SelectionDAGCompat.td | 3 +
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 47 ++++++++----
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 3 +
.../GISel/AArch64InstructionSelector.cpp | 20 ++---
.../lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp | 12 +--
llvm/lib/Target/Mips/MipsLegalizerInfo.cpp | 5 --
.../RISCV/GISel/RISCVInstructionSelector.cpp | 27 -------
.../X86/GISel/X86InstructionSelector.cpp | 19 -----
.../GlobalISel/irtranslator-unreachable.ll | 2 +-
.../AArch64/GlobalISel/legalize-exceptions.ll | 2 +-
.../GlobalISel/legalizer-info-validation.mir | 9 +++
.../AArch64/GlobalISel/select-trap.mir | 2 +-
.../AArch64/GlobalISel/uaddo-8-16-bits.mir | 52 ++++++-------
.../AMDGPU/GlobalISel/legalize-trap.mir | 4 +-
.../trap.mir | 9 ++-
.../GlobalISel/instruction-select/trap.mir | 4 +-
.../X86/GlobalISel/x86-select-trap.mir | 2 +-
llvm/test/CodeGen/X86/isel-traps.ll | 73 +++++++++++++++++++
24 files changed, 248 insertions(+), 124 deletions(-)
rename llvm/test/CodeGen/Mips/GlobalISel/{legalizer => instruction-select}/trap.mir (55%)
create mode 100644 llvm/test/CodeGen/X86/isel-traps.ll
diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst
index f9f9e1186460ee..eceaf2def193cc 100644
--- a/llvm/docs/GlobalISel/GenericOpcode.rst
+++ b/llvm/docs/GlobalISel/GenericOpcode.rst
@@ -779,11 +779,17 @@ G_ATOMIC_CMPXCHG
Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
operands.
-G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_AND,
-G_ATOMICRMW_NAND, G_ATOMICRMW_OR, G_ATOMICRMW_XOR, G_ATOMICRMW_MAX,
-G_ATOMICRMW_MIN, G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN, G_ATOMICRMW_FADD,
-G_ATOMICRMW_FSUB, G_ATOMICRMW_FMAX, G_ATOMICRMW_FMIN
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+|all_g_atomicrmw|
+^^^^^^^^^^^^^^^
+
+.. |all_g_atomicrmw| replace:: G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD,
+ G_ATOMICRMW_SUB, G_ATOMICRMW_AND,
+ G_ATOMICRMW_NAND, G_ATOMICRMW_OR,
+ G_ATOMICRMW_XOR, G_ATOMICRMW_MAX,
+ G_ATOMICRMW_MIN, G_ATOMICRMW_UMAX,
+ G_ATOMICRMW_UMIN, G_ATOMICRMW_FADD,
+ G_ATOMICRMW_FSUB, G_ATOMICRMW_FMAX,
+ G_ATOMICRMW_FMIN
Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
operands.
@@ -922,6 +928,25 @@ The _CONVERGENT variant corresponds to an LLVM IR intrinsic marked `convergent`.
Unlike SelectionDAG, there is no _VOID variant. Both of these are permitted
to have zero, one, or multiple results.
+G_TRAP, G_DEBUGTRAP, G_UBSANTRAP
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Represents :ref:`llvm.trap <llvm.trap>`, :ref:`llvm.debugtrap <llvm.debugtrap>`
+and :ref:`llvm.ubsantrap <llvm.ubsantrap>` that generate a target dependent
+trap instructions.
+
+.. code-block:: none
+
+ G_TRAP
+
+.. code-block:: none
+
+ G_DEBUGTRAP
+
+.. code-block:: none
+
+ G_UBSANTRAP 12
+
Variadic Arguments
------------------
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 77ec72f176d6ed..2650903cee5eb6 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -26869,6 +26869,8 @@ Arguments:
The argument should be an MDTuple containing any number of MDStrings.
+.. _llvm.trap:
+
'``llvm.trap``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26896,6 +26898,8 @@ This intrinsic is lowered to the target dependent trap instruction. If
the target does not have a trap instruction, this intrinsic will be
lowered to a call of the ``abort()`` function.
+.. _llvm.debugtrap:
+
'``llvm.debugtrap``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26923,6 +26927,8 @@ This intrinsic is lowered to code which is intended to cause an
execution trap with the intention of requesting the attention of a
debugger.
+.. _llvm.ubsantrap:
+
'``llvm.ubsantrap``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index bfac54a65c5b4e..5d1dcc6b747dd2 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -243,6 +243,10 @@ class IRTranslator : public MachineFunctionPass {
bool translateMemFunc(const CallInst &CI, MachineIRBuilder &MIRBuilder,
unsigned Opcode);
+ /// Translate an LLVM trap intrinsic (trap, debugtrap, ubsantrap).
+ bool translateTrap(const CallInst &U, MachineIRBuilder &MIRBuilder,
+ unsigned Opcode);
+
void getStackGuard(Register DstReg, MachineIRBuilder &MIRBuilder);
bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 4732eaf4ee27c5..90f59e7ebf27dd 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -2091,6 +2091,11 @@ class MachineIRBuilder {
DstMMO, SrcMMO);
}
+ /// Build and insert G_TRAP or G_DEBUGTRAP
+ MachineInstrBuilder buildTrap(bool Debug = false) {
+ return buildInstr(Debug ? TargetOpcode::G_DEBUGTRAP : TargetOpcode::G_TRAP);
+ }
+
/// Build and insert \p Dst = G_SBFX \p Src, \p LSB, \p Width.
MachineInstrBuilder buildSbfx(const DstOp &Dst, const SrcOp &Src,
const SrcOp &LSB, const SrcOp &Width) {
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index 3dade14f043b60..71f0ec9159c045 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -834,6 +834,11 @@ HANDLE_TARGET_OPCODE(G_MEMMOVE)
HANDLE_TARGET_OPCODE(G_MEMSET)
HANDLE_TARGET_OPCODE(G_BZERO)
+/// llvm.trap, llvm.debugtrap and llvm.ubsantrap intrinsics
+HANDLE_TARGET_OPCODE(G_TRAP)
+HANDLE_TARGET_OPCODE(G_DEBUGTRAP)
+HANDLE_TARGET_OPCODE(G_UBSANTRAP)
+
/// Vector reductions
HANDLE_TARGET_OPCODE(G_VECREDUCE_SEQ_FADD)
HANDLE_TARGET_OPCODE(G_VECREDUCE_SEQ_FMUL)
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index 8dc84fb0ba0524..05bdb7f166322e 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -1566,6 +1566,28 @@ def G_BZERO : GenericInstruction {
let mayStore = true;
}
+//------------------------------------------------------------------------------
+// Trap intrinsics
+//------------------------------------------------------------------------------
+def G_TRAP : GenericInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins);
+ let hasSideEffects = true;
+ let mayStore = true;
+}
+
+def G_DEBUGTRAP : GenericInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins);
+ let hasSideEffects = true;
+}
+
+def G_UBSANTRAP : GenericInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins untyped_imm_0:$kind);
+ let hasSideEffects = true;
+}
+
//------------------------------------------------------------------------------
// Bitfield extraction.
//------------------------------------------------------------------------------
diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index b1f3c500a1b6c5..4bb9929e2cf8ba 100644
--- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
+++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -250,6 +250,9 @@ def : GINodeEquiv<G_ATOMICRMW_UINC_WRAP, atomic_load_uinc_wrap>;
def : GINodeEquiv<G_ATOMICRMW_UDEC_WRAP, atomic_load_udec_wrap>;
def : GINodeEquiv<G_FENCE, atomic_fence>;
def : GINodeEquiv<G_PREFETCH, prefetch>;
+def : GINodeEquiv<G_TRAP, trap>;
+def : GINodeEquiv<G_DEBUGTRAP, debugtrap>;
+def : GINodeEquiv<G_UBSANTRAP, ubsantrap>;
// Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern.
// Should be used on defs that subclass GIComplexOperandMatcher<>.
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 365870f540daeb..504ba23029b64c 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1770,6 +1770,32 @@ bool IRTranslator::translateMemFunc(const CallInst &CI,
return true;
}
+bool IRTranslator::translateTrap(const CallInst &CI,
+ MachineIRBuilder &MIRBuilder,
+ unsigned Opcode) {
+ StringRef TrapFuncName =
+ CI.getAttributes().getFnAttr("trap-func-name").getValueAsString();
+ if (TrapFuncName.empty()) {
+ if (Opcode == TargetOpcode::G_UBSANTRAP) {
+ uint64_t Code = cast<ConstantInt>(CI.getOperand(0))->getZExtValue();
+ MIRBuilder.buildInstr(Opcode, {}, ArrayRef<llvm::SrcOp>{Code});
+ } else {
+ MIRBuilder.buildInstr(Opcode);
+ }
+ return true;
+ }
+
+ CallLowering::CallLoweringInfo Info;
+ if (Opcode == TargetOpcode::G_UBSANTRAP)
+ Info.OrigArgs.push_back({getOrCreateVRegs(*CI.getArgOperand(0)),
+ CI.getArgOperand(0)->getType(), 0});
+
+ Info.Callee = MachineOperand::CreateES(TrapFuncName.data());
+ Info.CB = &CI;
+ Info.OrigRet = {Register(), Type::getVoidTy(CI.getContext()), 0};
+ return CLI->lowerCall(MIRBuilder, Info);
+}
+
void IRTranslator::getStackGuard(Register DstReg,
MachineIRBuilder &MIRBuilder) {
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
@@ -2393,22 +2419,11 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
return true;
}
case Intrinsic::trap:
+ return translateTrap(CI, MIRBuilder, TargetOpcode::G_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(TrapFuncName.data());
- Info.CB = &CI;
- Info.OrigRet = {Register(), Type::getVoidTy(CI.getContext()), 0};
- return CLI->lowerCall(MIRBuilder, Info);
- }
+ return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
+ case Intrinsic::ubsantrap:
+ return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
case Intrinsic::amdgcn_cs_chain:
return translateCallBase(CI, MIRBuilder);
case Intrinsic::fptrunc_round: {
@@ -2949,7 +2964,7 @@ bool IRTranslator::translateUnreachable(const User &U, MachineIRBuilder &MIRBuil
}
}
- MIRBuilder.buildIntrinsic(Intrinsic::trap, ArrayRef<Register>());
+ MIRBuilder.buildTrap();
return true;
}
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 6254e68326f79d..b698d881f7e211 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -8423,6 +8423,9 @@ def ubsan_trap_xform : SDNodeXForm<timm, [{
return CurDAG->getTargetConstant(N->getZExtValue() | ('U' << 8), SDLoc(N), MVT::i32);
}]>;
+def gi_ubsan_trap_xform : GICustomOperandRenderer<"renderUbsanTrap">,
+ GISDNodeXFormEquiv<ubsan_trap_xform>;
+
def ubsan_trap_imm : TImmLeaf<i32, [{
return isUInt<8>(Imm);
}], ubsan_trap_xform>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 0f3c3cb96e6ce3..175aa9fcb8648c 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -479,6 +479,8 @@ class AArch64InstructionSelector : public InstructionSelector {
int OpIdx = -1) const;
void renderLogicalImm64(MachineInstrBuilder &MIB, const MachineInstr &I,
int OpIdx = -1) const;
+ void renderUbsanTrap(MachineInstrBuilder &MIB, const MachineInstr &MI,
+ int OpIdx) const;
void renderFPImm16(MachineInstrBuilder &MIB, const MachineInstr &MI,
int OpIdx = -1) const;
void renderFPImm32(MachineInstrBuilder &MIB, const MachineInstr &MI,
@@ -6140,16 +6142,6 @@ bool AArch64InstructionSelector::selectIntrinsicWithSideEffects(
constrainSelectedInstRegOperands(*NewI, TII, TRI, RBI);
break;
}
- case Intrinsic::trap:
- MIB.buildInstr(AArch64::BRK, {}, {}).addImm(1);
- break;
- case Intrinsic::debugtrap:
- MIB.buildInstr(AArch64::BRK, {}, {}).addImm(0xF000);
- break;
- case Intrinsic::ubsantrap:
- MIB.buildInstr(AArch64::BRK, {}, {})
- .addImm(I.getOperand(1).getImm() | ('U' << 8));
- break;
case Intrinsic::aarch64_neon_ld1x2: {
LLT Ty = MRI.getType(I.getOperand(0).getReg());
unsigned Opc = 0;
@@ -7644,6 +7636,14 @@ void AArch64InstructionSelector::renderLogicalImm64(
MIB.addImm(Enc);
}
+void AArch64InstructionSelector::renderUbsanTrap(MachineInstrBuilder &MIB,
+ const MachineInstr &MI,
+ int OpIdx) const {
+ assert(MI.getOpcode() == TargetOpcode::G_UBSANTRAP && OpIdx == 0 &&
+ "Expected G_UBSANTRAP");
+ MIB.addImm(MI.getOperand(0).getImm() | ('U' << 8));
+}
+
void AArch64InstructionSelector::renderFPImm16(MachineInstrBuilder &MIB,
const MachineInstr &MI,
int OpIdx) const {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index 0029c51231f286..dcccfd92df03fd 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -2030,6 +2030,8 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
getActionDefinitionsBuilder({G_MEMCPY, G_MEMCPY_INLINE, G_MEMMOVE, G_MEMSET})
.lower();
+ getActionDefinitionsBuilder({G_TRAP, G_DEBUGTRAP}).custom();
+
getActionDefinitionsBuilder({G_VASTART, G_VAARG, G_BRJT, G_JUMP_TABLE,
G_INDEXED_LOAD, G_INDEXED_SEXTLOAD,
G_INDEXED_ZEXTLOAD, G_INDEXED_STORE})
@@ -2134,6 +2136,10 @@ bool AMDGPULegalizerInfo::legalizeCustom(
return legalizeGetFPEnv(MI, MRI, B);
case TargetOpcode::G_SET_FPENV:
return legalizeSetFPEnv(MI, MRI, B);
+ case TargetOpcode::G_TRAP:
+ return legalizeTrapIntrinsic(MI, MRI, B);
+ case TargetOpcode::G_DEBUGTRAP:
+ return legalizeDebugTrapIntrinsic(MI, MRI, B);
default:
return false;
}
@@ -2925,7 +2931,7 @@ bool AMDGPULegalizerInfo::legalizeGlobalValue(
// functions that use local objects. However, if these dead functions are
// not eliminated, we don't want a compile time error. Just emit a warning
// and a trap, since there should be no callable path here.
- B.buildIntrinsic(Intrinsic::trap, ArrayRef<Register>());
+ B.buildTrap();
B.buildUndef(DstReg);
MI.eraseFromParent();
return true;
@@ -7270,10 +7276,6 @@ bool AMDGPULegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
case Intrinsic::amdgcn_struct_buffer_atomic_fadd_v2bf16:
case Intrinsic::amdgcn_struct_ptr_buffer_atomic_fadd_v2bf16:
return legalizeBufferAtomic(MI, B, IntrID);
- case Intrinsic::trap:
- return legalizeTrapIntrinsic(MI, MRI, B);
- case Intrinsic::debugtrap:
- return legalizeDebugTrapIntrinsic(MI, MRI, B);
case Intrinsic::amdgcn_rsq_clamp:
return legalizeRsqClampIntrinsic(MI, MRI, B);
case Intrinsic::amdgcn_ds_fadd:
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index f5e94235859a06..b96a3903222d73 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -513,11 +513,6 @@ bool MipsLegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
const RegisterBankInfo &RBI = *ST.getRegBankInfo();
switch (cast<GIntrinsic>(MI).getIntrinsicID()) {
- case Intrinsic::trap: {
- MachineInstr *Trap = MIRBuilder.buildInstr(Mips::TRAP);
- MI.eraseFromParent();
- return constrainSelectedInstRegOperands(*Trap, TII, TRI, RBI);
- }
case Intrinsic::vacopy: {
MachinePointerInfo MPO;
LLT PtrTy = LLT::pointer(0, 32);
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 5738f86e7e9ff5..3103992a86c099 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -77,8 +77,6 @@ class RISCVInstructionSelector : public InstructionSelector {
MachineRegisterInfo &MRI) const;
bool selectFPCompare(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI) const;
- bool selectIntrinsicWithSideEffects(MachineInstr &MI, MachineIRBuilder &MIB,
- MachineRegisterInfo &MRI) const;
void emitFence(AtomicOrdering FenceOrdering, SyncScope::ID FenceSSID,
MachineIRBuilder &MIB) const;
bool selectMergeValues(MachineInstr &MI, MachineIRBuilder &MIB,
@@ -686,8 +684,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
return selectSelect(MI, MIB, MRI);
case TargetOpcode::G_FCMP:
return selectFPCompare(MI, MIB, MRI);
- case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
- return selectIntrinsicWithSideEffects(MI, MIB, MRI);
case TargetOpcode::G_FENCE: {
AtomicOrdering FenceOrdering =
static_cast<AtomicOrdering>(MI.getOperand(0).getImm());
@@ -1255,29 +1251,6 @@ bool RISCVInstructionSelector::selectFPCompare(MachineInstr &MI,
return true;
}
-bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
- MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI) const {
- assert(MI.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS &&
- "Unexpected opcode");
- // Find the intrinsic ID.
- unsigned IntrinID = cast<GIntrinsic>(MI).getIntrinsicID();
-
- // Select the instruction.
- switch (IntrinID) {
- default:
- return false;
- case Intrinsic::trap:
- MIB.buildInstr(RISCV::UNIMP, {}, {});
- break;
- case Intrinsic::debugtrap:
- MIB.buildInstr(RISCV::EBREAK, {}, {});
- break;
- }
-
- MI.eraseFromParent();
- return true;
-}
-
void RISCVInstructionSelector::emitFence(AtomicOrdering FenceOrdering,
SyncScope::ID FenceSSID,
MachineIRBuilder &MIB) const {
diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index 8e0f61a855661b..9be3812300af12 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -119,8 +119,6 @@ class X86InstructionSelector : public InstructionSelector {
MachineFunction &MF) const;
bool selectSelect(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
- bool selectIntrinsicWSideEffects(MachineInstr &I, MachineRegisterInfo &MRI,
- MachineFunction &MF) const;
// emit insert subreg instruction and insert it before MachineInstr &I
bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
@@ -434,8 +432,6 @@ bool X86InstructionSelector::select(MachineInstr &I) {
return selectMulDivRem(I, MRI, MF);
case TargetOpcode::G_SELECT:
return selectSelect(I, MRI, MF);
- case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
- return selectIntrinsicWSideEffects(I, MRI, MF);
}
return false;
@@ -1834,21 +1830,6 @@ bool X86InstructionSelector::selectSelect(MachineInstr &I,
return true;
}
-bool X86InstructionSelector::selectIntrinsicWSideEffects(
- MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) const {
-
- assert(I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS &&
- "unexpected instruction");
-
- if (I.getOperand(0).getIntrinsicID() != Intrinsic::trap)
- return false;
-
- BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TRAP));
-
- I.eraseFromParent();
- return true;
-}
-
InstructionSelector *
llvm::createX86InstructionSelector(const X86TargetMachine &TM,
X86Subtarget &Subtarget,
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unreachable.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unreachable.ll
index fe9427d2678a16..edae903fae848f 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unreachable.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unreachable.ll
@@ -6,7 +6,7 @@ declare void @llvm.trap()
define void @unreachable() {
; CHECK-LABEL: name: unreachable
; CHECK: bb.1 (%ir-block.0):
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
unreachable
ret void
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll
index 5662de4cbdca52..f7550ceb2799a5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll
@@ -48,7 +48,7 @@ define void @bar() personality ptr @__gxx_personality_v0 {
; CHECK-NEXT: $x0 = COPY [[LOAD]](p0)
; CHECK-NEXT: BL @_Unwind_Resume, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
%exn.slot = alloca ptr
%ehselector.slot = alloca i32
%1 = invoke i32 @foo(i32 42) to label %continue unwind label %cleanup
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
index ac330918b430a0..61053b2ba769f8 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
@@ -749,6 +749,15 @@
# DEBUG-NEXT: G_BZERO (opcode {{[0-9]+}}): 2 type indices, 1 imm index
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: G_TRAP (opcode {{[0-9]+}}): 0 type indices, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_DEBUGTRAP (opcode {{[0-9]+}}): 0 type indices, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_UBSANTRAP (opcode {{[0-9]+}}): 0 type indices, 1 imm index
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_VECREDUCE_SEQ_FADD (opcode {{[0-9]+}}): 3 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-trap.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-trap.mir
index ad66fa5623e3da..25ecce4dd92bf8 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-trap.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-trap.mir
@@ -26,7 +26,7 @@ body: |
; CHECK-LABEL: name: foo
; CHECK: BRK 1
; CHECK: RET_ReallyLR
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
RET_ReallyLR
...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/uaddo-8-16-bits.mir b/llvm/test/CodeGen/AArch64/GlobalISel/uaddo-8-16-bits.mir
index f4366fb7888ead..b242c68e3b07f5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/uaddo-8-16-bits.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/uaddo-8-16-bits.mir
@@ -26,7 +26,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: $w0 = COPY [[ADD]](s32)
@@ -48,7 +48,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%8:_(s32) = G_ZEXT %6(s8)
@@ -80,7 +80,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: $w0 = COPY [[ADD]](s32)
@@ -102,7 +102,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%8:_(s32) = G_ZEXT %6(s16)
@@ -134,7 +134,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: liveins: $x2
@@ -165,7 +165,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
liveins: $x2
@@ -206,7 +206,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: $w0 = COPY [[ADD]](s32)
@@ -228,7 +228,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%8:_(s32) = G_ANYEXT %6(s16)
@@ -261,7 +261,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: $w0 = COPY [[ADD]](s32)
@@ -284,7 +284,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%8:_(s32) = G_ZEXT %6(s16)
@@ -317,7 +317,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: $w0 = COPY [[ADD]](s32)
@@ -340,7 +340,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%8:_(s32) = G_ZEXT %6(s16)
@@ -377,7 +377,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: liveins: $x2
@@ -410,7 +410,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
liveins: $x2
@@ -512,7 +512,7 @@ body: |
; CHECK-NEXT: bb.2:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3:
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[UADDO]](s16)
@@ -544,7 +544,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%9:_(s32) = G_ZEXT %6(s16)
@@ -577,7 +577,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[UADDO]](s8)
@@ -601,7 +601,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%9:_(s32) = G_ZEXT %7(s8)
@@ -634,7 +634,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[UADDO]](s8)
@@ -658,7 +658,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%9:_(s32) = G_ZEXT %7(s8)
@@ -692,7 +692,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[UADDO]](s8)
@@ -717,7 +717,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%10:_(s32) = G_ZEXT %8(s8)
@@ -783,7 +783,7 @@ body: |
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors:
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UADDO]](s16)
@@ -804,7 +804,7 @@ body: |
bb.2:
successors:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.3:
%6:_(s32) = G_ANYEXT %4(s16)
@@ -839,7 +839,7 @@ body: |
; CHECK-NEXT: RET_ReallyLR implicit $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
- ; CHECK-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; CHECK-NEXT: G_TRAP
bb.1:
successors: %bb.2(0x7ffff800), %bb.3(0x00000800)
liveins: $w0, $w1
@@ -860,6 +860,6 @@ body: |
RET_ReallyLR implicit $w0
bb.3:
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
...
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-trap.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-trap.mir
index b4bc64812b532a..305eca792cfbcc 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-trap.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-trap.mir
@@ -24,7 +24,7 @@ body: |
bb.0:
%0:_(s8) = G_CONSTANT i8 0
%1:_(p1) = G_CONSTANT i64 0
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
bb.1:
G_STORE %0, %1 :: (store 1, addrspace 1)
@@ -55,7 +55,7 @@ body: |
; GCN-NEXT: S_ENDPGM 0
bb.0:
%0:_(s8) = G_CONSTANT i8 0
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
%1:_(p1) = G_CONSTANT i64 0
bb.1:
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/trap.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/trap.mir
similarity index 55%
rename from llvm/test/CodeGen/Mips/GlobalISel/legalizer/trap.mir
rename to llvm/test/CodeGen/Mips/GlobalISel/instruction-select/trap.mir
index 64388933fda88b..dc99ce8d7a099f 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/trap.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/trap.mir
@@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
--- |
declare void @llvm.trap()
@@ -9,12 +9,15 @@
---
name: f
alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
body: |
bb.1 (%ir-block.0):
; MIPS32-LABEL: name: f
; MIPS32: TRAP
- ; MIPS32: RetRA
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ ; MIPS32-NEXT: RetRA
+ G_TRAP
RetRA
...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/trap.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/trap.mir
index 11789a030e6fac..5f52030fc17012 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/trap.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/trap.mir
@@ -14,7 +14,7 @@ body: |
; CHECK-LABEL: name: test_trap
; CHECK: UNIMP
; CHECK-NEXT: PseudoRET
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
PseudoRET
...
@@ -28,7 +28,7 @@ body: |
; CHECK-LABEL: name: test_debugtrap
; CHECK: EBREAK
; CHECK-NEXT: PseudoRET
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.debugtrap)
+ G_DEBUGTRAP
PseudoRET
...
diff --git a/llvm/test/CodeGen/X86/GlobalISel/x86-select-trap.mir b/llvm/test/CodeGen/X86/GlobalISel/x86-select-trap.mir
index ea548c296dcaf6..20b8b671ac5a53 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/x86-select-trap.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/x86-select-trap.mir
@@ -23,6 +23,6 @@ body: |
bb.1 (%ir-block.0):
; CHECK-LABEL: name: trap
; CHECK: TRAP
- G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.trap)
+ G_TRAP
...
diff --git a/llvm/test/CodeGen/X86/isel-traps.ll b/llvm/test/CodeGen/X86/isel-traps.ll
new file mode 100644
index 00000000000000..c207387166a6bc
--- /dev/null
+++ b/llvm/test/CodeGen/X86/isel-traps.ll
@@ -0,0 +1,73 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=ALL,X64
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=ALL,X64
+; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=ALL,GISEL-X64
+; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=ALL,X86
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=ALL,X86
+; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=ALL,GISEL-X86
+
+declare void @llvm.trap()
+
+define void @test_trap() {
+; ALL-LABEL: test_trap:
+; ALL: # %bb.0:
+; ALL-NEXT: ud2
+; ALL-NEXT: ret{{[l|q]}}
+ tail call void @llvm.trap()
+ ret void
+}
+
+define void @test_debugtrap() {
+; ALL-LABEL: test_debugtrap:
+; ALL: # %bb.0:
+; ALL-NEXT: int3
+; ALL-NEXT: ret{{[l|q]}}
+ tail call void @llvm.debugtrap()
+ ret void
+}
+
+define void @test_ubsantrap() {
+; ALL-LABEL: test_ubsantrap:
+; ALL: # %bb.0:
+; ALL-NEXT: ud1l 12(%eax), %eax
+; ALL-NEXT: ret{{[l|q]}}
+ call void @llvm.ubsantrap(i8 12)
+ ret void
+}
+
+define void @test_ubsantrap_custom() nounwind {
+; X64-LABEL: test_ubsantrap_custom:
+; X64: # %bb.0:
+; X64-NEXT: pushq %rax
+; X64-NEXT: movl $42, %edi
+; X64-NEXT: callq guide at PLT
+; X64-NEXT: popq %rax
+; X64-NEXT: retq
+;
+; GISEL-X64-LABEL: test_ubsantrap_custom:
+; GISEL-X64: # %bb.0:
+; GISEL-X64-NEXT: pushq %rax
+; GISEL-X64-NEXT: movl $42, %edi
+; GISEL-X64-NEXT: callq guide
+; GISEL-X64-NEXT: popq %rax
+; GISEL-X64-NEXT: retq
+;
+; X86-LABEL: test_ubsantrap_custom:
+; X86: # %bb.0:
+; X86-NEXT: subl $12, %esp
+; X86-NEXT: movl $42, (%esp)
+; X86-NEXT: calll guide
+; X86-NEXT: addl $12, %esp
+; X86-NEXT: retl
+;
+; GISEL-X86-LABEL: test_ubsantrap_custom:
+; GISEL-X86: # %bb.0:
+; GISEL-X86-NEXT: subl $12, %esp
+; GISEL-X86-NEXT: movl $42, %eax
+; GISEL-X86-NEXT: movl %eax, (%esp)
+; GISEL-X86-NEXT: calll guide
+; GISEL-X86-NEXT: addl $12, %esp
+; GISEL-X86-NEXT: retl
+ call void @llvm.ubsantrap(i8 42) "trap-func-name"="guide"
+ ret void
+}
More information about the llvm-commits
mailing list