[llvm] [RISCV] Use X0_Pair for storing 0 using Zilsd. (PR #141847)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed May 28 13:22:14 PDT 2025


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/141847

When we're creating a Zilsd store from a split i64 value, check if both inputs are 0 and use X0_Pair instead of a REG_SEQUENCE.

>From 3f78574926d3d93f97d087643017ce27c66a5ce6 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 28 May 2025 13:18:19 -0700
Subject: [PATCH] [RISCV] Use X0_Pair for storing 0 using Zilsd.

When we're creating a Zilsd store from a split i64 value, check
if both inputs are 0 and use X0_Pair instead of a REG_SEQUENCE.
---
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 30 +++++++++++++--------
 llvm/test/CodeGen/RISCV/zilsd.ll            |  6 ++---
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 7f65216282a82..ccb798268fb60 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -1659,18 +1659,26 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
     SDValue Addr = Node->getOperand(3);
     SelectAddrRegImm(Addr, Base, Offset);
 
-    SDValue Ops[] = {
-        CurDAG->getTargetConstant(RISCV::GPRPairRegClassID, DL, MVT::i32),
-        Node->getOperand(1),
-        CurDAG->getTargetConstant(RISCV::sub_gpr_even, DL, MVT::i32),
-        Node->getOperand(2),
-        CurDAG->getTargetConstant(RISCV::sub_gpr_odd, DL, MVT::i32)};
+    SDValue Lo = Node->getOperand(1);
+    SDValue Hi = Node->getOperand(2);
+
+    SDValue RegPair;
+    // Peephole to use X0_Pair for storing zero.
+    if (isNullConstant(Lo) && isNullConstant(Hi)) {
+      RegPair = CurDAG->getRegister(RISCV::X0_Pair, MVT::Untyped);
+    } else {
+      SDValue Ops[] = {
+          CurDAG->getTargetConstant(RISCV::GPRPairRegClassID, DL, MVT::i32), Lo,
+          CurDAG->getTargetConstant(RISCV::sub_gpr_even, DL, MVT::i32), Hi,
+          CurDAG->getTargetConstant(RISCV::sub_gpr_odd, DL, MVT::i32)};
+
+      RegPair = SDValue(CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL,
+                                               MVT::Untyped, Ops),
+                        0);
+    }
 
-    SDNode *RegPair = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL,
-                                             MVT::Untyped, Ops);
-    MachineSDNode *New =
-        CurDAG->getMachineNode(RISCV::SD_RV32, DL, MVT::Other,
-                               {SDValue(RegPair, 0), Base, Offset, Chain});
+    MachineSDNode *New = CurDAG->getMachineNode(RISCV::SD_RV32, DL, MVT::Other,
+                                                {RegPair, Base, Offset, Chain});
     CurDAG->setNodeMemRefs(New, {cast<MemSDNode>(Node)->getMemOperand()});
     ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
     CurDAG->RemoveDeadNode(Node);
diff --git a/llvm/test/CodeGen/RISCV/zilsd.ll b/llvm/test/CodeGen/RISCV/zilsd.ll
index 3eaaffba250dd..f6f87dfe9e789 100644
--- a/llvm/test/CodeGen/RISCV/zilsd.ll
+++ b/llvm/test/CodeGen/RISCV/zilsd.ll
@@ -110,10 +110,8 @@ entry:
 define void @store_g() nounwind {
 ; CHECK-LABEL: store_g:
 ; CHECK:       # %bb.0: # %entyr
-; CHECK-NEXT:    li a0, 0
-; CHECK-NEXT:    lui a2, %hi(g)
-; CHECK-NEXT:    li a1, 0
-; CHECK-NEXT:    sd a0, %lo(g)(a2)
+; CHECK-NEXT:    lui a0, %hi(g)
+; CHECK-NEXT:    sd zero, %lo(g)(a0)
 ; CHECK-NEXT:    ret
 entyr:
   store i64 0, ptr @g



More information about the llvm-commits mailing list