[llvm-commits] [PATCH] __builtin_debugtrap() intrinsic function (change to Clang and CodeGen)
Shuxin Yang
shuxin.llvm at gmail.com
Fri Oct 19 11:23:07 PDT 2012
Hi,
This patch is to fix radar://8426430. It is about llvm support of
__builtin_debugtrap()
which is supposed to consistently raise SIGTRAP across all systems. In
contrast,
__builtin_trap() behave differently on different systems. e.g. it raises
SIGTRAP on ARM, and
SIGILL on X86. The purpose of __builtin_debugtrap() is to consistently
provide "trap"
functionality, in the mean time preserve the compatibility with on gcc
on __builtin_trap().
The X86 backend is already able to handle debugtrap(). This patch is to:
1) make front-end recognize "__builtin_debugtrap()" (emboddied in the
one-line change to Clang).
2) In DAG legalization phase, by default, "debugtrap" will be
replaced with "trap", which
make the __builtin_debugtrap() "available" to all existing ports
without the hassle of
changing their code.
3) If trap-function is specified (via -trap-func=xyz to llc), both
__builtin_debugtrap() and
__builtin_trap() will be expanded into the function call of the
specified trap function.
This behavior may need change in the future.
The provided testing-case is to make sure 2) and 3) are working for
ARM port, and we
already have a testing case for x86.
This change pass regression test, SingleSource and MultipleSource test.
Thanks
Shuxin
-------------- next part --------------
Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def (revision 166287)
+++ include/clang/Basic/Builtins.def (working copy)
@@ -479,6 +479,7 @@
BUILTIN(__builtin_prefetch, "vvC*.", "nc")
BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
BUILTIN(__builtin_trap, "v", "nr")
+BUILTIN(__builtin_debugtrap, "v", "nr")
BUILTIN(__builtin_unreachable, "v", "nr")
BUILTIN(__builtin_shufflevector, "v." , "nc")
BUILTIN(__builtin_alloca, "v*z" , "n")
-------------- next part --------------
Index: test/CodeGen/ARM/trap.ll
===================================================================
--- test/CodeGen/ARM/trap.ll (revision 166287)
+++ test/CodeGen/ARM/trap.ll (working copy)
@@ -14,4 +14,16 @@
unreachable
}
+define void @t2() nounwind {
+entry:
+; INSTR: t2:
+; INSTR: trap
+
+; FUNC: t2:
+; FUNC: bl __trap
+ call void @llvm.debugtrap()
+ unreachable
+}
+
declare void @llvm.trap() nounwind
+declare void @llvm.debugtrap() nounwind
Index: include/llvm/Intrinsics.td
===================================================================
--- include/llvm/Intrinsics.td (revision 166287)
+++ include/llvm/Intrinsics.td (working copy)
@@ -420,7 +420,7 @@
GCCBuiltin<"__builtin_flt_rounds">;
def int_trap : Intrinsic<[], [], [IntrNoReturn]>,
GCCBuiltin<"__builtin_trap">;
-def int_debugtrap : Intrinsic<[]>,
+def int_debugtrap : Intrinsic<[], [], [IntrNoReturn]>,
GCCBuiltin<"__builtin_debugtrap">;
// NOP: calls/invokes to this intrinsic are removed by codegen
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp (revision 166287)
+++ lib/Target/X86/X86ISelLowering.cpp (working copy)
@@ -557,6 +557,7 @@
setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom);
setOperationAction(ISD::TRAP, MVT::Other, Legal);
+ setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal);
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
setOperationAction(ISD::VASTART , MVT::Other, Custom);
Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (revision 166287)
+++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (working copy)
@@ -1240,6 +1240,19 @@
if (Action == TargetLowering::Legal)
Action = TargetLowering::Custom;
break;
+ case ISD::DEBUGTRAP:
+ Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
+ if (Action == TargetLowering::Expand) {
+ // replace ISD::DEBUGTRAP with ISD::TRAP
+ SDValue NewVal;
+ NewVal = DAG.getNode (ISD::TRAP, Node->getDebugLoc(), Node->getVTList(),
+ Node->getOperand(0));
+ ReplaceNode(Node, NewVal.getNode());
+ LegalizeOp(NewVal.getNode());
+ return;
+ }
+ break;
+
default:
if (Node->getOpcode() >= ISD::BUILTIN_OP_END) {
Action = TargetLowering::Legal;
Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/TargetLowering.cpp (revision 166287)
+++ lib/CodeGen/SelectionDAG/TargetLowering.cpp (working copy)
@@ -583,6 +583,11 @@
// Default ISD::TRAP to expand (which turns it into abort).
setOperationAction(ISD::TRAP, MVT::Other, Expand);
+ // On most systems, DEBUGTRAP and TRAP have no difference. The "Expand"
+ // here is to inform DAG Legalizer to replace DEBUGTRAP with TRAP.
+ //
+ setOperationAction(ISD::DEBUGTRAP, MVT::Other, Expand);
+
IsLittleEndian = TD->isLittleEndian();
PointerTy = MVT::getIntegerVT(8*TD->getPointerSize(0));
memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*));
Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (revision 166287)
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (working copy)
@@ -5175,10 +5175,13 @@
return 0;
}
+ case Intrinsic::debugtrap:
case Intrinsic::trap: {
StringRef TrapFuncName = TM.Options.getTrapFunctionName();
if (TrapFuncName.empty()) {
- DAG.setRoot(DAG.getNode(ISD::TRAP, dl,MVT::Other, getRoot()));
+ ISD::NodeType Op = (Intrinsic == Intrinsic::trap) ?
+ ISD::TRAP : ISD::DEBUGTRAP;
+ DAG.setRoot(DAG.getNode(Op, dl,MVT::Other, getRoot()));
return 0;
}
TargetLowering::ArgListTy Args;
@@ -5193,10 +5196,7 @@
DAG.setRoot(Result.second);
return 0;
}
- case Intrinsic::debugtrap: {
- DAG.setRoot(DAG.getNode(ISD::DEBUGTRAP, dl,MVT::Other, getRoot()));
- return 0;
- }
+
case Intrinsic::uadd_with_overflow:
case Intrinsic::sadd_with_overflow:
case Intrinsic::usub_with_overflow:
More information about the llvm-commits
mailing list