-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[RISCV] Fix Lsb > Msb case in (sra (sext_inreg X, _), C) for th.ext #136287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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/pr-subscribers-backend-risc-v Author: Jim Lin (tclin914) ChangesAccording the spec, the operation of 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. Full diff: https://github.com/llvm/llvm-project/pull/136287.diff 2 Files Affected:
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 4bb8d6c248caa..0ced0c746a4cf 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_sext_inreg_sra(i16 %a) nounwind {
+; RV32I-LABEL: sext_sext_inreg_sra:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srai a0, a0, 26
+; RV32I-NEXT: ret
+;
+; RV32XTHEADBB-LABEL: sext_sext_inreg_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_sext_inreg_sra_2(i16 %a) nounwind {
+; RV32I-LABEL: sext_sext_inreg_sra_2:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srai a0, a0, 31
+; RV32I-NEXT: ret
+;
+; RV32XTHEADBB-LABEL: sext_sext_inreg_sra_2:
+; RV32XTHEADBB: # %bb.0:
+; RV32XTHEADBB-NEXT: th.ext a0, a0, 15, 15
+; 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:
|
7f17c5b
to
cb71c3f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
According the spec, the operation of
th.ext rd, rs1, msb, lsb
isreg[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.