From d365a45cb3eaa640b09874fb7984a6a69683c773 Mon Sep 17 00:00:00 2001 From: Evgenii Kudriashov Date: Sat, 23 Mar 2024 15:12:44 +0300 Subject: [PATCH] [GlobalISel] Introduce G_TRAP, G_DEBUGTRAP, G_UBSANTRAP (#84941) Here we introduce three new GMIR instructions to cover a set of trap intrinsics. The idea behind it is that generic intrinsics shouldn't be used with G_INTRINSIC opcode. These new instructions can match perfectly with existing trap ISD nodes. It allows X86, AArch64, RISCV and Mips to reuse SelectionDAG patterns for selection and avoid manual selection. However AMDGPU is an exception. It selects traps during legalization regardless SelectionDAG or GlobalISel. Since there are not many places where traps are used, this change attempts to clean up all the usages of G_INTRINSIC with trap intrinsics. So, there is no stage when both G_TRAP and G_INTRINSIC_W_SIDE_EFFECTS(@llvm.trap) are allowed. --- llvm/docs/GlobalISel/GenericOpcode.rst | 19 +++++ 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/CodeGen/MachineVerifier.cpp | 11 +++ llvm/lib/Target/AArch64/AArch64InstrInfo.td | 3 + .../GISel/AArch64InstructionSelector.cpp | 20 ++--- .../lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp | 23 +++--- llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h | 8 +- llvm/lib/Target/Mips/MipsLegalizerInfo.cpp | 8 -- .../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 +++++++++++++++++++ .../test/MachineVerifier/test_g_ubsantrap.mir | 18 +++++ 27 files changed, 276 insertions(+), 131 deletions(-) rename llvm/test/CodeGen/Mips/GlobalISel/{legalizer => instruction-select}/trap.mir (55%) create mode 100644 llvm/test/CodeGen/X86/isel-traps.ll create mode 100644 llvm/test/MachineVerifier/test_g_ubsantrap.mir diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst index ac6217d08e6a..cae2c21b80d7 100644 --- a/llvm/docs/GlobalISel/GenericOpcode.rst +++ b/llvm/docs/GlobalISel/GenericOpcode.rst @@ -939,6 +939,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 `, :ref:`llvm.debugtrap ` +and :ref:`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 8bc1cab01bf0..391fd2d960dd 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -26926,6 +26926,8 @@ Arguments: The argument should be an MDTuple containing any number of MDStrings. +.. _llvm.trap: + '``llvm.trap``' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26953,6 +26955,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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26980,6 +26984,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 6ae7c1440907..5f28908e998a 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -243,6 +243,10 @@ private: 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); + // Translate @llvm.experimental.vector.interleave2 and // @llvm.experimental.vector.deinterleave2 intrinsics for fixed-width vector // types into vector shuffles. diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index aaa81342845b..3ba036ae713f 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -2113,6 +2113,11 @@ public: 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 899eaad5842a..5765926d6d93 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -837,6 +837,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 67d405ba96fa..d0f471eb29b6 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -1575,6 +1575,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 i8imm:$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 b1f3c500a1b6..4bb9929e2cf8 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -250,6 +250,9 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; // 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 757af3b1c4fe..ef95ceec18a1 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1771,6 +1771,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(CI.getOperand(0))->getZExtValue(); + MIRBuilder.buildInstr(Opcode, {}, ArrayRef{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); +} + bool IRTranslator::translateVectorInterleave2Intrinsic( const CallInst &CI, MachineIRBuilder &MIRBuilder) { assert(CI.getIntrinsicID() == Intrinsic::experimental_vector_interleave2 && @@ -2459,22 +2485,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: { @@ -3047,7 +3062,7 @@ bool IRTranslator::translateUnreachable(const User &U, MachineIRBuilder &MIRBuil } } - MIRBuilder.buildIntrinsic(Intrinsic::trap, ArrayRef()); + MIRBuilder.buildTrap(); return true; } diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index 005efe48ac0c..9a1498d4070e 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1867,6 +1867,17 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) { break; } + case TargetOpcode::G_UBSANTRAP: { + const MachineOperand &KindOp = MI->getOperand(0); + if (!MI->getOperand(0).isImm()) { + report("Crash kind must be an immediate", &KindOp, 0); + break; + } + int64_t Kind = MI->getOperand(0).getImm(); + if (!isInt<8>(Kind)) + report("Crash kind must be 8 bit wide", &KindOp, 0); + break; + } case TargetOpcode::G_VECREDUCE_SEQ_FADD: case TargetOpcode::G_VECREDUCE_SEQ_FMUL: { LLT DstTy = MRI->getType(MI->getOperand(0).getReg()); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index b4b975cce007..b1f514f75207 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -8436,6 +8436,9 @@ def ubsan_trap_xform : SDNodeXFormgetTargetConstant(N->getZExtValue() | ('U' << 8), SDLoc(N), MVT::i32); }]>; +def gi_ubsan_trap_xform : GICustomOperandRenderer<"renderUbsanTrap">, + GISDNodeXFormEquiv; + def ubsan_trap_imm : TImmLeaf(Imm); }], ubsan_trap_xform>; diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp index 677dd0b502b9..a8f2c45279e6 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -479,6 +479,8 @@ private: 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, @@ -6159,16 +6161,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; @@ -7663,6 +7655,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 90872516dd6d..e55d1de01b4f 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 legalizeTrap(MI, MRI, B); + case TargetOpcode::G_DEBUGTRAP: + return legalizeDebugTrap(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()); + B.buildTrap(); B.buildUndef(DstReg); MI.eraseFromParent(); return true; @@ -6618,9 +6624,9 @@ bool AMDGPULegalizerInfo::legalizeSBufferLoad(LegalizerHelper &Helper, } // TODO: Move to selection -bool AMDGPULegalizerInfo::legalizeTrapIntrinsic(MachineInstr &MI, - MachineRegisterInfo &MRI, - MachineIRBuilder &B) const { +bool AMDGPULegalizerInfo::legalizeTrap(MachineInstr &MI, + MachineRegisterInfo &MRI, + MachineIRBuilder &B) const { if (!ST.isTrapHandlerEnabled() || ST.getTrapHandlerAbi() != GCNSubtarget::TrapHandlerAbi::AMDHSA) return legalizeTrapEndpgm(MI, MRI, B); @@ -6726,8 +6732,9 @@ bool AMDGPULegalizerInfo::legalizeTrapHsa( return true; } -bool AMDGPULegalizerInfo::legalizeDebugTrapIntrinsic( - MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const { +bool AMDGPULegalizerInfo::legalizeDebugTrap(MachineInstr &MI, + MachineRegisterInfo &MRI, + MachineIRBuilder &B) const { // Is non-HSA path or trap-handler disabled? Then, report a warning // accordingly if (!ST.isTrapHandlerEnabled() || @@ -7270,10 +7277,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/AMDGPU/AMDGPULegalizerInfo.h b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h index 9661646fffc9..e5ba84a74a0f 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h +++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h @@ -226,16 +226,16 @@ public: bool legalizeSBufferLoad(LegalizerHelper &Helper, MachineInstr &MI) const; - bool legalizeTrapIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &B) const; + bool legalizeTrap(MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilder &B) const; bool legalizeTrapEndpgm(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const; bool legalizeTrapHsaQueuePtr(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const; bool legalizeTrapHsa(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const; - bool legalizeDebugTrapIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, - MachineIRBuilder &B) const; + bool legalizeDebugTrap(MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilder &B) const; bool legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const override; diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp index 3307e840a2af..8468dd6a2211 100644 --- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp +++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp @@ -508,16 +508,8 @@ bool MipsLegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const { MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; const MipsSubtarget &ST = MI.getMF()->getSubtarget(); - const MipsInstrInfo &TII = *ST.getInstrInfo(); - const MipsRegisterInfo &TRI = *ST.getRegisterInfo(); - const RegisterBankInfo &RBI = *ST.getRegBankInfo(); switch (cast(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 5738f86e7e9f..3103992a86c0 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -77,8 +77,6 @@ private: 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(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(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 8e0f61a85566..9be3812300af 100644 --- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp @@ -119,8 +119,6 @@ private: 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 fe9427d2678a..edae903fae84 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 5662de4cbdca..f7550ceb2799 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 c9e5f8924f8a..ac3c47c8001d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -752,6 +752,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, 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_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 ad66fa5623e3..25ecce4dd92b 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 f4366fb7888e..b242c68e3b07 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 b4bc64812b53..305eca792cfb 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 64388933fda8..dc99ce8d7a09 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 11789a030e6f..5f52030fc170 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 ea548c296dca..20b8b671ac5a 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 000000000000..c207387166a6 --- /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@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 +} diff --git a/llvm/test/MachineVerifier/test_g_ubsantrap.mir b/llvm/test/MachineVerifier/test_g_ubsantrap.mir new file mode 100644 index 000000000000..d2b219d8650a --- /dev/null +++ b/llvm/test/MachineVerifier/test_g_ubsantrap.mir @@ -0,0 +1,18 @@ +# RUN: not --crash llc -o - -mtriple=arm64 -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: aarch64-registered-target + +--- +name: test_ubsantrap +tracksRegLiveness: true +liveins: +body: | + bb.0: + + ; CHECK: Crash kind must be 8 bit wide + G_UBSANTRAP 4096 + + ; CHECK: Crash kind must be an immediate + %5:_(s32) = IMPLICIT_DEF + G_UBSANTRAP %5 + +...