Define a new intrinsic, @llvm.debugger. It will be similar to __builtin_trap(),
authorDan Gohman <gohman@apple.com>
Fri, 11 May 2012 00:19:32 +0000 (00:19 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 11 May 2012 00:19:32 +0000 (00:19 +0000)
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

docs/LangRef.html
include/llvm/CodeGen/ISDOpcodes.h
include/llvm/Intrinsics.td
include/llvm/Target/TargetSelectionDAG.td
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
lib/Target/X86/X86InstrSystem.td
test/CodeGen/X86/trap.ll

index b222b063194a0255c30cc8db918233f1378df4f0..f92fbf4abd7db3a2301528da805e015aa6a7fa0b 100644 (file)
             '<tt>llvm.annotation.*</tt>' Intrinsic</a></li>
           <li><a href="#int_trap">
             '<tt>llvm.trap</tt>' Intrinsic</a></li>
+          <li><a href="#int_debugger">
+            '<tt>llvm.debugger</tt>' Intrinsic</a></li>
           <li><a href="#int_stackprotector">
             '<tt>llvm.stackprotector</tt>' Intrinsic</a></li>
          <li><a href="#int_objectsize">
@@ -8398,6 +8400,30 @@ LLVM</a>.</p>
 
 </div>
 
+<!-- _______________________________________________________________________ -->
+<h4>
+  <a name="int_debugger">'<tt>llvm.debugger</tt>' Intrinsic</a>
+</h4>
+
+<div>
+
+<h5>Syntax:</h5>
+<pre>
+  declare void @llvm.debugger()
+</pre>
+
+<h5>Overview:</h5>
+<p>The '<tt>llvm.debugger</tt>' intrinsic.</p>
+
+<h5>Arguments:</h5>
+<p>None.</p>
+
+<h5>Semantics:</h5>
+<p>This intrinsic is lowered to code which is intended to cause an execution
+   trap with the intention of requesting the attention of a debugger.</p>
+
+</div>
+
 <!-- _______________________________________________________________________ -->
 <h4>
   <a name="int_stackprotector">'<tt>llvm.stackprotector</tt>' Intrinsic</a>
index ab8ab5dd7b4ee3537fb0e151d14009c7943deddd..e570e12503af099df2009a32f302a7c05bd950dc 100644 (file)
@@ -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
index f5883b6bdf781d84ef064e278344865bf00ceac8..6b09cbd7854b3eafea6b1f5bcb08de4e31965aeb 100644 (file)
@@ -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 {
index f55cf0e6306ce7d7844656e563cbcb0fd5543f83..361b42a12b5f35fd4cd618ea0ad32bfcaa67ad17 100644 (file)
@@ -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,
index f1e879be9567ee44aca9ad119f1a8ddfdcec1751..c73ba7bc221651b8536fa2e506fec2722f7166e4 100644 (file)
@@ -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:
index f981afb437b0fa9b990f4a0f2fd1b5c1f0bec820..7b633eff541c4ede1ea0f3b165c5a86af88354ae 100644 (file)
@@ -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";
index f1ca114c4c933a2290b4a3a0e1027cd6ef5766db..dd1b499ddd7e906bb53df19eb0112900ba5d5849 100644 (file)
@@ -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)>;
index 03ae6bfc869ec7b256a8bf0f769e886b2be6d5c6..2020516a8830f0639d0270f1b168ee5388e5b646 100644 (file)
@@ -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