summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2012-05-11 00:19:32 +0000
committerDan Gohman <gohman@apple.com>2012-05-11 00:19:32 +0000
commitd4347e1af9141ec9f8e3e527367bfd16c0cc4ffb (patch)
tree15339f77ace4f0f4501e61e22ce6d01f82bce24a
parent61aef8bdf7a60bb1ab510fee0c5b2792468aadd3 (diff)
downloadexternal_llvm-d4347e1af9141ec9f8e3e527367bfd16c0cc4ffb.zip
external_llvm-d4347e1af9141ec9f8e3e527367bfd16c0cc4ffb.tar.gz
external_llvm-d4347e1af9141ec9f8e3e527367bfd16c0cc4ffb.tar.bz2
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
-rw-r--r--docs/LangRef.html26
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h3
-rw-r--r--include/llvm/Intrinsics.td2
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp1
-rw-r--r--lib/Target/X86/X86InstrSystem.td3
-rw-r--r--test/CodeGen/X86/trap.ll16
8 files changed, 55 insertions, 2 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html
index b222b06..f92fbf4 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -307,6 +307,8 @@
'<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">
@@ -8400,6 +8402,30 @@ LLVM</a>.</p>
<!-- _______________________________________________________________________ -->
<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>
</h4>
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index ab8ab5d..e570e12 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 f5883b6..6b09cbd 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 f55cf0e..361b42a 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 f1e879b..c73ba7b 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 f981afb..7b633ef 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 f1ca114..dd1b499 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 03ae6bf..2020516 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