A UD2 might make its way into the program via a call to @llvm.trap.
Obviously, calls are not terminators. However, we modeled the X86
instruction, UD2, as a terminator. Later on, this confuses the epilogue
insertion machinery which results in the epilogue getting inserted
before the UD2. For some platforms, like x64, the result is a
violation of the ABI.
Instead, model UD2/UD2B as a side effecting instruction which may
observe memory.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278144
91177308-0d34-0410-b5e6-
96231b3b80d8
// CPU flow control instructions
-let isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in {
+let mayLoad = 1, mayStore = 0, hasSideEffects = 1 in {
def TRAP : I<0x0B, RawFrm, (outs), (ins), "ud2", [(trap)]>, TB;
def UD2B : I<0xB9, RawFrm, (outs), (ins), "ud2b", []>, TB;
}
target triple = "x86_64-unknown-linux-gnu"
; CHECK-LABEL: bar:
+; CHECK: pushq
; CHECK: ud2
+; CHECK-NEXT: popq
; CHECK-NEXT: retq
define void @bar() {
entry:
+ call void @callee()
call void @llvm.trap()
ret void
}
; Function Attrs: noreturn nounwind
declare void @llvm.trap()
+
+declare void @callee()