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

Sudharsan Veeravalli via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 11 21:11:29 PST 2026


https://github.com/svs-quic updated https://github.com/llvm/llvm-project/pull/153595

>From 6b3f27ac97323b0e4cc843035620d53e17e99be1 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Thu, 14 Aug 2025 20:38:35 +0530
Subject: [PATCH 1/6] Pre-commit test

---
 llvm/test/CodeGen/RISCV/zdinx-spill.ll | 109 +++++++++++++++++--------
 1 file changed, 73 insertions(+), 36 deletions(-)

diff --git a/llvm/test/CodeGen/RISCV/zdinx-spill.ll b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
index 6f206fe571c17..1ee50820ad7ae 100644
--- a/llvm/test/CodeGen/RISCV/zdinx-spill.ll
+++ b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
@@ -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:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
+  ; ZDINX-ZILSD-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-ZILSD-NEXT:   renamable $x10_x11 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.0, align 4)
+  ; ZDINX-ZILSD-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
+  ; ZDINX-ZILSD-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
+  ; ZDINX-ZILSD-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
+  ; ZDINX-ZILSD-NEXT:   $x19 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
+  ; ZDINX-ZILSD-NEXT:   $x20 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
+  ; ZDINX-ZILSD-NEXT:   $x21 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
+  ; ZDINX-ZILSD-NEXT:   $x22 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
+  ; ZDINX-ZILSD-NEXT:   $x23 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
+  ; ZDINX-ZILSD-NEXT:   $x24 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
+  ; ZDINX-ZILSD-NEXT:   $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
+  ; ZDINX-ZILSD-NEXT:   $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
+  ; ZDINX-ZILSD-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
+  ; ZDINX-ZILSD-NEXT:   $x2 = frame-destroy ADDI $x2, 64
+  ; ZDINX-ZILSD-NEXT:   PseudoRET implicit $x10, implicit $x11
   %a = fadd double %x, %x
   call void asm sideeffect "", "~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15},~{x16},~{x17},~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{x29},~{xr0},~{x31}"()
   ret double %a

>From f4940326ae21d1a4132bdcc86978d17d527c53bb Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Thu, 14 Aug 2025 20:41:48 +0530
Subject: [PATCH 2/6] Use LD_RV32/SD_RV32 for storing and loading from stack
 slot

---
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 14 ++++++++++++--
 llvm/test/CodeGen/RISCV/zdinx-spill.ll   |  4 ++--
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 085064eee896a..cd75f6709e1e8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -658,7 +658,12 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
   } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::SW_INX;
   } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
-    Opcode = RISCV::PseudoRV32ZdinxSD;
+    if (STI.hasStdExtZilsd() && !STI.is64Bit()) {
+      Opcode = RISCV::SD_RV32;
+    } else {
+      assert(STI.hasStdExtZdinx() && !STI.is64Bit());
+      Opcode = RISCV::PseudoRV32ZdinxSD;
+    }
   } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::FSH;
   } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
@@ -742,7 +747,12 @@ void RISCVInstrInfo::loadRegFromStackSlot(
   } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::LW_INX;
   } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
-    Opcode = RISCV::PseudoRV32ZdinxLD;
+    if (STI.hasStdExtZilsd() && !STI.is64Bit()) {
+      Opcode = RISCV::LD_RV32;
+    } else {
+      assert(STI.hasStdExtZdinx() && !STI.is64Bit());
+      Opcode = RISCV::PseudoRV32ZdinxLD;
+    }
   } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::FLH;
   } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
diff --git a/llvm/test/CodeGen/RISCV/zdinx-spill.ll b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
index 1ee50820ad7ae..526392b0280cb 100644
--- a/llvm/test/CodeGen/RISCV/zdinx-spill.ll
+++ b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
@@ -59,9 +59,9 @@ define double @foo(double %x) nounwind {
   ; 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:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
+  ; ZDINX-ZILSD-NEXT:   SD_RV32 killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
   ; ZDINX-ZILSD-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-ZILSD-NEXT:   renamable $x10_x11 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.0, align 4)
+  ; ZDINX-ZILSD-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 8 :: (load (s64) from %stack.0, align 4)
   ; ZDINX-ZILSD-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
   ; ZDINX-ZILSD-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
   ; ZDINX-ZILSD-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)

>From 2c0a833df8b513e3f47b5ab2abcb9a6b24fb128b Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Thu, 8 Jan 2026 12:08:11 +0530
Subject: [PATCH 3/6] Add 4-byte align constraint

---
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp |  4 +--
 llvm/test/CodeGen/RISCV/zdinx-spill.ll   | 41 ++++++++++++++++++++++--
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index d9ac35811b40e..15b4a7445abc9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -662,7 +662,7 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
   } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::SW_INX;
   } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
-    if (STI.hasStdExtZilsd() && !STI.is64Bit()) {
+    if (!STI.is64Bit() && STI.hasStdExtZilsd() && STI.allowZilsd4ByteAlign()) {
       Opcode = RISCV::SD_RV32;
     } else {
       assert(STI.hasStdExtZdinx() && !STI.is64Bit());
@@ -753,7 +753,7 @@ void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
   } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::LW_INX;
   } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
-    if (STI.hasStdExtZilsd() && !STI.is64Bit()) {
+    if (!STI.is64Bit() && STI.hasStdExtZilsd() && STI.allowZilsd4ByteAlign()) {
       Opcode = RISCV::LD_RV32;
     } else {
       assert(STI.hasStdExtZdinx() && !STI.is64Bit());
diff --git a/llvm/test/CodeGen/RISCV/zdinx-spill.ll b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
index 526392b0280cb..47b3d1024a99c 100644
--- a/llvm/test/CodeGen/RISCV/zdinx-spill.ll
+++ b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
@@ -1,6 +1,7 @@
 ; 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 -check-prefix=ZDINX
 ; RUN: llc < %s -mtriple=riscv32 -mattr=+zdinx,+zilsd -verify-machineinstrs -stop-after=prologepilog | FileCheck %s -check-prefix=ZDINX-ZILSD
+; RUN: llc < %s -mtriple=riscv32 -mattr=+zdinx,+zilsd,+zilsd-4byte-align -verify-machineinstrs -stop-after=prologepilog | FileCheck %s -check-prefix=ZDINX-ZILSD-4BYTEALIGN
 
 declare void @bar()
 
@@ -59,9 +60,9 @@ define double @foo(double %x) nounwind {
   ; 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)
+  ; ZDINX-ZILSD-NEXT:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
   ; ZDINX-ZILSD-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-ZILSD-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 8 :: (load (s64) from %stack.0, align 4)
+  ; ZDINX-ZILSD-NEXT:   renamable $x10_x11 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.0, align 4)
   ; ZDINX-ZILSD-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
   ; ZDINX-ZILSD-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
   ; ZDINX-ZILSD-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
@@ -76,6 +77,42 @@ define double @foo(double %x) nounwind {
   ; ZDINX-ZILSD-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
   ; ZDINX-ZILSD-NEXT:   $x2 = frame-destroy ADDI $x2, 64
   ; ZDINX-ZILSD-NEXT:   PseudoRET implicit $x10, implicit $x11
+  ;
+  ; ZDINX-ZILSD-4BYTEALIGN-LABEL: name: foo
+  ; ZDINX-ZILSD-4BYTEALIGN: bb.0 (%ir-block.0):
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT: {{  $}}
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x2 = frame-setup ADDI $x2, -64
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x19, $x2, 48 :: (store (s32) into %stack.4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x20, $x2, 44 :: (store (s32) into %stack.5)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x21, $x2, 40 :: (store (s32) into %stack.6)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x22, $x2, 36 :: (store (s32) into %stack.7)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x23, $x2, 32 :: (store (s32) into %stack.8)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x24, $x2, 28 :: (store (s32) into %stack.9)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   SD_RV32 killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-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-ZILSD-4BYTEALIGN-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 8 :: (load (s64) from %stack.0, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x19 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x20 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x21 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x22 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x23 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x24 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x2 = frame-destroy ADDI $x2, 64
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   PseudoRET implicit $x10, implicit $x11
   %a = fadd double %x, %x
   call void asm sideeffect "", "~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15},~{x16},~{x17},~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{x29},~{xr0},~{x31}"()
   ret double %a

>From b43790e99a4bd0f0d34d535c6db0ccacac207b96 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Mon, 12 Jan 2026 10:00:31 +0530
Subject: [PATCH 4/6] Pre-commit unaligned test

---
 llvm/test/CodeGen/RISCV/zdinx-spill.ll | 37 ++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/zdinx-spill.ll b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
index 47b3d1024a99c..c96d9aabeee32 100644
--- a/llvm/test/CodeGen/RISCV/zdinx-spill.ll
+++ b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
@@ -1,6 +1,7 @@
 ; 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 -check-prefix=ZDINX
 ; RUN: llc < %s -mtriple=riscv32 -mattr=+zdinx,+zilsd -verify-machineinstrs -stop-after=prologepilog | FileCheck %s -check-prefix=ZDINX-ZILSD
+; RUN: llc < %s -mtriple=riscv32 -mattr=+zdinx,+zilsd,+unaligned-scalar-mem -verify-machineinstrs -stop-after=prologepilog | FileCheck %s -check-prefix=ZDINX-ZILSD-UNALIGNED
 ; RUN: llc < %s -mtriple=riscv32 -mattr=+zdinx,+zilsd,+zilsd-4byte-align -verify-machineinstrs -stop-after=prologepilog | FileCheck %s -check-prefix=ZDINX-ZILSD-4BYTEALIGN
 
 declare void @bar()
@@ -78,6 +79,42 @@ define double @foo(double %x) nounwind {
   ; ZDINX-ZILSD-NEXT:   $x2 = frame-destroy ADDI $x2, 64
   ; ZDINX-ZILSD-NEXT:   PseudoRET implicit $x10, implicit $x11
   ;
+  ; ZDINX-ZILSD-UNALIGNED-LABEL: name: foo
+  ; ZDINX-ZILSD-UNALIGNED: bb.0 (%ir-block.0):
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; ZDINX-ZILSD-UNALIGNED-NEXT: {{  $}}
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x2 = frame-setup ADDI $x2, -64
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x19, $x2, 48 :: (store (s32) into %stack.4)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x20, $x2, 44 :: (store (s32) into %stack.5)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x21, $x2, 40 :: (store (s32) into %stack.6)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x22, $x2, 36 :: (store (s32) into %stack.7)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x23, $x2, 32 :: (store (s32) into %stack.8)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x24, $x2, 28 :: (store (s32) into %stack.9)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
+  ; ZDINX-ZILSD-UNALIGNED-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-ZILSD-UNALIGNED-NEXT:   renamable $x10_x11 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.0, align 4)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x19 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x20 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x21 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x22 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x23 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x24 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x2 = frame-destroy ADDI $x2, 64
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   PseudoRET implicit $x10, implicit $x11
+  ;
   ; ZDINX-ZILSD-4BYTEALIGN-LABEL: name: foo
   ; ZDINX-ZILSD-4BYTEALIGN: bb.0 (%ir-block.0):
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27

>From f125906c97b82dc4be0dfabe4cf537f136a14c41 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Mon, 12 Jan 2026 10:07:28 +0530
Subject: [PATCH 5/6] Handle unaligned and align >= 8

---
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 18 ++++++++++--------
 llvm/test/CodeGen/RISCV/zdinx-spill.ll   |  4 ++--
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 15b4a7445abc9..4577c69ce4d1b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -652,6 +652,7 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                          MachineInstr::MIFlag Flags) const {
   MachineFunction *MF = MBB.getParent();
   MachineFrameInfo &MFI = MF->getFrameInfo();
+  Align Alignment = MFI.getObjectAlign(FI);
 
   unsigned Opcode;
   if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
@@ -662,10 +663,10 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
   } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::SW_INX;
   } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
-    if (!STI.is64Bit() && STI.hasStdExtZilsd() && STI.allowZilsd4ByteAlign()) {
+    if (!STI.is64Bit() && STI.hasStdExtZilsd() &&
+        Alignment >= STI.getZilsdAlign()) {
       Opcode = RISCV::SD_RV32;
     } else {
-      assert(STI.hasStdExtZdinx() && !STI.is64Bit());
       Opcode = RISCV::PseudoRV32ZdinxSD;
     }
   } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
@@ -710,7 +711,7 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
   if (RISCVRegisterInfo::isRVVRegClass(RC)) {
     MachineMemOperand *MMO = MF->getMachineMemOperand(
         MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
-        TypeSize::getScalable(MFI.getObjectSize(FI)), MFI.getObjectAlign(FI));
+        TypeSize::getScalable(MFI.getObjectSize(FI)), Alignment);
 
     MFI.setStackID(FI, TargetStackID::ScalableVector);
     BuildMI(MBB, I, DebugLoc(), get(Opcode))
@@ -722,7 +723,7 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
   } else {
     MachineMemOperand *MMO = MF->getMachineMemOperand(
         MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
-        MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
+        MFI.getObjectSize(FI), Alignment);
 
     BuildMI(MBB, I, DebugLoc(), get(Opcode))
         .addReg(SrcReg, getKillRegState(IsKill))
@@ -741,6 +742,7 @@ void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                           MachineInstr::MIFlag Flags) const {
   MachineFunction *MF = MBB.getParent();
   MachineFrameInfo &MFI = MF->getFrameInfo();
+  Align Alignment = MFI.getObjectAlign(FI);
   DebugLoc DL =
       Flags & MachineInstr::FrameDestroy ? MBB.findDebugLoc(I) : DebugLoc();
 
@@ -753,10 +755,10 @@ void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
   } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::LW_INX;
   } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
-    if (!STI.is64Bit() && STI.hasStdExtZilsd() && STI.allowZilsd4ByteAlign()) {
+    if (!STI.is64Bit() && STI.hasStdExtZilsd() &&
+        Alignment >= STI.getZilsdAlign()) {
       Opcode = RISCV::LD_RV32;
     } else {
-      assert(STI.hasStdExtZdinx() && !STI.is64Bit());
       Opcode = RISCV::PseudoRV32ZdinxLD;
     }
   } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
@@ -801,7 +803,7 @@ void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
   if (RISCVRegisterInfo::isRVVRegClass(RC)) {
     MachineMemOperand *MMO = MF->getMachineMemOperand(
         MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
-        TypeSize::getScalable(MFI.getObjectSize(FI)), MFI.getObjectAlign(FI));
+        TypeSize::getScalable(MFI.getObjectSize(FI)), Alignment);
 
     MFI.setStackID(FI, TargetStackID::ScalableVector);
     BuildMI(MBB, I, DL, get(Opcode), DstReg)
@@ -812,7 +814,7 @@ void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
   } else {
     MachineMemOperand *MMO = MF->getMachineMemOperand(
         MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
-        MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
+        MFI.getObjectSize(FI), Alignment);
 
     BuildMI(MBB, I, DL, get(Opcode), DstReg)
         .addFrameIndex(FI)
diff --git a/llvm/test/CodeGen/RISCV/zdinx-spill.ll b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
index c96d9aabeee32..fc1199cd239f2 100644
--- a/llvm/test/CodeGen/RISCV/zdinx-spill.ll
+++ b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
@@ -97,9 +97,9 @@ define double @foo(double %x) nounwind {
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   SD_RV32 killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
   ; ZDINX-ZILSD-UNALIGNED-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-ZILSD-UNALIGNED-NEXT:   renamable $x10_x11 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.0, align 4)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 8 :: (load (s64) from %stack.0, align 4)
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)

>From 381ad6405b0ac4f0531ca23f9bdd08c9fcbe48d4 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Mon, 12 Jan 2026 10:39:40 +0530
Subject: [PATCH 6/6] Test for Zilsd using PseudoRV32Zdinx when Zdnix not
 enabled

---
 llvm/test/CodeGen/RISCV/zilsd-spill.ll | 220 +++++++++++++++++++++++++
 1 file changed, 220 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/zilsd-spill.ll

diff --git a/llvm/test/CodeGen/RISCV/zilsd-spill.ll b/llvm/test/CodeGen/RISCV/zilsd-spill.ll
new file mode 100644
index 0000000000000..e937925dc7591
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/zilsd-spill.ll
@@ -0,0 +1,220 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs -stop-after=prologepilog \
+; RUN: | FileCheck %s -check-prefix=RV32I
+; RUN: llc < %s -mtriple=riscv32 -mattr=+zilsd -verify-machineinstrs -stop-after=prologepilog \
+; RUN: | FileCheck %s -check-prefix=RV32I-ZILSD
+; RUN: llc < %s -mtriple=riscv32 -mattr=+zilsd,+unaligned-scalar-mem  -verify-machineinstrs -stop-after=prologepilog \
+; RUN: | FileCheck %s -check-prefix=RV32I-ZILSD-UNALIGNED
+; RUN: llc < %s -mtriple=riscv32 -mattr=+zilsd,+zilsd-4byte-align -verify-machineinstrs -stop-after=prologepilog \
+; RUN: | FileCheck %s -check-prefix=RV32I-ZILSD-4BYTEALIGN
+
+define i64 @cmpxchg_i64_monotonic_monotonic(ptr %ptr, i64 %cmp, i64 %val) nounwind {
+  ; RV32I-LABEL: name: cmpxchg_i64_monotonic_monotonic
+  ; RV32I: bb.0 (%ir-block.0):
+  ; RV32I-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT:   $x2 = frame-setup ADDI $x2, -64
+  ; RV32I-NEXT:   frame-setup SW killed $x1, $x2, 60 :: (store (s32) into %stack.1)
+  ; RV32I-NEXT:   frame-setup SW killed $x8, $x2, 56 :: (store (s32) into %stack.2)
+  ; RV32I-NEXT:   frame-setup SW killed $x9, $x2, 52 :: (store (s32) into %stack.3)
+  ; RV32I-NEXT:   frame-setup SW killed $x18, $x2, 48 :: (store (s32) into %stack.4)
+  ; RV32I-NEXT:   frame-setup SW killed $x19, $x2, 44 :: (store (s32) into %stack.5)
+  ; RV32I-NEXT:   frame-setup SW killed $x20, $x2, 40 :: (store (s32) into %stack.6)
+  ; RV32I-NEXT:   frame-setup SW killed $x21, $x2, 36 :: (store (s32) into %stack.7)
+  ; RV32I-NEXT:   frame-setup SW killed $x22, $x2, 32 :: (store (s32) into %stack.8)
+  ; RV32I-NEXT:   frame-setup SW killed $x23, $x2, 28 :: (store (s32) into %stack.9)
+  ; RV32I-NEXT:   frame-setup SW killed $x24, $x2, 24 :: (store (s32) into %stack.10)
+  ; RV32I-NEXT:   frame-setup SW killed $x25, $x2, 20 :: (store (s32) into %stack.11)
+  ; RV32I-NEXT:   frame-setup SW killed $x26, $x2, 16 :: (store (s32) into %stack.12)
+  ; RV32I-NEXT:   frame-setup SW killed $x27, $x2, 12 :: (store (s32) into %stack.13)
+  ; RV32I-NEXT:   SW killed renamable $x11, $x2, 0 :: (store (s32) into %ir.1, align 8)
+  ; RV32I-NEXT:   SW killed renamable $x12, $x2, 4 :: (store (s32) into %ir.1 + 4, basealign 8)
+  ; RV32I-NEXT:   $x11 = ADDI $x2, 0
+  ; RV32I-NEXT:   $x12 = COPY killed renamable $x13
+  ; RV32I-NEXT:   $x13 = COPY killed renamable $x14
+  ; RV32I-NEXT:   $x14 = COPY $x0
+  ; RV32I-NEXT:   $x15 = COPY $x0
+  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @__atomic_compare_exchange_8, csr_ilp32_lp64, implicit-def dead $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit-def $x2, implicit-def dead $x10
+  ; RV32I-NEXT:   renamable $x10 = LW $x2, 0 :: (dereferenceable load (s32) from %ir.1, align 8)
+  ; RV32I-NEXT:   renamable $x11 = LW $x2, 4 :: (dereferenceable load (s32) from %ir.1 + 4, basealign 8)
+  ; RV32I-NEXT:   renamable $x5 = ADD renamable $x10, renamable $x10
+  ; RV32I-NEXT:   renamable $x11 = ADD killed renamable $x11, renamable $x11
+  ; RV32I-NEXT:   renamable $x30 = SLTU renamable $x5, killed renamable $x10
+  ; RV32I-NEXT:   renamable $x30 = ADD killed renamable $x11, killed renamable $x30
+  ; RV32I-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
+  ; RV32I-NEXT:   $x10 = COPY killed renamable $x5
+  ; RV32I-NEXT:   $x11 = COPY killed renamable $x30
+  ; RV32I-NEXT:   $x1 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
+  ; RV32I-NEXT:   $x8 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
+  ; RV32I-NEXT:   $x9 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
+  ; RV32I-NEXT:   $x18 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
+  ; RV32I-NEXT:   $x19 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
+  ; RV32I-NEXT:   $x20 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
+  ; RV32I-NEXT:   $x21 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
+  ; RV32I-NEXT:   $x22 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
+  ; RV32I-NEXT:   $x23 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
+  ; RV32I-NEXT:   $x24 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
+  ; RV32I-NEXT:   $x25 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
+  ; RV32I-NEXT:   $x26 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
+  ; RV32I-NEXT:   $x27 = frame-destroy LW $x2, 12 :: (load (s32) from %stack.13)
+  ; RV32I-NEXT:   $x2 = frame-destroy ADDI $x2, 64
+  ; RV32I-NEXT:   PseudoRET implicit $x10, implicit $x11
+  ;
+  ; RV32I-ZILSD-LABEL: name: cmpxchg_i64_monotonic_monotonic
+  ; RV32I-ZILSD: bb.0 (%ir-block.0):
+  ; RV32I-ZILSD-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; RV32I-ZILSD-NEXT: {{  $}}
+  ; RV32I-ZILSD-NEXT:   $x2 = frame-setup ADDI $x2, -80
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x1, $x2, 76 :: (store (s32) into %stack.2)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x8, $x2, 72 :: (store (s32) into %stack.3)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x9, $x2, 68 :: (store (s32) into %stack.4)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x18, $x2, 64 :: (store (s32) into %stack.5)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x19, $x2, 60 :: (store (s32) into %stack.6)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x20, $x2, 56 :: (store (s32) into %stack.7)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x21, $x2, 52 :: (store (s32) into %stack.8)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x22, $x2, 48 :: (store (s32) into %stack.9)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x23, $x2, 44 :: (store (s32) into %stack.10)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x24, $x2, 40 :: (store (s32) into %stack.11)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x25, $x2, 36 :: (store (s32) into %stack.12)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x26, $x2, 32 :: (store (s32) into %stack.13)
+  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x27, $x2, 28 :: (store (s32) into %stack.14)
+  ; RV32I-ZILSD-NEXT:   renamable $x17 = COPY $x12
+  ; RV32I-ZILSD-NEXT:   renamable $x16 = COPY $x11
+  ; RV32I-ZILSD-NEXT:   SD_RV32 killed renamable $x16_x17, $x2, 16 :: (store (s64) into %ir.1)
+  ; RV32I-ZILSD-NEXT:   $x11 = ADDI $x2, 16
+  ; RV32I-ZILSD-NEXT:   $x12 = COPY killed renamable $x13
+  ; RV32I-ZILSD-NEXT:   $x13 = COPY killed renamable $x14
+  ; RV32I-ZILSD-NEXT:   $x14 = COPY $x0
+  ; RV32I-ZILSD-NEXT:   $x15 = COPY $x0
+  ; RV32I-ZILSD-NEXT:   PseudoCALL target-flags(riscv-call) @__atomic_compare_exchange_8, csr_ilp32_lp64, implicit-def dead $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit-def $x2, implicit-def dead $x10
+  ; RV32I-ZILSD-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 16 :: (dereferenceable load (s64) from %ir.1)
+  ; RV32I-ZILSD-NEXT:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.1, align 4)
+  ; RV32I-ZILSD-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
+  ; RV32I-ZILSD-NEXT:   renamable $x12_x13 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.1, align 4)
+  ; RV32I-ZILSD-NEXT:   renamable $x10 = ADD renamable $x12, renamable $x12
+  ; RV32I-ZILSD-NEXT:   renamable $x11 = SLTU renamable $x10, renamable $x12
+  ; RV32I-ZILSD-NEXT:   renamable $x12 = ADD killed renamable $x13, renamable $x13
+  ; RV32I-ZILSD-NEXT:   renamable $x11 = ADD killed renamable $x12, killed renamable $x11
+  ; RV32I-ZILSD-NEXT:   $x1 = frame-destroy LW $x2, 76 :: (load (s32) from %stack.2)
+  ; RV32I-ZILSD-NEXT:   $x8 = frame-destroy LW $x2, 72 :: (load (s32) from %stack.3)
+  ; RV32I-ZILSD-NEXT:   $x9 = frame-destroy LW $x2, 68 :: (load (s32) from %stack.4)
+  ; RV32I-ZILSD-NEXT:   $x18 = frame-destroy LW $x2, 64 :: (load (s32) from %stack.5)
+  ; RV32I-ZILSD-NEXT:   $x19 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.6)
+  ; RV32I-ZILSD-NEXT:   $x20 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.7)
+  ; RV32I-ZILSD-NEXT:   $x21 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.8)
+  ; RV32I-ZILSD-NEXT:   $x22 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.9)
+  ; RV32I-ZILSD-NEXT:   $x23 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.10)
+  ; RV32I-ZILSD-NEXT:   $x24 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.11)
+  ; RV32I-ZILSD-NEXT:   $x25 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.12)
+  ; RV32I-ZILSD-NEXT:   $x26 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.13)
+  ; RV32I-ZILSD-NEXT:   $x27 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.14)
+  ; RV32I-ZILSD-NEXT:   $x2 = frame-destroy ADDI $x2, 80
+  ; RV32I-ZILSD-NEXT:   PseudoRET implicit $x10, implicit $x11
+  ;
+  ; RV32I-ZILSD-UNALIGNED-LABEL: name: cmpxchg_i64_monotonic_monotonic
+  ; RV32I-ZILSD-UNALIGNED: bb.0 (%ir-block.0):
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; RV32I-ZILSD-UNALIGNED-NEXT: {{  $}}
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x2 = frame-setup ADDI $x2, -80
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x1, $x2, 76 :: (store (s32) into %stack.2)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x8, $x2, 72 :: (store (s32) into %stack.3)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x9, $x2, 68 :: (store (s32) into %stack.4)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x18, $x2, 64 :: (store (s32) into %stack.5)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x19, $x2, 60 :: (store (s32) into %stack.6)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x20, $x2, 56 :: (store (s32) into %stack.7)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x21, $x2, 52 :: (store (s32) into %stack.8)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x22, $x2, 48 :: (store (s32) into %stack.9)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x23, $x2, 44 :: (store (s32) into %stack.10)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x24, $x2, 40 :: (store (s32) into %stack.11)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x25, $x2, 36 :: (store (s32) into %stack.12)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x26, $x2, 32 :: (store (s32) into %stack.13)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x27, $x2, 28 :: (store (s32) into %stack.14)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x17 = COPY $x12
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x16 = COPY $x11
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   SD_RV32 killed renamable $x16_x17, $x2, 16 :: (store (s64) into %ir.1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x11 = ADDI $x2, 16
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x12 = COPY killed renamable $x13
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x13 = COPY killed renamable $x14
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x14 = COPY $x0
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x15 = COPY $x0
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   PseudoCALL target-flags(riscv-call) @__atomic_compare_exchange_8, csr_ilp32_lp64, implicit-def dead $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit-def $x2, implicit-def dead $x10
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 16 :: (dereferenceable load (s64) from %ir.1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   SD_RV32 killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.1, align 4)
+  ; RV32I-ZILSD-UNALIGNED-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
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x12_x13 = LD_RV32 $x2, 8 :: (load (s64) from %stack.1, align 4)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x10 = ADD renamable $x12, renamable $x12
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x11 = SLTU renamable $x10, renamable $x12
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x12 = ADD killed renamable $x13, renamable $x13
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x11 = ADD killed renamable $x12, killed renamable $x11
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x1 = frame-destroy LW $x2, 76 :: (load (s32) from %stack.2)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x8 = frame-destroy LW $x2, 72 :: (load (s32) from %stack.3)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x9 = frame-destroy LW $x2, 68 :: (load (s32) from %stack.4)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x18 = frame-destroy LW $x2, 64 :: (load (s32) from %stack.5)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x19 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.6)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x20 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.7)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x21 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.8)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x22 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.9)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x23 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.10)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x24 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.11)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x25 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.12)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x26 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.13)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x27 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.14)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x2 = frame-destroy ADDI $x2, 80
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   PseudoRET implicit $x10, implicit $x11
+  ;
+  ; RV32I-ZILSD-4BYTEALIGN-LABEL: name: cmpxchg_i64_monotonic_monotonic
+  ; RV32I-ZILSD-4BYTEALIGN: bb.0 (%ir-block.0):
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT: {{  $}}
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x2 = frame-setup ADDI $x2, -80
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x1, $x2, 76 :: (store (s32) into %stack.2)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x8, $x2, 72 :: (store (s32) into %stack.3)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x9, $x2, 68 :: (store (s32) into %stack.4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x18, $x2, 64 :: (store (s32) into %stack.5)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x19, $x2, 60 :: (store (s32) into %stack.6)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x20, $x2, 56 :: (store (s32) into %stack.7)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x21, $x2, 52 :: (store (s32) into %stack.8)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x22, $x2, 48 :: (store (s32) into %stack.9)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x23, $x2, 44 :: (store (s32) into %stack.10)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x24, $x2, 40 :: (store (s32) into %stack.11)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x25, $x2, 36 :: (store (s32) into %stack.12)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x26, $x2, 32 :: (store (s32) into %stack.13)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x27, $x2, 28 :: (store (s32) into %stack.14)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x17 = COPY $x12
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x16 = COPY $x11
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   SD_RV32 killed renamable $x16_x17, $x2, 16 :: (store (s64) into %ir.1)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x11 = ADDI $x2, 16
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x12 = COPY killed renamable $x13
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x13 = COPY killed renamable $x14
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x14 = COPY $x0
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x15 = COPY $x0
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   PseudoCALL target-flags(riscv-call) @__atomic_compare_exchange_8, csr_ilp32_lp64, implicit-def dead $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit-def $x2, implicit-def dead $x10
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 16 :: (dereferenceable load (s64) from %ir.1)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   SD_RV32 killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.1, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-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
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x12_x13 = LD_RV32 $x2, 8 :: (load (s64) from %stack.1, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x10 = ADD renamable $x12, renamable $x12
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x11 = SLTU renamable $x10, renamable $x12
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x12 = ADD killed renamable $x13, renamable $x13
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x11 = ADD killed renamable $x12, killed renamable $x11
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x1 = frame-destroy LW $x2, 76 :: (load (s32) from %stack.2)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x8 = frame-destroy LW $x2, 72 :: (load (s32) from %stack.3)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x9 = frame-destroy LW $x2, 68 :: (load (s32) from %stack.4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x18 = frame-destroy LW $x2, 64 :: (load (s32) from %stack.5)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x19 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.6)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x20 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.7)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x21 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.8)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x22 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.9)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x23 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.10)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x24 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.11)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x25 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.12)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x26 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.13)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x27 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.14)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x2 = frame-destroy ADDI $x2, 80
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   PseudoRET implicit $x10, implicit $x11
+  %res = cmpxchg ptr %ptr, i64 %cmp, i64 %val monotonic monotonic
+  %1 = extractvalue { i64, i1 } %res, 0
+  %2 = add i64 %1, %1
+  call void asm sideeffect "", "~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15},~{x16},~{x17},~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{x29},~{xr0},~{x31}"()
+  ret i64 %2
+}



More information about the llvm-commits mailing list