[llvm] [RISCV] Use LD_RV32/SD_RV32 for spills and reloads when Zilsd is enabled (PR #153595)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 14 13:05:40 PDT 2025


================
@@ -1,44 +1,81 @@
 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-; RUN: llc < %s -mtriple=riscv32 -mattr=+zdinx -verify-machineinstrs -stop-after=prologepilog | FileCheck %s
+; RUN: llc < %s -mtriple=riscv32 -mattr=+zdinx -verify-machineinstrs -stop-after=prologepilog | FileCheck %s -check-prefix=ZDINX
+; RUN: llc < %s -mtriple=riscv32 -mattr=+zdinx,+zilsd -verify-machineinstrs -stop-after=prologepilog | FileCheck %s -check-prefix=ZDINX-ZILSD
 
 declare void @bar()
 
 define double @foo(double %x) nounwind {
-  ; CHECK-LABEL: name: foo
-  ; CHECK: bb.0 (%ir-block.0):
-  ; CHECK-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
-  ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT:   $x2 = frame-setup ADDI $x2, -64
-  ; CHECK-NEXT:   frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1)
-  ; CHECK-NEXT:   frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2)
-  ; CHECK-NEXT:   frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3)
-  ; CHECK-NEXT:   frame-setup SW killed $x19, $x2, 48 :: (store (s32) into %stack.4)
-  ; CHECK-NEXT:   frame-setup SW killed $x20, $x2, 44 :: (store (s32) into %stack.5)
-  ; CHECK-NEXT:   frame-setup SW killed $x21, $x2, 40 :: (store (s32) into %stack.6)
-  ; CHECK-NEXT:   frame-setup SW killed $x22, $x2, 36 :: (store (s32) into %stack.7)
-  ; CHECK-NEXT:   frame-setup SW killed $x23, $x2, 32 :: (store (s32) into %stack.8)
-  ; CHECK-NEXT:   frame-setup SW killed $x24, $x2, 28 :: (store (s32) into %stack.9)
-  ; CHECK-NEXT:   frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10)
-  ; CHECK-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
-  ; CHECK-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
-  ; CHECK-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
-  ; CHECK-NEXT:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
-  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $x6, 12 /* clobber */, implicit-def dead early-clobber $x7, 12 /* clobber */, implicit-def dead early-clobber $x8, 12 /* clobber */, implicit-def dead early-clobber $x9, 12 /* clobber */, implicit-def dead early-clobber $x10, 12 /* clobber */, implicit-def dead early-clobber $x11, 12 /* clobber */, implicit-def dead early-clobber $x12, 12 /* clobber */, implicit-def dead early-clobber $x13, 12 /* clobber */, implicit-def dead early-clobber $x14, 12 /* clobber */, implicit-def dead early-clobber $x15, 12 /* clobber */, implicit-def dead early-clobber $x16, 12 /* clobber */, implicit-def dead early-clobber $x17, 12 /* clobber */, implicit-def dead early-clobber $x18, 12 /* clobber */, implicit-def dead early-clobber $x19, 12 /* clobber */, implicit-def dead early-clobber $x20, 12 /* clobber */, implicit-def dead early-clobber $x21, 12 /* clobber */, implicit-def dead early-clobber $x22, 12 /* clobber */, implicit-def dead early-clobber $x23, 12 /* clobber */, implicit-def dead early-clobber $x24, 12 /* clobber */, implicit-def dead early-clobber $x25, 12 /* clobber */, implicit-def dead early-clobber $x26, 12 /* clobber */, implicit-def dead early-clobber $x27, 12 /* clobber */, implicit-def dead early-clobber $x28, 12 /* clobber */, implicit-def dead early-clobber $x29, 12 /* clobber */, implicit-def dead early-clobber $x31
-  ; CHECK-NEXT:   renamable $x10_x11 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.0, align 4)
-  ; CHECK-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
-  ; CHECK-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
-  ; CHECK-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
-  ; CHECK-NEXT:   $x19 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
-  ; CHECK-NEXT:   $x20 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
-  ; CHECK-NEXT:   $x21 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
-  ; CHECK-NEXT:   $x22 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
-  ; CHECK-NEXT:   $x23 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
-  ; CHECK-NEXT:   $x24 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
-  ; CHECK-NEXT:   $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
-  ; CHECK-NEXT:   $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
-  ; CHECK-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
-  ; CHECK-NEXT:   $x2 = frame-destroy ADDI $x2, 64
-  ; CHECK-NEXT:   PseudoRET implicit $x10, implicit $x11
+  ; ZDINX-LABEL: name: foo
+  ; ZDINX: bb.0 (%ir-block.0):
+  ; ZDINX-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; ZDINX-NEXT: {{  $}}
+  ; ZDINX-NEXT:   $x2 = frame-setup ADDI $x2, -64
+  ; ZDINX-NEXT:   frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1)
+  ; ZDINX-NEXT:   frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2)
+  ; ZDINX-NEXT:   frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3)
+  ; ZDINX-NEXT:   frame-setup SW killed $x19, $x2, 48 :: (store (s32) into %stack.4)
+  ; ZDINX-NEXT:   frame-setup SW killed $x20, $x2, 44 :: (store (s32) into %stack.5)
+  ; ZDINX-NEXT:   frame-setup SW killed $x21, $x2, 40 :: (store (s32) into %stack.6)
+  ; ZDINX-NEXT:   frame-setup SW killed $x22, $x2, 36 :: (store (s32) into %stack.7)
+  ; ZDINX-NEXT:   frame-setup SW killed $x23, $x2, 32 :: (store (s32) into %stack.8)
+  ; ZDINX-NEXT:   frame-setup SW killed $x24, $x2, 28 :: (store (s32) into %stack.9)
+  ; ZDINX-NEXT:   frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10)
+  ; ZDINX-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
+  ; ZDINX-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
+  ; ZDINX-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
+  ; ZDINX-NEXT:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
+  ; ZDINX-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $x6, 12 /* clobber */, implicit-def dead early-clobber $x7, 12 /* clobber */, implicit-def dead early-clobber $x8, 12 /* clobber */, implicit-def dead early-clobber $x9, 12 /* clobber */, implicit-def dead early-clobber $x10, 12 /* clobber */, implicit-def dead early-clobber $x11, 12 /* clobber */, implicit-def dead early-clobber $x12, 12 /* clobber */, implicit-def dead early-clobber $x13, 12 /* clobber */, implicit-def dead early-clobber $x14, 12 /* clobber */, implicit-def dead early-clobber $x15, 12 /* clobber */, implicit-def dead early-clobber $x16, 12 /* clobber */, implicit-def dead early-clobber $x17, 12 /* clobber */, implicit-def dead early-clobber $x18, 12 /* clobber */, implicit-def dead early-clobber $x19, 12 /* clobber */, implicit-def dead early-clobber $x20, 12 /* clobber */, implicit-def dead early-clobber $x21, 12 /* clobber */, implicit-def dead early-clobber $x22, 12 /* clobber */, implicit-def dead early-clobber $x23, 12 /* clobber */, implicit-def dead early-clobber $x24, 12 /* clobber */, implicit-def dead early-clobber $x25, 12 /* clobber */, implicit-def dead early-clobber $x26, 12 /* clobber */, implicit-def dead early-clobber $x27, 12 /* clobber */, implicit-def dead early-clobber $x28, 12 /* clobber */, implicit-def dead early-clobber $x29, 12 /* clobber */, implicit-def dead early-clobber $x31
+  ; ZDINX-NEXT:   renamable $x10_x11 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.0, align 4)
+  ; ZDINX-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
+  ; ZDINX-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
+  ; ZDINX-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
+  ; ZDINX-NEXT:   $x19 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
+  ; ZDINX-NEXT:   $x20 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
+  ; ZDINX-NEXT:   $x21 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
+  ; ZDINX-NEXT:   $x22 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
+  ; ZDINX-NEXT:   $x23 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
+  ; ZDINX-NEXT:   $x24 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
+  ; ZDINX-NEXT:   $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
+  ; ZDINX-NEXT:   $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
+  ; ZDINX-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
+  ; ZDINX-NEXT:   $x2 = frame-destroy ADDI $x2, 64
+  ; ZDINX-NEXT:   PseudoRET implicit $x10, implicit $x11
+  ;
+  ; ZDINX-ZILSD-LABEL: name: foo
+  ; ZDINX-ZILSD: bb.0 (%ir-block.0):
+  ; ZDINX-ZILSD-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; ZDINX-ZILSD-NEXT: {{  $}}
+  ; ZDINX-ZILSD-NEXT:   $x2 = frame-setup ADDI $x2, -64
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x19, $x2, 48 :: (store (s32) into %stack.4)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x20, $x2, 44 :: (store (s32) into %stack.5)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x21, $x2, 40 :: (store (s32) into %stack.6)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x22, $x2, 36 :: (store (s32) into %stack.7)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x23, $x2, 32 :: (store (s32) into %stack.8)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x24, $x2, 28 :: (store (s32) into %stack.9)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
+  ; ZDINX-ZILSD-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
+  ; ZDINX-ZILSD-NEXT:   SD_RV32 killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
----------------
topperc wrote:

I think I looked into this once.

One thing I do remember is that the alignment associated with the FrameIndex object might be wrong if the stack can't be realigned.

I'm now wondering if spills of D registers on RV32E can reliably use FSD/FLD since the stack is only 4 byte aligned.

https://github.com/llvm/llvm-project/pull/153595


More information about the llvm-commits mailing list