-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[RISCV] Improve instruction selection for most significant bit extraction #151687
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
Conversation
pfusik
commented
Aug 1, 2025
@llvm/pr-subscribers-backend-risc-v Author: Piotr Fusik (pfusik) Changes
Patch is 138.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/151687.diff 39 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 653607827282e..d0c9d32af2786 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1691,6 +1691,20 @@ multiclass SelectCC_GPR_riirr<DAGOperand valty, DAGOperand imm> {
valty:$truev, valty:$falsev), []>;
}
+let Predicates = [IsRV32] in {
+def : Pat<(i32 (seteq (i32 (and GPR:$rs1, 0xffffffff80000000)), 0)),
+ (XORI (i32 (SRLI GPR:$rs1, 31)), 1)>;
+def : Pat<(i32 (setlt (i32 GPR:$rs1), 0)), (SRLI GPR:$rs1, 31)>; // compressible
+}
+let Predicates = [IsRV64] in {
+def : Pat<(i64 (seteq (i64 (and GPR:$rs1, 0x8000000000000000)), 0)),
+ (XORI (i64 (SRLI GPR:$rs1, 63)), 1)>;
+def : Pat<(i64 (seteq (i64 (and GPR:$rs1, 0x0000000080000000)), 0)),
+ (XORI (i64 (SRLIW GPR:$rs1, 31)), 1)>;
+def : Pat<(i64 (setlt (i64 GPR:$rs1), 0)), (SRLI GPR:$rs1, 63)>; // compressible
+def : Pat<(i64 (setlt (sext_inreg GPR:$rs1, i32), 0)), (SRLIW GPR:$rs1, 31)>;
+}
+
/// Branches and jumps
// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction.
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll
index dfa76a2e1531b..9ec8c32e989b0 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll
@@ -138,7 +138,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -148,8 +148,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srliw a0, a0, 31
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -446,7 +445,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -456,8 +455,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srliw a0, a0, 31
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll
index 475b67bda9ae9..380751c907c0d 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll
@@ -138,7 +138,7 @@ define i32 @fcmp_olt(float %a, float %b) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltsf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -148,8 +148,7 @@ define i32 @fcmp_olt(float %a, float %b) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltsf2
-; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srliw a0, a0, 31
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -431,7 +430,7 @@ define i32 @fcmp_ult(float %a, float %b) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gesf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -441,8 +440,7 @@ define i32 @fcmp_ult(float %a, float %b) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gesf2
-; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srliw a0, a0, 31
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/alu64.ll b/llvm/test/CodeGen/RISCV/alu64.ll
index f032756e007b6..c7938a718de70 100644
--- a/llvm/test/CodeGen/RISCV/alu64.ll
+++ b/llvm/test/CodeGen/RISCV/alu64.ll
@@ -37,7 +37,7 @@ define i64 @slti(i64 %a) nounwind {
; RV32I: # %bb.0:
; RV32I-NEXT: beqz a1, .LBB1_2
; RV32I-NEXT: # %bb.1:
-; RV32I-NEXT: slti a0, a1, 0
+; RV32I-NEXT: srli a0, a1, 31
; RV32I-NEXT: li a1, 0
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB1_2:
diff --git a/llvm/test/CodeGen/RISCV/arith-with-overflow.ll b/llvm/test/CodeGen/RISCV/arith-with-overflow.ll
index 4efc224ab1ca7..551d8864033f3 100644
--- a/llvm/test/CodeGen/RISCV/arith-with-overflow.ll
+++ b/llvm/test/CodeGen/RISCV/arith-with-overflow.ll
@@ -12,7 +12,7 @@ define i1 @sadd(i32 %a, i32 %b, ptr %c) nounwind {
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: add a3, a0, a1
; RV32I-NEXT: slt a0, a3, a0
-; RV32I-NEXT: slti a1, a1, 0
+; RV32I-NEXT: srli a1, a1, 31
; RV32I-NEXT: xor a0, a1, a0
; RV32I-NEXT: sw a3, 0(a2)
; RV32I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/bittest.ll b/llvm/test/CodeGen/RISCV/bittest.ll
index fa6892be44d97..95c577f833a37 100644
--- a/llvm/test/CodeGen/RISCV/bittest.ll
+++ b/llvm/test/CodeGen/RISCV/bittest.ll
@@ -187,14 +187,14 @@ define i64 @bittest_31_i64(i64 %a) nounwind {
;
; RV64ZBS-LABEL: bittest_31_i64:
; RV64ZBS: # %bb.0:
-; RV64ZBS-NEXT: not a0, a0
-; RV64ZBS-NEXT: bexti a0, a0, 31
+; RV64ZBS-NEXT: srliw a0, a0, 31
+; RV64ZBS-NEXT: xori a0, a0, 1
; RV64ZBS-NEXT: ret
;
; RV64XTHEADBS-LABEL: bittest_31_i64:
; RV64XTHEADBS: # %bb.0:
-; RV64XTHEADBS-NEXT: not a0, a0
-; RV64XTHEADBS-NEXT: th.tst a0, a0, 31
+; RV64XTHEADBS-NEXT: srliw a0, a0, 31
+; RV64XTHEADBS-NEXT: xori a0, a0, 1
; RV64XTHEADBS-NEXT: ret
%shr = lshr i64 %a, 31
%not = xor i64 %shr, -1
@@ -3507,3 +3507,77 @@ define void @bit_64_1_nz_branch_i64(i64 %0) {
5:
ret void
}
+
+define i32 @bittest_31_andeq0_i64(i64 %x) {
+; RV32-LABEL: bittest_31_andeq0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a0, a0, 31
+; RV32-NEXT: xori a0, a0, 1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_31_andeq0_i64:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: xori a0, a0, 1
+; RV64-NEXT: ret
+ %and = and i64 %x, 2147483648
+ %cmp = icmp eq i64 %and, 0
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+define i32 @bittest_63_andeq0_i64(i64 %x) {
+; RV32-LABEL: bittest_63_andeq0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a1, a1, 31
+; RV32-NEXT: xori a0, a1, 1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_63_andeq0_i64:
+; RV64: # %bb.0:
+; RV64-NEXT: srli a0, a0, 63
+; RV64-NEXT: xori a0, a0, 1
+; RV64-NEXT: ret
+ %and = and i64 %x, 9223372036854775808
+ %cmp = icmp eq i64 %and, 0
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+define i32 @bittest_31_slt0_i32(i32 %x, i1 %y) {
+; RV32-LABEL: bittest_31_slt0_i32:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a0, a0, 31
+; RV32-NEXT: and a0, a0, a1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_31_slt0_i32:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: and a0, a0, a1
+; RV64-NEXT: ret
+ %cmp = icmp slt i32 %x, 0
+ %and = and i1 %cmp, %y
+ %ext = zext i1 %and to i32
+ ret i32 %ext
+}
+
+define i32 @bittest_63_slt0_i64(i32 %x, i1 %y) {
+; RV32-LABEL: bittest_63_slt0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srai a0, a0, 31
+; RV32-NEXT: srli a0, a0, 31
+; RV32-NEXT: and a0, a0, a1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_63_slt0_i64:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: and a0, a0, a1
+; RV64-NEXT: ret
+ %ext = sext i32 %x to i64
+ %cmp = icmp slt i64 %ext, 0
+ %and = and i1 %cmp, %y
+ %cond = zext i1 %and to i32
+ ret i32 %cond
+}
diff --git a/llvm/test/CodeGen/RISCV/condbinops.ll b/llvm/test/CodeGen/RISCV/condbinops.ll
index dc81c13bfb6a3..91052bce9704c 100644
--- a/llvm/test/CodeGen/RISCV/condbinops.ll
+++ b/llvm/test/CodeGen/RISCV/condbinops.ll
@@ -459,7 +459,7 @@ define i64 @shl64(i64 %x, i64 %y, i1 %c) {
; RV32ZICOND-NEXT: addi a4, a2, -32
; RV32ZICOND-NEXT: sll a1, a1, a2
; RV32ZICOND-NEXT: not a2, a2
-; RV32ZICOND-NEXT: slti a4, a4, 0
+; RV32ZICOND-NEXT: srli a4, a4, 31
; RV32ZICOND-NEXT: srl a2, a3, a2
; RV32ZICOND-NEXT: czero.nez a3, a0, a4
; RV32ZICOND-NEXT: or a1, a1, a2
@@ -534,7 +534,7 @@ define i64 @ashr64(i64 %x, i64 %y, i1 %c) {
; RV32ZICOND-NEXT: addi a4, a2, -32
; RV32ZICOND-NEXT: srl a0, a0, a2
; RV32ZICOND-NEXT: not a2, a2
-; RV32ZICOND-NEXT: slti a4, a4, 0
+; RV32ZICOND-NEXT: srli a4, a4, 31
; RV32ZICOND-NEXT: sll a2, a3, a2
; RV32ZICOND-NEXT: czero.nez a3, a1, a4
; RV32ZICOND-NEXT: or a0, a0, a2
@@ -610,7 +610,7 @@ define i64 @lshr64(i64 %x, i64 %y, i1 %c) {
; RV32ZICOND-NEXT: addi a4, a2, -32
; RV32ZICOND-NEXT: srl a0, a0, a2
; RV32ZICOND-NEXT: not a2, a2
-; RV32ZICOND-NEXT: slti a4, a4, 0
+; RV32ZICOND-NEXT: srli a4, a4, 31
; RV32ZICOND-NEXT: sll a2, a3, a2
; RV32ZICOND-NEXT: czero.nez a3, a1, a4
; RV32ZICOND-NEXT: or a0, a0, a2
diff --git a/llvm/test/CodeGen/RISCV/double-convert.ll b/llvm/test/CodeGen/RISCV/double-convert.ll
index a2e6186e051bf..9c81bc2851347 100644
--- a/llvm/test/CodeGen/RISCV/double-convert.ll
+++ b/llvm/test/CodeGen/RISCV/double-convert.ll
@@ -405,7 +405,7 @@ define i32 @fcvt_wu_d_sat(double %a) nounwind {
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: addi s3, a0, -1
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: mv a1, s0
@@ -446,8 +446,8 @@ define i32 @fcvt_wu_d_sat(double %a) nounwind {
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: j .LBB6_3
; RV64I-NEXT: .LBB6_2:
-; RV64I-NEXT: slti a0, s0, 0
-; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: srli s0, s0, 63
+; RV64I-NEXT: addi a0, s0, -1
; RV64I-NEXT: and a0, a0, s1
; RV64I-NEXT: .LBB6_3: # %start
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
@@ -819,7 +819,7 @@ define i64 @fcvt_l_d_sat(double %a) nounwind {
; RV32I-NEXT: mv a3, s0
; RV32I-NEXT: call __unorddf2
; RV32I-NEXT: snez a0, a0
-; RV32I-NEXT: slti a1, s4, 0
+; RV32I-NEXT: srli a1, s4, 31
; RV32I-NEXT: sgtz a2, s2
; RV32I-NEXT: addi a0, a0, -1
; RV32I-NEXT: addi a3, a1, -1
@@ -1029,7 +1029,7 @@ define i64 @fcvt_lu_d_sat(double %a) nounwind {
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: addi s3, a0, -1
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: mv a1, s0
@@ -1055,7 +1055,7 @@ define i64 @fcvt_lu_d_sat(double %a) nounwind {
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: li a1, 0
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: addi s1, a0, -1
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: call __fixunsdfdi
@@ -1898,9 +1898,9 @@ define zeroext i16 @fcvt_wu_s_sat_i16(double %a) nounwind {
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: j .LBB28_3
; RV32I-NEXT: .LBB28_2:
-; RV32I-NEXT: slti a2, s0, 0
-; RV32I-NEXT: addi a2, a2, -1
-; RV32I-NEXT: and a0, a2, a0
+; RV32I-NEXT: srli s0, s0, 31
+; RV32I-NEXT: addi s0, s0, -1
+; RV32I-NEXT: and a0, s0, a0
; RV32I-NEXT: .LBB28_3: # %start
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
@@ -1937,8 +1937,8 @@ define zeroext i16 @fcvt_wu_s_sat_i16(double %a) nounwind {
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: j .LBB28_3
; RV64I-NEXT: .LBB28_2:
-; RV64I-NEXT: slti a0, s0, 0
-; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: srli s0, s0, 63
+; RV64I-NEXT: addi a0, s0, -1
; RV64I-NEXT: and a0, a0, s1
; RV64I-NEXT: .LBB28_3: # %start
; RV64I-NEXT: and a0, a0, a1
@@ -2271,9 +2271,9 @@ define zeroext i8 @fcvt_wu_s_sat_i8(double %a) nounwind {
; RV32I-NEXT: li a0, 255
; RV32I-NEXT: j .LBB32_3
; RV32I-NEXT: .LBB32_2:
-; RV32I-NEXT: slti a1, s0, 0
-; RV32I-NEXT: addi a1, a1, -1
-; RV32I-NEXT: and a0, a1, a0
+; RV32I-NEXT: srli s0, s0, 31
+; RV32I-NEXT: addi s0, s0, -1
+; RV32I-NEXT: and a0, s0, a0
; RV32I-NEXT: .LBB32_3: # %start
; RV32I-NEXT: zext.b a0, a0
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
@@ -2307,8 +2307,8 @@ define zeroext i8 @fcvt_wu_s_sat_i8(double %a) nounwind {
; RV64I-NEXT: li a0, 255
; RV64I-NEXT: j .LBB32_3
; RV64I-NEXT: .LBB32_2:
-; RV64I-NEXT: slti a0, s0, 0
-; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: srli s0, s0, 63
+; RV64I-NEXT: addi a0, s0, -1
; RV64I-NEXT: and a0, a0, s1
; RV64I-NEXT: .LBB32_3: # %start
; RV64I-NEXT: zext.b a0, a0
@@ -2386,7 +2386,7 @@ define zeroext i32 @fcvt_wu_d_sat_zext(double %a) nounwind {
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: addi s3, a0, -1
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: mv a1, s0
@@ -2427,8 +2427,8 @@ define zeroext i32 @fcvt_wu_d_sat_zext(double %a) nounwind {
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: j .LBB33_3
; RV64I-NEXT: .LBB33_2:
-; RV64I-NEXT: slti a0, s0, 0
-; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: srli s0, s0, 63
+; RV64I-NEXT: addi a0, s0, -1
; RV64I-NEXT: and a0, a0, s1
; RV64I-NEXT: .LBB33_3: # %start
; RV64I-NEXT: slli a0, a0, 32
diff --git a/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll b/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll
index 7c5332f719867..b1c63af3e7e07 100644
--- a/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll
+++ b/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll
@@ -140,7 +140,7 @@ define i32 @fcmp_oge(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: xori a0, a0, 1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
@@ -151,7 +151,7 @@ define i32 @fcmp_oge(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: xori a0, a0, 1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
@@ -193,7 +193,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -203,7 +203,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -605,7 +605,7 @@ define i32 @fcmp_uge(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: xori a0, a0, 1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
@@ -616,7 +616,7 @@ define i32 @fcmp_uge(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: xori a0, a0, 1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
@@ -661,7 +661,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -671,7 +671,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -934,7 +934,7 @@ define i32 @fcmps_oge(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: xori a0, a0, 1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
@@ -945,7 +945,7 @@ define i32 @fcmps_oge(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: xori a0, a0, 1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
@@ -976,7 +976,7 @@ define i32 @fcmps_olt(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -986,7 +986,7 @@ define i32 @fcmps_olt(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -1311,7 +1311,7 @@ define i32 @fcmps_uge(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: xori a0, a0, 1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
@@ -1322,7 +1322,7 @@ define i32 @fcmps_uge(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: xori a0, a0, 1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
@@ -1356,7 +1356,7 @@ define i32 @fcmps_ult(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -1366,7 +13...
[truncated]
|
@llvm/pr-subscribers-llvm-globalisel Author: Piotr Fusik (pfusik) Changes
Patch is 138.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/151687.diff 39 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 653607827282e..d0c9d32af2786 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1691,6 +1691,20 @@ multiclass SelectCC_GPR_riirr<DAGOperand valty, DAGOperand imm> {
valty:$truev, valty:$falsev), []>;
}
+let Predicates = [IsRV32] in {
+def : Pat<(i32 (seteq (i32 (and GPR:$rs1, 0xffffffff80000000)), 0)),
+ (XORI (i32 (SRLI GPR:$rs1, 31)), 1)>;
+def : Pat<(i32 (setlt (i32 GPR:$rs1), 0)), (SRLI GPR:$rs1, 31)>; // compressible
+}
+let Predicates = [IsRV64] in {
+def : Pat<(i64 (seteq (i64 (and GPR:$rs1, 0x8000000000000000)), 0)),
+ (XORI (i64 (SRLI GPR:$rs1, 63)), 1)>;
+def : Pat<(i64 (seteq (i64 (and GPR:$rs1, 0x0000000080000000)), 0)),
+ (XORI (i64 (SRLIW GPR:$rs1, 31)), 1)>;
+def : Pat<(i64 (setlt (i64 GPR:$rs1), 0)), (SRLI GPR:$rs1, 63)>; // compressible
+def : Pat<(i64 (setlt (sext_inreg GPR:$rs1, i32), 0)), (SRLIW GPR:$rs1, 31)>;
+}
+
/// Branches and jumps
// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction.
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll
index dfa76a2e1531b..9ec8c32e989b0 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll
@@ -138,7 +138,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -148,8 +148,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srliw a0, a0, 31
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -446,7 +445,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -456,8 +455,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srliw a0, a0, 31
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll
index 475b67bda9ae9..380751c907c0d 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll
@@ -138,7 +138,7 @@ define i32 @fcmp_olt(float %a, float %b) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltsf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -148,8 +148,7 @@ define i32 @fcmp_olt(float %a, float %b) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltsf2
-; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srliw a0, a0, 31
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -431,7 +430,7 @@ define i32 @fcmp_ult(float %a, float %b) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gesf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -441,8 +440,7 @@ define i32 @fcmp_ult(float %a, float %b) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gesf2
-; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srliw a0, a0, 31
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/alu64.ll b/llvm/test/CodeGen/RISCV/alu64.ll
index f032756e007b6..c7938a718de70 100644
--- a/llvm/test/CodeGen/RISCV/alu64.ll
+++ b/llvm/test/CodeGen/RISCV/alu64.ll
@@ -37,7 +37,7 @@ define i64 @slti(i64 %a) nounwind {
; RV32I: # %bb.0:
; RV32I-NEXT: beqz a1, .LBB1_2
; RV32I-NEXT: # %bb.1:
-; RV32I-NEXT: slti a0, a1, 0
+; RV32I-NEXT: srli a0, a1, 31
; RV32I-NEXT: li a1, 0
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB1_2:
diff --git a/llvm/test/CodeGen/RISCV/arith-with-overflow.ll b/llvm/test/CodeGen/RISCV/arith-with-overflow.ll
index 4efc224ab1ca7..551d8864033f3 100644
--- a/llvm/test/CodeGen/RISCV/arith-with-overflow.ll
+++ b/llvm/test/CodeGen/RISCV/arith-with-overflow.ll
@@ -12,7 +12,7 @@ define i1 @sadd(i32 %a, i32 %b, ptr %c) nounwind {
; RV32I: # %bb.0: # %entry
; RV32I-NEXT: add a3, a0, a1
; RV32I-NEXT: slt a0, a3, a0
-; RV32I-NEXT: slti a1, a1, 0
+; RV32I-NEXT: srli a1, a1, 31
; RV32I-NEXT: xor a0, a1, a0
; RV32I-NEXT: sw a3, 0(a2)
; RV32I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/bittest.ll b/llvm/test/CodeGen/RISCV/bittest.ll
index fa6892be44d97..95c577f833a37 100644
--- a/llvm/test/CodeGen/RISCV/bittest.ll
+++ b/llvm/test/CodeGen/RISCV/bittest.ll
@@ -187,14 +187,14 @@ define i64 @bittest_31_i64(i64 %a) nounwind {
;
; RV64ZBS-LABEL: bittest_31_i64:
; RV64ZBS: # %bb.0:
-; RV64ZBS-NEXT: not a0, a0
-; RV64ZBS-NEXT: bexti a0, a0, 31
+; RV64ZBS-NEXT: srliw a0, a0, 31
+; RV64ZBS-NEXT: xori a0, a0, 1
; RV64ZBS-NEXT: ret
;
; RV64XTHEADBS-LABEL: bittest_31_i64:
; RV64XTHEADBS: # %bb.0:
-; RV64XTHEADBS-NEXT: not a0, a0
-; RV64XTHEADBS-NEXT: th.tst a0, a0, 31
+; RV64XTHEADBS-NEXT: srliw a0, a0, 31
+; RV64XTHEADBS-NEXT: xori a0, a0, 1
; RV64XTHEADBS-NEXT: ret
%shr = lshr i64 %a, 31
%not = xor i64 %shr, -1
@@ -3507,3 +3507,77 @@ define void @bit_64_1_nz_branch_i64(i64 %0) {
5:
ret void
}
+
+define i32 @bittest_31_andeq0_i64(i64 %x) {
+; RV32-LABEL: bittest_31_andeq0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a0, a0, 31
+; RV32-NEXT: xori a0, a0, 1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_31_andeq0_i64:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: xori a0, a0, 1
+; RV64-NEXT: ret
+ %and = and i64 %x, 2147483648
+ %cmp = icmp eq i64 %and, 0
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+define i32 @bittest_63_andeq0_i64(i64 %x) {
+; RV32-LABEL: bittest_63_andeq0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a1, a1, 31
+; RV32-NEXT: xori a0, a1, 1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_63_andeq0_i64:
+; RV64: # %bb.0:
+; RV64-NEXT: srli a0, a0, 63
+; RV64-NEXT: xori a0, a0, 1
+; RV64-NEXT: ret
+ %and = and i64 %x, 9223372036854775808
+ %cmp = icmp eq i64 %and, 0
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+define i32 @bittest_31_slt0_i32(i32 %x, i1 %y) {
+; RV32-LABEL: bittest_31_slt0_i32:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a0, a0, 31
+; RV32-NEXT: and a0, a0, a1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_31_slt0_i32:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: and a0, a0, a1
+; RV64-NEXT: ret
+ %cmp = icmp slt i32 %x, 0
+ %and = and i1 %cmp, %y
+ %ext = zext i1 %and to i32
+ ret i32 %ext
+}
+
+define i32 @bittest_63_slt0_i64(i32 %x, i1 %y) {
+; RV32-LABEL: bittest_63_slt0_i64:
+; RV32: # %bb.0:
+; RV32-NEXT: srai a0, a0, 31
+; RV32-NEXT: srli a0, a0, 31
+; RV32-NEXT: and a0, a0, a1
+; RV32-NEXT: ret
+;
+; RV64-LABEL: bittest_63_slt0_i64:
+; RV64: # %bb.0:
+; RV64-NEXT: srliw a0, a0, 31
+; RV64-NEXT: and a0, a0, a1
+; RV64-NEXT: ret
+ %ext = sext i32 %x to i64
+ %cmp = icmp slt i64 %ext, 0
+ %and = and i1 %cmp, %y
+ %cond = zext i1 %and to i32
+ ret i32 %cond
+}
diff --git a/llvm/test/CodeGen/RISCV/condbinops.ll b/llvm/test/CodeGen/RISCV/condbinops.ll
index dc81c13bfb6a3..91052bce9704c 100644
--- a/llvm/test/CodeGen/RISCV/condbinops.ll
+++ b/llvm/test/CodeGen/RISCV/condbinops.ll
@@ -459,7 +459,7 @@ define i64 @shl64(i64 %x, i64 %y, i1 %c) {
; RV32ZICOND-NEXT: addi a4, a2, -32
; RV32ZICOND-NEXT: sll a1, a1, a2
; RV32ZICOND-NEXT: not a2, a2
-; RV32ZICOND-NEXT: slti a4, a4, 0
+; RV32ZICOND-NEXT: srli a4, a4, 31
; RV32ZICOND-NEXT: srl a2, a3, a2
; RV32ZICOND-NEXT: czero.nez a3, a0, a4
; RV32ZICOND-NEXT: or a1, a1, a2
@@ -534,7 +534,7 @@ define i64 @ashr64(i64 %x, i64 %y, i1 %c) {
; RV32ZICOND-NEXT: addi a4, a2, -32
; RV32ZICOND-NEXT: srl a0, a0, a2
; RV32ZICOND-NEXT: not a2, a2
-; RV32ZICOND-NEXT: slti a4, a4, 0
+; RV32ZICOND-NEXT: srli a4, a4, 31
; RV32ZICOND-NEXT: sll a2, a3, a2
; RV32ZICOND-NEXT: czero.nez a3, a1, a4
; RV32ZICOND-NEXT: or a0, a0, a2
@@ -610,7 +610,7 @@ define i64 @lshr64(i64 %x, i64 %y, i1 %c) {
; RV32ZICOND-NEXT: addi a4, a2, -32
; RV32ZICOND-NEXT: srl a0, a0, a2
; RV32ZICOND-NEXT: not a2, a2
-; RV32ZICOND-NEXT: slti a4, a4, 0
+; RV32ZICOND-NEXT: srli a4, a4, 31
; RV32ZICOND-NEXT: sll a2, a3, a2
; RV32ZICOND-NEXT: czero.nez a3, a1, a4
; RV32ZICOND-NEXT: or a0, a0, a2
diff --git a/llvm/test/CodeGen/RISCV/double-convert.ll b/llvm/test/CodeGen/RISCV/double-convert.ll
index a2e6186e051bf..9c81bc2851347 100644
--- a/llvm/test/CodeGen/RISCV/double-convert.ll
+++ b/llvm/test/CodeGen/RISCV/double-convert.ll
@@ -405,7 +405,7 @@ define i32 @fcvt_wu_d_sat(double %a) nounwind {
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: addi s3, a0, -1
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: mv a1, s0
@@ -446,8 +446,8 @@ define i32 @fcvt_wu_d_sat(double %a) nounwind {
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: j .LBB6_3
; RV64I-NEXT: .LBB6_2:
-; RV64I-NEXT: slti a0, s0, 0
-; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: srli s0, s0, 63
+; RV64I-NEXT: addi a0, s0, -1
; RV64I-NEXT: and a0, a0, s1
; RV64I-NEXT: .LBB6_3: # %start
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
@@ -819,7 +819,7 @@ define i64 @fcvt_l_d_sat(double %a) nounwind {
; RV32I-NEXT: mv a3, s0
; RV32I-NEXT: call __unorddf2
; RV32I-NEXT: snez a0, a0
-; RV32I-NEXT: slti a1, s4, 0
+; RV32I-NEXT: srli a1, s4, 31
; RV32I-NEXT: sgtz a2, s2
; RV32I-NEXT: addi a0, a0, -1
; RV32I-NEXT: addi a3, a1, -1
@@ -1029,7 +1029,7 @@ define i64 @fcvt_lu_d_sat(double %a) nounwind {
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: addi s3, a0, -1
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: mv a1, s0
@@ -1055,7 +1055,7 @@ define i64 @fcvt_lu_d_sat(double %a) nounwind {
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: li a1, 0
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: addi s1, a0, -1
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: call __fixunsdfdi
@@ -1898,9 +1898,9 @@ define zeroext i16 @fcvt_wu_s_sat_i16(double %a) nounwind {
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: j .LBB28_3
; RV32I-NEXT: .LBB28_2:
-; RV32I-NEXT: slti a2, s0, 0
-; RV32I-NEXT: addi a2, a2, -1
-; RV32I-NEXT: and a0, a2, a0
+; RV32I-NEXT: srli s0, s0, 31
+; RV32I-NEXT: addi s0, s0, -1
+; RV32I-NEXT: and a0, s0, a0
; RV32I-NEXT: .LBB28_3: # %start
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
@@ -1937,8 +1937,8 @@ define zeroext i16 @fcvt_wu_s_sat_i16(double %a) nounwind {
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: j .LBB28_3
; RV64I-NEXT: .LBB28_2:
-; RV64I-NEXT: slti a0, s0, 0
-; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: srli s0, s0, 63
+; RV64I-NEXT: addi a0, s0, -1
; RV64I-NEXT: and a0, a0, s1
; RV64I-NEXT: .LBB28_3: # %start
; RV64I-NEXT: and a0, a0, a1
@@ -2271,9 +2271,9 @@ define zeroext i8 @fcvt_wu_s_sat_i8(double %a) nounwind {
; RV32I-NEXT: li a0, 255
; RV32I-NEXT: j .LBB32_3
; RV32I-NEXT: .LBB32_2:
-; RV32I-NEXT: slti a1, s0, 0
-; RV32I-NEXT: addi a1, a1, -1
-; RV32I-NEXT: and a0, a1, a0
+; RV32I-NEXT: srli s0, s0, 31
+; RV32I-NEXT: addi s0, s0, -1
+; RV32I-NEXT: and a0, s0, a0
; RV32I-NEXT: .LBB32_3: # %start
; RV32I-NEXT: zext.b a0, a0
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
@@ -2307,8 +2307,8 @@ define zeroext i8 @fcvt_wu_s_sat_i8(double %a) nounwind {
; RV64I-NEXT: li a0, 255
; RV64I-NEXT: j .LBB32_3
; RV64I-NEXT: .LBB32_2:
-; RV64I-NEXT: slti a0, s0, 0
-; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: srli s0, s0, 63
+; RV64I-NEXT: addi a0, s0, -1
; RV64I-NEXT: and a0, a0, s1
; RV64I-NEXT: .LBB32_3: # %start
; RV64I-NEXT: zext.b a0, a0
@@ -2386,7 +2386,7 @@ define zeroext i32 @fcvt_wu_d_sat_zext(double %a) nounwind {
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: addi s3, a0, -1
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: mv a1, s0
@@ -2427,8 +2427,8 @@ define zeroext i32 @fcvt_wu_d_sat_zext(double %a) nounwind {
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: j .LBB33_3
; RV64I-NEXT: .LBB33_2:
-; RV64I-NEXT: slti a0, s0, 0
-; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: srli s0, s0, 63
+; RV64I-NEXT: addi a0, s0, -1
; RV64I-NEXT: and a0, a0, s1
; RV64I-NEXT: .LBB33_3: # %start
; RV64I-NEXT: slli a0, a0, 32
diff --git a/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll b/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll
index 7c5332f719867..b1c63af3e7e07 100644
--- a/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll
+++ b/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll
@@ -140,7 +140,7 @@ define i32 @fcmp_oge(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: xori a0, a0, 1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
@@ -151,7 +151,7 @@ define i32 @fcmp_oge(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: xori a0, a0, 1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
@@ -193,7 +193,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -203,7 +203,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -605,7 +605,7 @@ define i32 @fcmp_uge(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: xori a0, a0, 1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
@@ -616,7 +616,7 @@ define i32 @fcmp_uge(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: xori a0, a0, 1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
@@ -661,7 +661,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -671,7 +671,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -934,7 +934,7 @@ define i32 @fcmps_oge(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: xori a0, a0, 1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
@@ -945,7 +945,7 @@ define i32 @fcmps_oge(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __gedf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: xori a0, a0, 1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
@@ -976,7 +976,7 @@ define i32 @fcmps_olt(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -986,7 +986,7 @@ define i32 @fcmps_olt(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -1311,7 +1311,7 @@ define i32 @fcmps_uge(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __ltdf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: xori a0, a0, 1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
@@ -1322,7 +1322,7 @@ define i32 @fcmps_uge(double %a, double %b) nounwind strictfp {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: call __ltdf2
-; RV64I-NEXT: slti a0, a0, 0
+; RV64I-NEXT: srli a0, a0, 63
; RV64I-NEXT: xori a0, a0, 1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
@@ -1356,7 +1356,7 @@ define i32 @fcmps_ult(double %a, double %b) nounwind strictfp {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: call __gedf2
-; RV32I-NEXT: slti a0, a0, 0
+; RV32I-NEXT: srli a0, a0, 31
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
@@ -1366,7 +13...
[truncated]
|
define i32 @bittest_63_slt0_i64(i32 %x, i1 %y) { | ||
; RV32-LABEL: bittest_63_slt0_i64: | ||
; RV32: # %bb.0: | ||
; RV32-NEXT: srai a0, a0, 31 |
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.
Future optimization opportunity: this srai
was and still is redundant.
The number 0x8000000000000000 caused: warning: integer constant is so large that it is unsigned Emit the INT64_MIN macro instead of a negative literal. Triggered in llvm#151687
…tion (seteq (and X, 1<<XLEN-1), 0) -> (xori (srli X, XLEN-1), 1) (seteq (and X, 1<<31), 0) -> (xori (srliw X, 31), 1) // RV64 (setlt X, 0) -> (srli X, XLEN-1) // SRLI is compressible (setlt (sext X), 0) -> (srliw X, 31) // RV64
Rebased resolving a conflict in |
The numbers are stored in an `uint8_t` array, either directly or via `GIMT_Encode2/4/8` macros (see `getEncodedEmitStr` and `emitEncodingMacrosDef`). Passing negative numbers only adds confusion and results in a warning for the `INT64_MIN` value (C++ parses `-9223372036854775808` as two tokens: a unary minus and an unsigned integer, triggered in llvm#151687).
The numbers are stored in an `uint8_t` array, either directly or via `GIMT_Encode2/4/8` macros (see `getEncodedEmitStr` and `emitEncodingMacrosDef`). Passing negative numbers only adds confusion and results in a warning for the `INT64_MIN` value (C++ parses `-9223372036854775808` as two tokens: a unary minus and an unsigned integer, triggered in #151687). BTW, parenthesize parameters in `GIMT_Encode2/4/8` macros and avoid unnecessary casts.
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