[PATCH] D104440: [X86] Fix bug when X86 stackify pass handle one ArgFPRW.

LuoYuanke via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 17 00:39:14 PDT 2021


LuoYuanke created this revision.
Herald added subscribers: pengfei, hiraditya.
LuoYuanke requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Here is the scenario that cause compiler crash.

  successors: %bb.26
  liveins: $r14
  ST_FPrr $st0, implicit-def $fpsw, implicit $fpcw
  renamable $rdi = MOV64ri @.str.3.16422
  renamable $rdx = LEA64r %stack.6, 1, $noreg, 0, $noreg
  ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def dead $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp
  dead $esi = MOV32r0 implicit-def dead $eflags, implicit-def $rsi
  CALL64pcrel32 @foo, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit-def dead $fp0
  renamable $xmm0 = MOVSDrm_alt %stack.10, 1, $noreg, 0, $noreg :: (load 8 from %stack.10)
  ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def dead $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp
  renamable $fp2 = CHS_Fp80 killed undef renamable $fp0, implicit-def $fpsw
  JMP_1 %bb.26

The CALL64pcrel32 mark fp0 dead, so llvm free the stack slot for fp0
and the stack become empty. In the late instruction CHS_Fp80, it use
undefined register fp0, the original code assume there must be a stack
slot for the src register (fp0) without respecting it is undefined,
so llvm report error. The fix is to check if the source register is
undefined when stack is empty(). If it is undefined, advance 1 stack
slot to avoid empty stack.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D104440

Files:
  llvm/lib/Target/X86/X86FloatingPoint.cpp
  llvm/test/CodeGen/X86/fpstack-call.mir


Index: llvm/test/CodeGen/X86/fpstack-call.mir
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/fpstack-call.mir
@@ -0,0 +1,52 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=x86_64-- -run-pass x86-codegen -verify-machineinstrs -mcpu=x86-64 -o - %s | FileCheck %s
+
+--- |
+   @x = dso_local global i32 0, align 4
+   define void @fpstack-empty() { ret void }
+   declare void @foo()
+...
+---
+
+name: fpstack-empty
+tracksRegLiveness: true
+registers:       []
+liveins:
+  - { reg: '$r14', virtual-reg: '' }
+stack:
+  - { id: 0, name: '', type: default, offset: 0, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: default, offset: 0, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+  bb.0 (%ir-block.0):
+    liveins: $r14
+    ; CHECK-LABEL: name: fpstack-empty
+    ; CHECK: liveins: $r14
+    ; CHECK: ST_FPrr $st0, implicit-def $fpsw, implicit $fpcw
+    ; CHECK: renamable $rdi = MOV64ri @x
+    ; CHECK: renamable $rdx = LEA64r %stack.0, 1, $noreg, 0, $noreg
+    ; CHECK: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def dead $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp
+    ; CHECK: dead $esi = MOV32r0 implicit-def dead $eflags, implicit-def $rsi
+    ; CHECK: CALL64pcrel32 @foo, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx
+    ; CHECK: ST_FPrr $st0, implicit-def $fpsw, implicit $fpcw
+    ; CHECK: renamable $xmm0 = MOVSDrm_alt %stack.1, 1, $noreg, 0, $noreg :: (load 8 from %stack.1)
+    ; CHECK: ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def dead $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp
+    ; CHECK: CHS_F implicit-def $fpsw
+    ; CHECK: ST_FPrr $st0, implicit-def $fpsw, implicit $fpcw
+    ; CHECK: RETQ
+    ST_FPrr $st0, implicit-def $fpsw, implicit $fpcw
+    renamable $rdi = MOV64ri @x
+    renamable $rdx = LEA64r %stack.0, 1, $noreg, 0, $noreg
+    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def dead $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp
+    dead $esi = MOV32r0 implicit-def dead $eflags, implicit-def $rsi
+    CALL64pcrel32 @foo, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit-def dead $fp0
+    renamable $xmm0 = MOVSDrm_alt %stack.1, 1, $noreg, 0, $noreg :: (load 8 from %stack.1)
+    ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def dead $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp
+    renamable $fp2 = CHS_Fp80 killed undef renamable $fp0, implicit-def $fpsw
+
+    RETQ
+...
+---
Index: llvm/lib/Target/X86/X86FloatingPoint.cpp
===================================================================
--- llvm/lib/Target/X86/X86FloatingPoint.cpp
+++ llvm/lib/Target/X86/X86FloatingPoint.cpp
@@ -1191,8 +1191,12 @@
     // If this is the last use of the source register, just make sure it's on
     // the top of the stack.
     moveToTop(Reg, I);
-    if (StackTop == 0)
-      report_fatal_error("Stack cannot be empty!");
+    if (StackTop == 0) {
+      if (MI.getOperand(1).isUndef())
+        ++StackTop;
+      else
+        report_fatal_error("Stack cannot be empty!");
+    }
     --StackTop;
     pushReg(getFPReg(MI.getOperand(0)));
   } else {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104440.352632.patch
Type: text/x-patch
Size: 3596 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210617/5021e5b8/attachment.bin>


More information about the llvm-commits mailing list