Skip to content

Commit 18782db

Browse files
authored
[RISCV] Improve instruction selection for most significant bit extraction (#151687)
(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
1 parent 7b904b0 commit 18782db

39 files changed

+529
-440
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,20 @@ multiclass SelectCC_GPR_riirr<DAGOperand valty, DAGOperand imm> {
16941694
valty:$truev, valty:$falsev), []>;
16951695
}
16961696

1697+
let Predicates = [IsRV32] in {
1698+
def : Pat<(i32 (seteq (i32 (and GPR:$rs1, 0xffffffff80000000)), 0)),
1699+
(XORI (i32 (SRLI GPR:$rs1, 31)), 1)>;
1700+
def : Pat<(i32 (setlt (i32 GPR:$rs1), 0)), (SRLI GPR:$rs1, 31)>; // compressible
1701+
}
1702+
let Predicates = [IsRV64] in {
1703+
def : Pat<(i64 (seteq (i64 (and GPR:$rs1, 0x8000000000000000)), 0)),
1704+
(XORI (i64 (SRLI GPR:$rs1, 63)), 1)>;
1705+
def : Pat<(i64 (seteq (i64 (and GPR:$rs1, 0x0000000080000000)), 0)),
1706+
(XORI (i64 (SRLIW GPR:$rs1, 31)), 1)>;
1707+
def : Pat<(i64 (setlt (i64 GPR:$rs1), 0)), (SRLI GPR:$rs1, 63)>; // compressible
1708+
def : Pat<(i64 (setlt (sext_inreg GPR:$rs1, i32), 0)), (SRLIW GPR:$rs1, 31)>;
1709+
}
1710+
16971711
/// Branches and jumps
16981712

16991713
// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction.

llvm/test/CodeGen/RISCV/GlobalISel/double-fcmp.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind {
138138
; RV32I-NEXT: addi sp, sp, -16
139139
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
140140
; RV32I-NEXT: call __ltdf2
141-
; RV32I-NEXT: slti a0, a0, 0
141+
; RV32I-NEXT: srli a0, a0, 31
142142
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
143143
; RV32I-NEXT: addi sp, sp, 16
144144
; RV32I-NEXT: ret
@@ -148,8 +148,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind {
148148
; RV64I-NEXT: addi sp, sp, -16
149149
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
150150
; RV64I-NEXT: call __ltdf2
151-
; RV64I-NEXT: sext.w a0, a0
152-
; RV64I-NEXT: slti a0, a0, 0
151+
; RV64I-NEXT: srliw a0, a0, 31
153152
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
154153
; RV64I-NEXT: addi sp, sp, 16
155154
; RV64I-NEXT: ret
@@ -446,7 +445,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind {
446445
; RV32I-NEXT: addi sp, sp, -16
447446
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
448447
; RV32I-NEXT: call __gedf2
449-
; RV32I-NEXT: slti a0, a0, 0
448+
; RV32I-NEXT: srli a0, a0, 31
450449
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
451450
; RV32I-NEXT: addi sp, sp, 16
452451
; RV32I-NEXT: ret
@@ -456,8 +455,7 @@ define i32 @fcmp_ult(double %a, double %b) nounwind {
456455
; RV64I-NEXT: addi sp, sp, -16
457456
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
458457
; RV64I-NEXT: call __gedf2
459-
; RV64I-NEXT: sext.w a0, a0
460-
; RV64I-NEXT: slti a0, a0, 0
458+
; RV64I-NEXT: srliw a0, a0, 31
461459
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
462460
; RV64I-NEXT: addi sp, sp, 16
463461
; RV64I-NEXT: ret

llvm/test/CodeGen/RISCV/GlobalISel/float-fcmp.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ define i32 @fcmp_olt(float %a, float %b) nounwind {
138138
; RV32I-NEXT: addi sp, sp, -16
139139
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
140140
; RV32I-NEXT: call __ltsf2
141-
; RV32I-NEXT: slti a0, a0, 0
141+
; RV32I-NEXT: srli a0, a0, 31
142142
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
143143
; RV32I-NEXT: addi sp, sp, 16
144144
; RV32I-NEXT: ret
@@ -148,8 +148,7 @@ define i32 @fcmp_olt(float %a, float %b) nounwind {
148148
; RV64I-NEXT: addi sp, sp, -16
149149
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
150150
; RV64I-NEXT: call __ltsf2
151-
; RV64I-NEXT: sext.w a0, a0
152-
; RV64I-NEXT: slti a0, a0, 0
151+
; RV64I-NEXT: srliw a0, a0, 31
153152
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
154153
; RV64I-NEXT: addi sp, sp, 16
155154
; RV64I-NEXT: ret
@@ -431,7 +430,7 @@ define i32 @fcmp_ult(float %a, float %b) nounwind {
431430
; RV32I-NEXT: addi sp, sp, -16
432431
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
433432
; RV32I-NEXT: call __gesf2
434-
; RV32I-NEXT: slti a0, a0, 0
433+
; RV32I-NEXT: srli a0, a0, 31
435434
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
436435
; RV32I-NEXT: addi sp, sp, 16
437436
; RV32I-NEXT: ret
@@ -441,8 +440,7 @@ define i32 @fcmp_ult(float %a, float %b) nounwind {
441440
; RV64I-NEXT: addi sp, sp, -16
442441
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
443442
; RV64I-NEXT: call __gesf2
444-
; RV64I-NEXT: sext.w a0, a0
445-
; RV64I-NEXT: slti a0, a0, 0
443+
; RV64I-NEXT: srliw a0, a0, 31
446444
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
447445
; RV64I-NEXT: addi sp, sp, 16
448446
; RV64I-NEXT: ret

llvm/test/CodeGen/RISCV/alu64.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ define i64 @slti(i64 %a) nounwind {
3737
; RV32I: # %bb.0:
3838
; RV32I-NEXT: beqz a1, .LBB1_2
3939
; RV32I-NEXT: # %bb.1:
40-
; RV32I-NEXT: slti a0, a1, 0
40+
; RV32I-NEXT: srli a0, a1, 31
4141
; RV32I-NEXT: li a1, 0
4242
; RV32I-NEXT: ret
4343
; RV32I-NEXT: .LBB1_2:

llvm/test/CodeGen/RISCV/arith-with-overflow.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ define i1 @sadd(i32 %a, i32 %b, ptr %c) nounwind {
1212
; RV32I: # %bb.0: # %entry
1313
; RV32I-NEXT: add a3, a0, a1
1414
; RV32I-NEXT: slt a0, a3, a0
15-
; RV32I-NEXT: slti a1, a1, 0
15+
; RV32I-NEXT: srli a1, a1, 31
1616
; RV32I-NEXT: xor a0, a1, a0
1717
; RV32I-NEXT: sw a3, 0(a2)
1818
; RV32I-NEXT: ret

llvm/test/CodeGen/RISCV/bittest.ll

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,14 @@ define i64 @bittest_31_i64(i64 %a) nounwind {
187187
;
188188
; RV64ZBS-LABEL: bittest_31_i64:
189189
; RV64ZBS: # %bb.0:
190-
; RV64ZBS-NEXT: not a0, a0
191-
; RV64ZBS-NEXT: bexti a0, a0, 31
190+
; RV64ZBS-NEXT: srliw a0, a0, 31
191+
; RV64ZBS-NEXT: xori a0, a0, 1
192192
; RV64ZBS-NEXT: ret
193193
;
194194
; RV64XTHEADBS-LABEL: bittest_31_i64:
195195
; RV64XTHEADBS: # %bb.0:
196-
; RV64XTHEADBS-NEXT: not a0, a0
197-
; RV64XTHEADBS-NEXT: th.tst a0, a0, 31
196+
; RV64XTHEADBS-NEXT: srliw a0, a0, 31
197+
; RV64XTHEADBS-NEXT: xori a0, a0, 1
198198
; RV64XTHEADBS-NEXT: ret
199199
%shr = lshr i64 %a, 31
200200
%not = xor i64 %shr, -1
@@ -3507,3 +3507,77 @@ define void @bit_64_1_nz_branch_i64(i64 %0) {
35073507
5:
35083508
ret void
35093509
}
3510+
3511+
define i32 @bittest_31_andeq0_i64(i64 %x) {
3512+
; RV32-LABEL: bittest_31_andeq0_i64:
3513+
; RV32: # %bb.0:
3514+
; RV32-NEXT: srli a0, a0, 31
3515+
; RV32-NEXT: xori a0, a0, 1
3516+
; RV32-NEXT: ret
3517+
;
3518+
; RV64-LABEL: bittest_31_andeq0_i64:
3519+
; RV64: # %bb.0:
3520+
; RV64-NEXT: srliw a0, a0, 31
3521+
; RV64-NEXT: xori a0, a0, 1
3522+
; RV64-NEXT: ret
3523+
%and = and i64 %x, 2147483648
3524+
%cmp = icmp eq i64 %and, 0
3525+
%conv = zext i1 %cmp to i32
3526+
ret i32 %conv
3527+
}
3528+
3529+
define i32 @bittest_63_andeq0_i64(i64 %x) {
3530+
; RV32-LABEL: bittest_63_andeq0_i64:
3531+
; RV32: # %bb.0:
3532+
; RV32-NEXT: srli a1, a1, 31
3533+
; RV32-NEXT: xori a0, a1, 1
3534+
; RV32-NEXT: ret
3535+
;
3536+
; RV64-LABEL: bittest_63_andeq0_i64:
3537+
; RV64: # %bb.0:
3538+
; RV64-NEXT: srli a0, a0, 63
3539+
; RV64-NEXT: xori a0, a0, 1
3540+
; RV64-NEXT: ret
3541+
%and = and i64 %x, 9223372036854775808
3542+
%cmp = icmp eq i64 %and, 0
3543+
%conv = zext i1 %cmp to i32
3544+
ret i32 %conv
3545+
}
3546+
3547+
define i32 @bittest_31_slt0_i32(i32 %x, i1 %y) {
3548+
; RV32-LABEL: bittest_31_slt0_i32:
3549+
; RV32: # %bb.0:
3550+
; RV32-NEXT: srli a0, a0, 31
3551+
; RV32-NEXT: and a0, a0, a1
3552+
; RV32-NEXT: ret
3553+
;
3554+
; RV64-LABEL: bittest_31_slt0_i32:
3555+
; RV64: # %bb.0:
3556+
; RV64-NEXT: srliw a0, a0, 31
3557+
; RV64-NEXT: and a0, a0, a1
3558+
; RV64-NEXT: ret
3559+
%cmp = icmp slt i32 %x, 0
3560+
%and = and i1 %cmp, %y
3561+
%ext = zext i1 %and to i32
3562+
ret i32 %ext
3563+
}
3564+
3565+
define i32 @bittest_63_slt0_i64(i32 %x, i1 %y) {
3566+
; RV32-LABEL: bittest_63_slt0_i64:
3567+
; RV32: # %bb.0:
3568+
; RV32-NEXT: srai a0, a0, 31
3569+
; RV32-NEXT: srli a0, a0, 31
3570+
; RV32-NEXT: and a0, a0, a1
3571+
; RV32-NEXT: ret
3572+
;
3573+
; RV64-LABEL: bittest_63_slt0_i64:
3574+
; RV64: # %bb.0:
3575+
; RV64-NEXT: srliw a0, a0, 31
3576+
; RV64-NEXT: and a0, a0, a1
3577+
; RV64-NEXT: ret
3578+
%ext = sext i32 %x to i64
3579+
%cmp = icmp slt i64 %ext, 0
3580+
%and = and i1 %cmp, %y
3581+
%cond = zext i1 %and to i32
3582+
ret i32 %cond
3583+
}

llvm/test/CodeGen/RISCV/condbinops.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ define i64 @shl64(i64 %x, i64 %y, i1 %c) {
459459
; RV32ZICOND-NEXT: addi a4, a2, -32
460460
; RV32ZICOND-NEXT: sll a1, a1, a2
461461
; RV32ZICOND-NEXT: not a2, a2
462-
; RV32ZICOND-NEXT: slti a4, a4, 0
462+
; RV32ZICOND-NEXT: srli a4, a4, 31
463463
; RV32ZICOND-NEXT: srl a2, a3, a2
464464
; RV32ZICOND-NEXT: czero.nez a3, a0, a4
465465
; RV32ZICOND-NEXT: or a1, a1, a2
@@ -534,7 +534,7 @@ define i64 @ashr64(i64 %x, i64 %y, i1 %c) {
534534
; RV32ZICOND-NEXT: addi a4, a2, -32
535535
; RV32ZICOND-NEXT: srl a0, a0, a2
536536
; RV32ZICOND-NEXT: not a2, a2
537-
; RV32ZICOND-NEXT: slti a4, a4, 0
537+
; RV32ZICOND-NEXT: srli a4, a4, 31
538538
; RV32ZICOND-NEXT: sll a2, a3, a2
539539
; RV32ZICOND-NEXT: czero.nez a3, a1, a4
540540
; RV32ZICOND-NEXT: or a0, a0, a2
@@ -610,7 +610,7 @@ define i64 @lshr64(i64 %x, i64 %y, i1 %c) {
610610
; RV32ZICOND-NEXT: addi a4, a2, -32
611611
; RV32ZICOND-NEXT: srl a0, a0, a2
612612
; RV32ZICOND-NEXT: not a2, a2
613-
; RV32ZICOND-NEXT: slti a4, a4, 0
613+
; RV32ZICOND-NEXT: srli a4, a4, 31
614614
; RV32ZICOND-NEXT: sll a2, a3, a2
615615
; RV32ZICOND-NEXT: czero.nez a3, a1, a4
616616
; RV32ZICOND-NEXT: or a0, a0, a2

llvm/test/CodeGen/RISCV/double-convert.ll

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ define i32 @fcvt_wu_d_sat(double %a) nounwind {
405405
; RV32I-NEXT: li a2, 0
406406
; RV32I-NEXT: li a3, 0
407407
; RV32I-NEXT: call __gedf2
408-
; RV32I-NEXT: slti a0, a0, 0
408+
; RV32I-NEXT: srli a0, a0, 31
409409
; RV32I-NEXT: addi s3, a0, -1
410410
; RV32I-NEXT: mv a0, s1
411411
; RV32I-NEXT: mv a1, s0
@@ -446,8 +446,8 @@ define i32 @fcvt_wu_d_sat(double %a) nounwind {
446446
; RV64I-NEXT: srli a0, a0, 32
447447
; RV64I-NEXT: j .LBB6_3
448448
; RV64I-NEXT: .LBB6_2:
449-
; RV64I-NEXT: slti a0, s0, 0
450-
; RV64I-NEXT: addi a0, a0, -1
449+
; RV64I-NEXT: srli s0, s0, 63
450+
; RV64I-NEXT: addi a0, s0, -1
451451
; RV64I-NEXT: and a0, a0, s1
452452
; RV64I-NEXT: .LBB6_3: # %start
453453
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
@@ -819,7 +819,7 @@ define i64 @fcvt_l_d_sat(double %a) nounwind {
819819
; RV32I-NEXT: mv a3, s0
820820
; RV32I-NEXT: call __unorddf2
821821
; RV32I-NEXT: snez a0, a0
822-
; RV32I-NEXT: slti a1, s4, 0
822+
; RV32I-NEXT: srli a1, s4, 31
823823
; RV32I-NEXT: sgtz a2, s2
824824
; RV32I-NEXT: addi a0, a0, -1
825825
; RV32I-NEXT: addi a3, a1, -1
@@ -1029,7 +1029,7 @@ define i64 @fcvt_lu_d_sat(double %a) nounwind {
10291029
; RV32I-NEXT: li a2, 0
10301030
; RV32I-NEXT: li a3, 0
10311031
; RV32I-NEXT: call __gedf2
1032-
; RV32I-NEXT: slti a0, a0, 0
1032+
; RV32I-NEXT: srli a0, a0, 31
10331033
; RV32I-NEXT: addi s3, a0, -1
10341034
; RV32I-NEXT: mv a0, s1
10351035
; RV32I-NEXT: mv a1, s0
@@ -1055,7 +1055,7 @@ define i64 @fcvt_lu_d_sat(double %a) nounwind {
10551055
; RV64I-NEXT: mv s0, a0
10561056
; RV64I-NEXT: li a1, 0
10571057
; RV64I-NEXT: call __gedf2
1058-
; RV64I-NEXT: slti a0, a0, 0
1058+
; RV64I-NEXT: srli a0, a0, 63
10591059
; RV64I-NEXT: addi s1, a0, -1
10601060
; RV64I-NEXT: mv a0, s0
10611061
; RV64I-NEXT: call __fixunsdfdi
@@ -1898,9 +1898,9 @@ define zeroext i16 @fcvt_wu_s_sat_i16(double %a) nounwind {
18981898
; RV32I-NEXT: mv a0, a1
18991899
; RV32I-NEXT: j .LBB28_3
19001900
; RV32I-NEXT: .LBB28_2:
1901-
; RV32I-NEXT: slti a2, s0, 0
1902-
; RV32I-NEXT: addi a2, a2, -1
1903-
; RV32I-NEXT: and a0, a2, a0
1901+
; RV32I-NEXT: srli s0, s0, 31
1902+
; RV32I-NEXT: addi s0, s0, -1
1903+
; RV32I-NEXT: and a0, s0, a0
19041904
; RV32I-NEXT: .LBB28_3: # %start
19051905
; RV32I-NEXT: and a0, a0, a1
19061906
; 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 {
19371937
; RV64I-NEXT: mv a0, a1
19381938
; RV64I-NEXT: j .LBB28_3
19391939
; RV64I-NEXT: .LBB28_2:
1940-
; RV64I-NEXT: slti a0, s0, 0
1941-
; RV64I-NEXT: addi a0, a0, -1
1940+
; RV64I-NEXT: srli s0, s0, 63
1941+
; RV64I-NEXT: addi a0, s0, -1
19421942
; RV64I-NEXT: and a0, a0, s1
19431943
; RV64I-NEXT: .LBB28_3: # %start
19441944
; RV64I-NEXT: and a0, a0, a1
@@ -2271,9 +2271,9 @@ define zeroext i8 @fcvt_wu_s_sat_i8(double %a) nounwind {
22712271
; RV32I-NEXT: li a0, 255
22722272
; RV32I-NEXT: j .LBB32_3
22732273
; RV32I-NEXT: .LBB32_2:
2274-
; RV32I-NEXT: slti a1, s0, 0
2275-
; RV32I-NEXT: addi a1, a1, -1
2276-
; RV32I-NEXT: and a0, a1, a0
2274+
; RV32I-NEXT: srli s0, s0, 31
2275+
; RV32I-NEXT: addi s0, s0, -1
2276+
; RV32I-NEXT: and a0, s0, a0
22772277
; RV32I-NEXT: .LBB32_3: # %start
22782278
; RV32I-NEXT: zext.b a0, a0
22792279
; 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 {
23072307
; RV64I-NEXT: li a0, 255
23082308
; RV64I-NEXT: j .LBB32_3
23092309
; RV64I-NEXT: .LBB32_2:
2310-
; RV64I-NEXT: slti a0, s0, 0
2311-
; RV64I-NEXT: addi a0, a0, -1
2310+
; RV64I-NEXT: srli s0, s0, 63
2311+
; RV64I-NEXT: addi a0, s0, -1
23122312
; RV64I-NEXT: and a0, a0, s1
23132313
; RV64I-NEXT: .LBB32_3: # %start
23142314
; RV64I-NEXT: zext.b a0, a0
@@ -2386,7 +2386,7 @@ define zeroext i32 @fcvt_wu_d_sat_zext(double %a) nounwind {
23862386
; RV32I-NEXT: li a2, 0
23872387
; RV32I-NEXT: li a3, 0
23882388
; RV32I-NEXT: call __gedf2
2389-
; RV32I-NEXT: slti a0, a0, 0
2389+
; RV32I-NEXT: srli a0, a0, 31
23902390
; RV32I-NEXT: addi s3, a0, -1
23912391
; RV32I-NEXT: mv a0, s1
23922392
; RV32I-NEXT: mv a1, s0
@@ -2427,8 +2427,8 @@ define zeroext i32 @fcvt_wu_d_sat_zext(double %a) nounwind {
24272427
; RV64I-NEXT: srli a0, a0, 32
24282428
; RV64I-NEXT: j .LBB33_3
24292429
; RV64I-NEXT: .LBB33_2:
2430-
; RV64I-NEXT: slti a0, s0, 0
2431-
; RV64I-NEXT: addi a0, a0, -1
2430+
; RV64I-NEXT: srli s0, s0, 63
2431+
; RV64I-NEXT: addi a0, s0, -1
24322432
; RV64I-NEXT: and a0, a0, s1
24332433
; RV64I-NEXT: .LBB33_3: # %start
24342434
; RV64I-NEXT: slli a0, a0, 32

0 commit comments

Comments
 (0)