Skip to content

Commit 7bc4e88

Browse files
committed
[RISCV] Improve instruction selection for most significant bit extraction
(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 2b8753b commit 7bc4e88

39 files changed

+479
-506
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: 28 additions & 70 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
@@ -3509,75 +3509,35 @@ define void @bit_64_1_nz_branch_i64(i64 %0) {
35093509
}
35103510

35113511
define i32 @bittest_31_andeq0_i64(i64 %x) {
3512-
; RV32I-LABEL: bittest_31_andeq0_i64:
3513-
; RV32I: # %bb.0:
3514-
; RV32I-NEXT: lui a1, 524288
3515-
; RV32I-NEXT: and a0, a0, a1
3516-
; RV32I-NEXT: seqz a0, a0
3517-
; RV32I-NEXT: ret
3518-
;
3519-
; RV64I-LABEL: bittest_31_andeq0_i64:
3520-
; RV64I: # %bb.0:
3521-
; RV64I-NEXT: srliw a0, a0, 31
3522-
; RV64I-NEXT: slli a0, a0, 31
3523-
; RV64I-NEXT: seqz a0, a0
3524-
; RV64I-NEXT: ret
3525-
;
3526-
; ZBS-LABEL: bittest_31_andeq0_i64:
3527-
; ZBS: # %bb.0:
3528-
; ZBS-NEXT: not a0, a0
3529-
; ZBS-NEXT: bexti a0, a0, 31
3530-
; ZBS-NEXT: ret
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
35313517
;
3532-
; XTHEADBS-LABEL: bittest_31_andeq0_i64:
3533-
; XTHEADBS: # %bb.0:
3534-
; XTHEADBS-NEXT: not a0, a0
3535-
; XTHEADBS-NEXT: th.tst a0, a0, 31
3536-
; XTHEADBS-NEXT: ret
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
35373523
%and = and i64 %x, 2147483648
35383524
%cmp = icmp eq i64 %and, 0
35393525
%conv = zext i1 %cmp to i32
35403526
ret i32 %conv
35413527
}
35423528

35433529
define i32 @bittest_63_andeq0_i64(i64 %x) {
3544-
; RV32I-LABEL: bittest_63_andeq0_i64:
3545-
; RV32I: # %bb.0:
3546-
; RV32I-NEXT: lui a0, 524288
3547-
; RV32I-NEXT: and a0, a1, a0
3548-
; RV32I-NEXT: seqz a0, a0
3549-
; RV32I-NEXT: ret
3550-
;
3551-
; RV64I-LABEL: bittest_63_andeq0_i64:
3552-
; RV64I: # %bb.0:
3553-
; RV64I-NEXT: srli a0, a0, 63
3554-
; RV64I-NEXT: slli a0, a0, 63
3555-
; RV64I-NEXT: seqz a0, a0
3556-
; RV64I-NEXT: ret
3557-
;
3558-
; RV32ZBS-LABEL: bittest_63_andeq0_i64:
3559-
; RV32ZBS: # %bb.0:
3560-
; RV32ZBS-NEXT: not a0, a1
3561-
; RV32ZBS-NEXT: bexti a0, a0, 31
3562-
; RV32ZBS-NEXT: ret
3563-
;
3564-
; RV64ZBS-LABEL: bittest_63_andeq0_i64:
3565-
; RV64ZBS: # %bb.0:
3566-
; RV64ZBS-NEXT: not a0, a0
3567-
; RV64ZBS-NEXT: bexti a0, a0, 63
3568-
; RV64ZBS-NEXT: ret
3569-
;
3570-
; RV32XTHEADBS-LABEL: bittest_63_andeq0_i64:
3571-
; RV32XTHEADBS: # %bb.0:
3572-
; RV32XTHEADBS-NEXT: not a0, a1
3573-
; RV32XTHEADBS-NEXT: th.tst a0, a0, 31
3574-
; RV32XTHEADBS-NEXT: ret
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
35753535
;
3576-
; RV64XTHEADBS-LABEL: bittest_63_andeq0_i64:
3577-
; RV64XTHEADBS: # %bb.0:
3578-
; RV64XTHEADBS-NEXT: not a0, a0
3579-
; RV64XTHEADBS-NEXT: th.tst a0, a0, 63
3580-
; RV64XTHEADBS-NEXT: ret
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
35813541
%and = and i64 %x, 9223372036854775808
35823542
%cmp = icmp eq i64 %and, 0
35833543
%conv = zext i1 %cmp to i32
@@ -3587,14 +3547,13 @@ define i32 @bittest_63_andeq0_i64(i64 %x) {
35873547
define i32 @bittest_31_slt0_i32(i32 %x, i1 %y) {
35883548
; RV32-LABEL: bittest_31_slt0_i32:
35893549
; RV32: # %bb.0:
3590-
; RV32-NEXT: slti a0, a0, 0
3550+
; RV32-NEXT: srli a0, a0, 31
35913551
; RV32-NEXT: and a0, a0, a1
35923552
; RV32-NEXT: ret
35933553
;
35943554
; RV64-LABEL: bittest_31_slt0_i32:
35953555
; RV64: # %bb.0:
3596-
; RV64-NEXT: sext.w a0, a0
3597-
; RV64-NEXT: slti a0, a0, 0
3556+
; RV64-NEXT: srliw a0, a0, 31
35983557
; RV64-NEXT: and a0, a0, a1
35993558
; RV64-NEXT: ret
36003559
%cmp = icmp slt i32 %x, 0
@@ -3607,14 +3566,13 @@ define i32 @bittest_63_slt0_i64(i32 %x, i1 %y) {
36073566
; RV32-LABEL: bittest_63_slt0_i64:
36083567
; RV32: # %bb.0:
36093568
; RV32-NEXT: srai a0, a0, 31
3610-
; RV32-NEXT: slti a0, a0, 0
3569+
; RV32-NEXT: srli a0, a0, 31
36113570
; RV32-NEXT: and a0, a0, a1
36123571
; RV32-NEXT: ret
36133572
;
36143573
; RV64-LABEL: bittest_63_slt0_i64:
36153574
; RV64: # %bb.0:
3616-
; RV64-NEXT: sext.w a0, a0
3617-
; RV64-NEXT: slti a0, a0, 0
3575+
; RV64-NEXT: srliw a0, a0, 31
36183576
; RV64-NEXT: and a0, a0, a1
36193577
; RV64-NEXT: ret
36203578
%ext = sext i32 %x to i64

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

0 commit comments

Comments
 (0)