From: Dan Gohman Date: Fri, 11 May 2012 00:19:32 +0000 (+0000) Subject: Define a new intrinsic, @llvm.debugger. It will be similar to __builtin_trap(), X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=d4347e1af9141ec9f8e3e527367bfd16c0cc4ffb;p=oota-llvm.git Define a new intrinsic, @llvm.debugger. It will be similar to __builtin_trap(), but it generates int3 on x86 instead of ud2. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156593 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LangRef.html b/docs/LangRef.html index b222b063194..f92fbf4abd7 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -307,6 +307,8 @@ 'llvm.annotation.*' Intrinsic
  • 'llvm.trap' Intrinsic
  • +
  • + 'llvm.debugger' Intrinsic
  • 'llvm.stackprotector' Intrinsic
  • @@ -8398,6 +8400,30 @@ LLVM.

    + +

    + 'llvm.debugger' Intrinsic +

    + +
    + +
    Syntax:
    +
    +  declare void @llvm.debugger()
    +
    + +
    Overview:
    +

    The 'llvm.debugger' intrinsic.

    + +
    Arguments:
    +

    None.

    + +
    Semantics:
    +

    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.stackprotector' Intrinsic diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index ab8ab5dd7b4..e570e12503a 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -582,6 +582,9 @@ namespace ISD { // TRAP - Trapping instruction TRAP, + // DEBUGGER - Trap intented to get the attention of a debugger. + DEBUGGER, + // PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are // their first operand. The other operands are the address to prefetch, // read / write specifier, locality specifier and instruction / data cache diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index f5883b6bdf7..6b09cbd7854 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -399,6 +399,8 @@ def int_flt_rounds : Intrinsic<[llvm_i32_ty]>, GCCBuiltin<"__builtin_flt_rounds">; def int_trap : Intrinsic<[]>, GCCBuiltin<"__builtin_trap">; +def int_debugger : Intrinsic<[]>, + GCCBuiltin<"__builtin_debugger">; // Intrisics to support half precision floating point format let Properties = [IntrNoMem] in { diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index f55cf0e6306..361b42a12b5 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -404,6 +404,8 @@ def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; def trap : SDNode<"ISD::TRAP" , SDTNone, [SDNPHasChain, SDNPSideEffect]>; +def debugger : SDNode<"ISD::DEBUGGER" , SDTNone, + [SDNPHasChain, SDNPSideEffect]>; def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, [SDNPHasChain, SDNPMayLoad, SDNPMayStore, diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index f1e879be956..c73ba7bc221 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5087,6 +5087,10 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { DAG.setRoot(Result.second); return 0; } + case Intrinsic::debugger: { + DAG.setRoot(DAG.getNode(ISD::DEBUGGER, dl,MVT::Other, getRoot())); + return 0; + } case Intrinsic::uadd_with_overflow: case Intrinsic::sadd_with_overflow: case Intrinsic::usub_with_overflow: diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp index f981afb437b..7b633eff541 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -265,6 +265,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::STACKSAVE: return "stacksave"; case ISD::STACKRESTORE: return "stackrestore"; case ISD::TRAP: return "trap"; + case ISD::DEBUGGER: return "debugger"; // Bit manipulation case ISD::BSWAP: return "bswap"; diff --git a/lib/Target/X86/X86InstrSystem.td b/lib/Target/X86/X86InstrSystem.td index f1ca114c4c9..dd1b499ddd7 100644 --- a/lib/Target/X86/X86InstrSystem.td +++ b/lib/Target/X86/X86InstrSystem.td @@ -36,6 +36,9 @@ let Uses = [EFLAGS] in def INT3 : I<0xcc, RawFrm, (outs), (ins), "int3", [(int_x86_int (i8 3))], IIC_INT3>; +def : Pat<(debugger), + (INT3)>; + // The long form of "int $3" turns into int3 as a size optimization. // FIXME: This doesn't work because InstAlias can't match immediate constants. //def : InstAlias<"int\t$3", (INT3)>; diff --git a/test/CodeGen/X86/trap.ll b/test/CodeGen/X86/trap.ll index 03ae6bfc869..2020516a883 100644 --- a/test/CodeGen/X86/trap.ll +++ b/test/CodeGen/X86/trap.ll @@ -1,9 +1,21 @@ -; RUN: llc < %s -march=x86 -mcpu=yonah | grep ud2 -define i32 @test() noreturn nounwind { +; RUN: llc < %s -march=x86 -mcpu=yonah | FileCheck %s + +; CHECK: test0: +; CHECK: ud2 +define i32 @test0() noreturn nounwind { entry: tail call void @llvm.trap( ) unreachable } +; CHECK: test1: +; CHECK: int3 +define i32 @test1() noreturn nounwind { +entry: + tail call void @llvm.debugger( ) + unreachable +} + declare void @llvm.trap() nounwind +declare void @llvm.debugger() nounwind