[llvm] 78c27a3 - [X86][Win64] Avoid statepoints in trailing call position

Markus Böck via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 15 03:17:27 PST 2022


Author: Markus Böck
Date: 2022-02-15T12:17:19+01:00
New Revision: 78c27a3cee424d1989ec7ce188b7142511482f77

URL: https://github.com/llvm/llvm-project/commit/78c27a3cee424d1989ec7ce188b7142511482f77
DIFF: https://github.com/llvm/llvm-project/commit/78c27a3cee424d1989ec7ce188b7142511482f77.diff

LOG: [X86][Win64] Avoid statepoints in trailing call position

The "avoid trailing call pass" makes sure that no function ends with a call instruction for the purpose of the unwinder.
It starts of by skipping over any non real instruction, which is approximated via the Pseudo and Meta property. This sadly leads to issues when the last machine instruction is a STATEPOINT, as it is skipped despite it lowering to a call.

This patch fixes the use of a statepoint in the trailing call position by making sure call instructions are not skipped.

Differential Revision: https://reviews.llvm.org/D119644

Added: 
    llvm/test/CodeGen/X86/win64-eh-trailing-statepoint.ll

Modified: 
    llvm/lib/Target/X86/X86AvoidTrailingCall.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86AvoidTrailingCall.cpp b/llvm/lib/Target/X86/X86AvoidTrailingCall.cpp
index 0899783d5f607..e2254680540a0 100644
--- a/llvm/lib/Target/X86/X86AvoidTrailingCall.cpp
+++ b/llvm/lib/Target/X86/X86AvoidTrailingCall.cpp
@@ -69,8 +69,8 @@ INITIALIZE_PASS(X86AvoidTrailingCallPass, AVOIDCALL_NAME, AVOIDCALL_DESC, false,
 // A real instruction is a non-meta, non-pseudo instruction.  Some pseudos
 // expand to nothing, and some expand to code. This logic conservatively assumes
 // they might expand to nothing.
-static bool isRealInstruction(MachineInstr &MI) {
-  return !MI.isPseudo() && !MI.isMetaInstruction();
+static bool isCallOrRealInstruction(MachineInstr &MI) {
+  return MI.isCall() || (!MI.isPseudo() && !MI.isMetaInstruction());
 }
 
 // Return true if this is a call instruction, but not a tail call.
@@ -100,7 +100,7 @@ bool X86AvoidTrailingCallPass::runOnMachineFunction(MachineFunction &MF) {
       continue;
 
     // Find the last real instruction in this block.
-    auto LastRealInstr = llvm::find_if(reverse(MBB), isRealInstruction);
+    auto LastRealInstr = llvm::find_if(reverse(MBB), isCallOrRealInstruction);
 
     // If the block is empty or the last real instruction is a call instruction,
     // insert an int3. If there is a call instruction, insert the int3 between

diff  --git a/llvm/test/CodeGen/X86/win64-eh-trailing-statepoint.ll b/llvm/test/CodeGen/X86/win64-eh-trailing-statepoint.ll
new file mode 100644
index 0000000000000..c6bd289f981ed
--- /dev/null
+++ b/llvm/test/CodeGen/X86/win64-eh-trailing-statepoint.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-windows-gnu %s -o - | FileCheck %s
+
+define void @foo() gc "statepoint-example" personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*) {
+; CHECK-LABEL: foo:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    subq $40, %rsp
+; CHECK-NEXT:    .seh_stackalloc 40
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    callq raise
+; CHECK-NEXT:  .Ltmp0:
+; CHECK-NEXT:    int3
+; CHECK-NEXT:    .seh_endproc
+    %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @raise, i32 0, i32 0, i32 0, i32 0)
+    unreachable
+}
+
+declare void @raise()
+
+declare dso_local i32 @__gxx_personality_seh0(...)
+
+declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 immarg, i32 immarg, void ()*, i32 immarg, i32 immarg, ...)


        


More information about the llvm-commits mailing list