[llvm] [RISCV] Fix Lsb > Msb case in (sra (sext_inreg X, _), C) for th.ext (PR #136287)

Jim Lin via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 18 02:32:22 PDT 2025


https://github.com/tclin914 updated https://github.com/llvm/llvm-project/pull/136287

>From bb6fe5170be04c102250a76365dd3ce538b49fcc Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Fri, 18 Apr 2025 15:18:28 +0800
Subject: [PATCH 1/2] [RISCV] Pre-commit test

---
 llvm/test/CodeGen/RISCV/rv32xtheadbb.ll | 32 +++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
index 4bb8d6c248caa..a5650d7b797a2 100644
--- a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
@@ -401,6 +401,38 @@ define i64 @no_sexth_i64(i64 %a) nounwind {
   ret i64 %shr
 }
 
+define i32 @sext_sextinreg_sra(i16 %a) nounwind {
+; RV32I-LABEL: sext_sextinreg_sra:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    slli a0, a0, 16
+; RV32I-NEXT:    srai a0, a0, 26
+; RV32I-NEXT:    ret
+;
+; RV32XTHEADBB-LABEL: sext_sextinreg_sra:
+; RV32XTHEADBB:       # %bb.0:
+; RV32XTHEADBB-NEXT:    th.ext a0, a0, 15, 10
+; RV32XTHEADBB-NEXT:    ret
+  %sext = sext i16 %a to i32
+  %shr = ashr exact i32 %sext, 10
+  ret i32 %shr
+}
+
+define i32 @sext_sextinreg_sra_2(i16 %a) nounwind {
+; RV32I-LABEL: sext_sextinreg_sra_2:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    slli a0, a0, 16
+; RV32I-NEXT:    srai a0, a0, 31
+; RV32I-NEXT:    ret
+;
+; RV32XTHEADBB-LABEL: sext_sextinreg_sra_2:
+; RV32XTHEADBB:       # %bb.0:
+; RV32XTHEADBB-NEXT:    th.ext a0, a0, 15, 24
+; RV32XTHEADBB-NEXT:    ret
+  %sext = sext i16 %a to i32
+  %shr = ashr exact i32 %sext, 24
+  ret i32 %shr
+}
+
 define i32 @zexth_i32(i32 %a) nounwind {
 ; RV32I-LABEL: zexth_i32:
 ; RV32I:       # %bb.0:

>From cb71c3f88c5c0eef7473053f20889ea9116befe2 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Fri, 18 Apr 2025 15:54:23 +0800
Subject: [PATCH 2/2] [RISCV] Fix Lsb > Msb case in (sra (sext_inreg X, _), C)
 for th.ext

According the spec
https://github.com/XUANTIE-RV/thead-extension-spec/releases/tag/2.3.0,
the operation of `th.ext rd, rs1, msb, lsb` is

  reg[rd] := sign_extend(reg[rs1][msb:lsb])

The spec doesn't specify if lsb is greater than msb.

I don't think lsb can be greater than msb. So that If
the shift-right amount is greater than msb, we can set lsb equal to
msb to extract the bit rs1[msb] and sign-extend it.
---
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 4 +++-
 llvm/test/CodeGen/RISCV/rv32xtheadbb.ll     | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 2d07a66ff275e..37b457e8a9b1e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -653,7 +653,9 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
       return false;
 
     const unsigned Msb = ExtSize - 1;
-    const unsigned Lsb = RightShAmt;
+    // If the shift-right amount is greater than Msb, it means that extracts
+    // the X[Msb] bit and sign-extend it.
+    const unsigned Lsb = RightShAmt > Msb ? Msb : RightShAmt;
 
     SDNode *TH_EXT = BitfieldExtract(N0, Msb, Lsb, DL, VT);
     ReplaceNode(Node, TH_EXT);
diff --git a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
index a5650d7b797a2..04a2f67c4942b 100644
--- a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
@@ -426,7 +426,7 @@ define i32 @sext_sextinreg_sra_2(i16 %a) nounwind {
 ;
 ; RV32XTHEADBB-LABEL: sext_sextinreg_sra_2:
 ; RV32XTHEADBB:       # %bb.0:
-; RV32XTHEADBB-NEXT:    th.ext a0, a0, 15, 24
+; RV32XTHEADBB-NEXT:    th.ext a0, a0, 15, 15
 ; RV32XTHEADBB-NEXT:    ret
   %sext = sext i16 %a to i32
   %shr = ashr exact i32 %sext, 24



More information about the llvm-commits mailing list