Skip to content

Commit 2c9e2e9

Browse files
authored
[RISCV][ISel] Eliminate andi rd, rs1, -1 instructions (llvm#89976)
Inspired by llvm#89966, this patch handles the special case `binop_allwusers<and> GPR:$rs1, 0xffffffff -> copy $rs1` to avoid creating redundant `andi rd, rs1, -1` instructions.
1 parent 42070a5 commit 2c9e2e9

File tree

8 files changed

+146
-275
lines changed

8 files changed

+146
-275
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,6 +1813,8 @@ def : Pat<(binop_allwusers<srl> (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
18131813

18141814
// Use binop_allwusers to recover immediates that may have been broken by
18151815
// SimplifyDemandedBits.
1816+
def : Pat<(binop_allwusers<and> GPR:$rs1, 0xffffffff),
1817+
(COPY GPR:$rs1)>;
18161818
def : Pat<(binop_allwusers<and> GPR:$rs1, u32simm12:$imm),
18171819
(ANDI GPR:$rs1, u32simm12:$imm)>;
18181820

llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,6 @@ define i64 @zext_mul288(i32 signext %a) {
634634
}
635635

636636
; We can't use slli.uw becaues the shift amount is more than 31.
637-
; FIXME: The zext.w is unneeded.
638637
define i64 @zext_mul12884901888(i32 signext %a) {
639638
; RV64I-LABEL: zext_mul12884901888:
640639
; RV64I: # %bb.0:
@@ -647,7 +646,6 @@ define i64 @zext_mul12884901888(i32 signext %a) {
647646
;
648647
; RV64ZBA-LABEL: zext_mul12884901888:
649648
; RV64ZBA: # %bb.0:
650-
; RV64ZBA-NEXT: andi a0, a0, -1
651649
; RV64ZBA-NEXT: sh1add a0, a0, a0
652650
; RV64ZBA-NEXT: slli a0, a0, 32
653651
; RV64ZBA-NEXT: ret
@@ -657,7 +655,6 @@ define i64 @zext_mul12884901888(i32 signext %a) {
657655
}
658656

659657
; We can't use slli.uw becaues the shift amount is more than 31.
660-
; FIXME: The zext.w is unneeded.
661658
define i64 @zext_mul21474836480(i32 signext %a) {
662659
; RV64I-LABEL: zext_mul21474836480:
663660
; RV64I: # %bb.0:
@@ -670,7 +667,6 @@ define i64 @zext_mul21474836480(i32 signext %a) {
670667
;
671668
; RV64ZBA-LABEL: zext_mul21474836480:
672669
; RV64ZBA: # %bb.0:
673-
; RV64ZBA-NEXT: andi a0, a0, -1
674670
; RV64ZBA-NEXT: sh2add a0, a0, a0
675671
; RV64ZBA-NEXT: slli a0, a0, 32
676672
; RV64ZBA-NEXT: ret
@@ -680,7 +676,6 @@ define i64 @zext_mul21474836480(i32 signext %a) {
680676
}
681677

682678
; We can't use slli.uw becaues the shift amount is more than 31.
683-
; FIXME: The zext.w is unneeded.
684679
define i64 @zext_mul38654705664(i32 signext %a) {
685680
; RV64I-LABEL: zext_mul38654705664:
686681
; RV64I: # %bb.0:
@@ -693,7 +688,6 @@ define i64 @zext_mul38654705664(i32 signext %a) {
693688
;
694689
; RV64ZBA-LABEL: zext_mul38654705664:
695690
; RV64ZBA: # %bb.0:
696-
; RV64ZBA-NEXT: andi a0, a0, -1
697691
; RV64ZBA-NEXT: sh3add a0, a0, a0
698692
; RV64ZBA-NEXT: slli a0, a0, 32
699693
; RV64ZBA-NEXT: ret

llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbb-zbkb.ll

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,10 @@ declare i32 @llvm.fshl.i32(i32, i32, i32)
102102
define signext i32 @rol_i32(i32 signext %a, i32 signext %b) nounwind {
103103
; RV64I-LABEL: rol_i32:
104104
; RV64I: # %bb.0:
105-
; RV64I-NEXT: andi a2, a1, -1
106-
; RV64I-NEXT: sllw a1, a0, a1
107-
; RV64I-NEXT: negw a2, a2
108-
; RV64I-NEXT: srlw a0, a0, a2
109-
; RV64I-NEXT: or a0, a1, a0
105+
; RV64I-NEXT: sllw a2, a0, a1
106+
; RV64I-NEXT: negw a1, a1
107+
; RV64I-NEXT: srlw a0, a0, a1
108+
; RV64I-NEXT: or a0, a2, a0
110109
; RV64I-NEXT: ret
111110
;
112111
; RV64ZBB-ZBKB-LABEL: rol_i32:
@@ -121,11 +120,10 @@ define signext i32 @rol_i32(i32 signext %a, i32 signext %b) nounwind {
121120
define void @rol_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind {
122121
; RV64I-LABEL: rol_i32_nosext:
123122
; RV64I: # %bb.0:
124-
; RV64I-NEXT: andi a3, a1, -1
125-
; RV64I-NEXT: sllw a1, a0, a1
126-
; RV64I-NEXT: negw a3, a3
127-
; RV64I-NEXT: srlw a0, a0, a3
128-
; RV64I-NEXT: or a0, a1, a0
123+
; RV64I-NEXT: sllw a3, a0, a1
124+
; RV64I-NEXT: negw a1, a1
125+
; RV64I-NEXT: srlw a0, a0, a1
126+
; RV64I-NEXT: or a0, a3, a0
129127
; RV64I-NEXT: sw a0, 0(a2)
130128
; RV64I-NEXT: ret
131129
;
@@ -142,12 +140,11 @@ define void @rol_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind {
142140
define signext i32 @rol_i32_neg_constant_rhs(i32 signext %a) nounwind {
143141
; RV64I-LABEL: rol_i32_neg_constant_rhs:
144142
; RV64I: # %bb.0:
145-
; RV64I-NEXT: andi a1, a0, -1
146-
; RV64I-NEXT: li a2, -2
147-
; RV64I-NEXT: sllw a0, a2, a0
148-
; RV64I-NEXT: negw a1, a1
149-
; RV64I-NEXT: srlw a1, a2, a1
150-
; RV64I-NEXT: or a0, a0, a1
143+
; RV64I-NEXT: li a1, -2
144+
; RV64I-NEXT: sllw a2, a1, a0
145+
; RV64I-NEXT: negw a0, a0
146+
; RV64I-NEXT: srlw a0, a1, a0
147+
; RV64I-NEXT: or a0, a2, a0
151148
; RV64I-NEXT: ret
152149
;
153150
; RV64ZBB-ZBKB-LABEL: rol_i32_neg_constant_rhs:
@@ -183,11 +180,10 @@ declare i32 @llvm.fshr.i32(i32, i32, i32)
183180
define signext i32 @ror_i32(i32 signext %a, i32 signext %b) nounwind {
184181
; RV64I-LABEL: ror_i32:
185182
; RV64I: # %bb.0:
186-
; RV64I-NEXT: andi a2, a1, -1
187-
; RV64I-NEXT: srlw a1, a0, a1
188-
; RV64I-NEXT: negw a2, a2
189-
; RV64I-NEXT: sllw a0, a0, a2
190-
; RV64I-NEXT: or a0, a1, a0
183+
; RV64I-NEXT: srlw a2, a0, a1
184+
; RV64I-NEXT: negw a1, a1
185+
; RV64I-NEXT: sllw a0, a0, a1
186+
; RV64I-NEXT: or a0, a2, a0
191187
; RV64I-NEXT: ret
192188
;
193189
; RV64ZBB-ZBKB-LABEL: ror_i32:
@@ -202,11 +198,10 @@ define signext i32 @ror_i32(i32 signext %a, i32 signext %b) nounwind {
202198
define void @ror_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind {
203199
; RV64I-LABEL: ror_i32_nosext:
204200
; RV64I: # %bb.0:
205-
; RV64I-NEXT: andi a3, a1, -1
206-
; RV64I-NEXT: srlw a1, a0, a1
207-
; RV64I-NEXT: negw a3, a3
208-
; RV64I-NEXT: sllw a0, a0, a3
209-
; RV64I-NEXT: or a0, a1, a0
201+
; RV64I-NEXT: srlw a3, a0, a1
202+
; RV64I-NEXT: negw a1, a1
203+
; RV64I-NEXT: sllw a0, a0, a1
204+
; RV64I-NEXT: or a0, a3, a0
210205
; RV64I-NEXT: sw a0, 0(a2)
211206
; RV64I-NEXT: ret
212207
;
@@ -223,12 +218,11 @@ define void @ror_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind {
223218
define signext i32 @ror_i32_neg_constant_rhs(i32 signext %a) nounwind {
224219
; RV64I-LABEL: ror_i32_neg_constant_rhs:
225220
; RV64I: # %bb.0:
226-
; RV64I-NEXT: andi a1, a0, -1
227-
; RV64I-NEXT: li a2, -2
228-
; RV64I-NEXT: srlw a0, a2, a0
229-
; RV64I-NEXT: negw a1, a1
230-
; RV64I-NEXT: sllw a1, a2, a1
231-
; RV64I-NEXT: or a0, a0, a1
221+
; RV64I-NEXT: li a1, -2
222+
; RV64I-NEXT: srlw a2, a1, a0
223+
; RV64I-NEXT: negw a0, a0
224+
; RV64I-NEXT: sllw a0, a1, a0
225+
; RV64I-NEXT: or a0, a2, a0
232226
; RV64I-NEXT: ret
233227
;
234228
; RV64ZBB-ZBKB-LABEL: ror_i32_neg_constant_rhs:

llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,17 @@ entry:
192192
%or = or i32 %and, 255
193193
ret i32 %or
194194
}
195+
196+
define i64 @and_allones(i32 signext %x) {
197+
; CHECK-LABEL: and_allones:
198+
; CHECK: # %bb.0: # %entry
199+
; CHECK-NEXT: addi a0, a0, -1
200+
; CHECK-NEXT: li a1, 1
201+
; CHECK-NEXT: sll a0, a1, a0
202+
; CHECK-NEXT: ret
203+
entry:
204+
%y = zext i32 %x to i64
205+
%shamt = add nsw i64 %y, -1
206+
%ret = shl i64 1, %shamt
207+
ret i64 %ret
208+
}

llvm/test/CodeGen/RISCV/rv64zba.ll

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,6 @@ define i64 @zext_mul288(i32 signext %a) {
851851
}
852852

853853
; We can't use slli.uw becaues the shift amount is more than 31.
854-
; FIXME: The zext.w is unneeded.
855854
define i64 @zext_mul12884901888(i32 signext %a) {
856855
; RV64I-LABEL: zext_mul12884901888:
857856
; RV64I: # %bb.0:
@@ -864,7 +863,6 @@ define i64 @zext_mul12884901888(i32 signext %a) {
864863
;
865864
; RV64ZBA-LABEL: zext_mul12884901888:
866865
; RV64ZBA: # %bb.0:
867-
; RV64ZBA-NEXT: andi a0, a0, -1
868866
; RV64ZBA-NEXT: sh1add a0, a0, a0
869867
; RV64ZBA-NEXT: slli a0, a0, 32
870868
; RV64ZBA-NEXT: ret
@@ -874,7 +872,6 @@ define i64 @zext_mul12884901888(i32 signext %a) {
874872
}
875873

876874
; We can't use slli.uw becaues the shift amount is more than 31.
877-
; FIXME: The zext.w is unneeded.
878875
define i64 @zext_mul21474836480(i32 signext %a) {
879876
; RV64I-LABEL: zext_mul21474836480:
880877
; RV64I: # %bb.0:
@@ -887,7 +884,6 @@ define i64 @zext_mul21474836480(i32 signext %a) {
887884
;
888885
; RV64ZBA-LABEL: zext_mul21474836480:
889886
; RV64ZBA: # %bb.0:
890-
; RV64ZBA-NEXT: andi a0, a0, -1
891887
; RV64ZBA-NEXT: sh2add a0, a0, a0
892888
; RV64ZBA-NEXT: slli a0, a0, 32
893889
; RV64ZBA-NEXT: ret
@@ -897,7 +893,6 @@ define i64 @zext_mul21474836480(i32 signext %a) {
897893
}
898894

899895
; We can't use slli.uw becaues the shift amount is more than 31.
900-
; FIXME: The zext.w is unneeded.
901896
define i64 @zext_mul38654705664(i32 signext %a) {
902897
; RV64I-LABEL: zext_mul38654705664:
903898
; RV64I: # %bb.0:
@@ -910,7 +905,6 @@ define i64 @zext_mul38654705664(i32 signext %a) {
910905
;
911906
; RV64ZBA-LABEL: zext_mul38654705664:
912907
; RV64ZBA: # %bb.0:
913-
; RV64ZBA-NEXT: andi a0, a0, -1
914908
; RV64ZBA-NEXT: sh3add a0, a0, a0
915909
; RV64ZBA-NEXT: slli a0, a0, 32
916910
; RV64ZBA-NEXT: ret

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int-vp.ll

Lines changed: 32 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -574,24 +574,14 @@ define signext i32 @vpreduce_add_v2i32(i32 signext %s, <2 x i32> %v, <2 x i1> %m
574574
declare i32 @llvm.vp.reduce.umax.v2i32(i32, <2 x i32>, <2 x i1>, i32)
575575

576576
define signext i32 @vpreduce_umax_v2i32(i32 signext %s, <2 x i32> %v, <2 x i1> %m, i32 zeroext %evl) {
577-
; RV32-LABEL: vpreduce_umax_v2i32:
578-
; RV32: # %bb.0:
579-
; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma
580-
; RV32-NEXT: vmv.s.x v9, a0
581-
; RV32-NEXT: vsetvli zero, a1, e32, mf2, ta, ma
582-
; RV32-NEXT: vredmaxu.vs v9, v8, v9, v0.t
583-
; RV32-NEXT: vmv.x.s a0, v9
584-
; RV32-NEXT: ret
585-
;
586-
; RV64-LABEL: vpreduce_umax_v2i32:
587-
; RV64: # %bb.0:
588-
; RV64-NEXT: andi a0, a0, -1
589-
; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma
590-
; RV64-NEXT: vmv.s.x v9, a0
591-
; RV64-NEXT: vsetvli zero, a1, e32, mf2, ta, ma
592-
; RV64-NEXT: vredmaxu.vs v9, v8, v9, v0.t
593-
; RV64-NEXT: vmv.x.s a0, v9
594-
; RV64-NEXT: ret
577+
; CHECK-LABEL: vpreduce_umax_v2i32:
578+
; CHECK: # %bb.0:
579+
; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma
580+
; CHECK-NEXT: vmv.s.x v9, a0
581+
; CHECK-NEXT: vsetvli zero, a1, e32, mf2, ta, ma
582+
; CHECK-NEXT: vredmaxu.vs v9, v8, v9, v0.t
583+
; CHECK-NEXT: vmv.x.s a0, v9
584+
; CHECK-NEXT: ret
595585
%r = call i32 @llvm.vp.reduce.umax.v2i32(i32 %s, <2 x i32> %v, <2 x i1> %m, i32 %evl)
596586
ret i32 %r
597587
}
@@ -614,24 +604,14 @@ define signext i32 @vpreduce_smax_v2i32(i32 signext %s, <2 x i32> %v, <2 x i1> %
614604
declare i32 @llvm.vp.reduce.umin.v2i32(i32, <2 x i32>, <2 x i1>, i32)
615605

616606
define signext i32 @vpreduce_umin_v2i32(i32 signext %s, <2 x i32> %v, <2 x i1> %m, i32 zeroext %evl) {
617-
; RV32-LABEL: vpreduce_umin_v2i32:
618-
; RV32: # %bb.0:
619-
; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma
620-
; RV32-NEXT: vmv.s.x v9, a0
621-
; RV32-NEXT: vsetvli zero, a1, e32, mf2, ta, ma
622-
; RV32-NEXT: vredminu.vs v9, v8, v9, v0.t
623-
; RV32-NEXT: vmv.x.s a0, v9
624-
; RV32-NEXT: ret
625-
;
626-
; RV64-LABEL: vpreduce_umin_v2i32:
627-
; RV64: # %bb.0:
628-
; RV64-NEXT: andi a0, a0, -1
629-
; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma
630-
; RV64-NEXT: vmv.s.x v9, a0
631-
; RV64-NEXT: vsetvli zero, a1, e32, mf2, ta, ma
632-
; RV64-NEXT: vredminu.vs v9, v8, v9, v0.t
633-
; RV64-NEXT: vmv.x.s a0, v9
634-
; RV64-NEXT: ret
607+
; CHECK-LABEL: vpreduce_umin_v2i32:
608+
; CHECK: # %bb.0:
609+
; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma
610+
; CHECK-NEXT: vmv.s.x v9, a0
611+
; CHECK-NEXT: vsetvli zero, a1, e32, mf2, ta, ma
612+
; CHECK-NEXT: vredminu.vs v9, v8, v9, v0.t
613+
; CHECK-NEXT: vmv.x.s a0, v9
614+
; CHECK-NEXT: ret
635615
%r = call i32 @llvm.vp.reduce.umin.v2i32(i32 %s, <2 x i32> %v, <2 x i1> %m, i32 %evl)
636616
ret i32 %r
637617
}
@@ -714,24 +694,14 @@ define signext i32 @vpreduce_add_v4i32(i32 signext %s, <4 x i32> %v, <4 x i1> %m
714694
declare i32 @llvm.vp.reduce.umax.v4i32(i32, <4 x i32>, <4 x i1>, i32)
715695

716696
define signext i32 @vpreduce_umax_v4i32(i32 signext %s, <4 x i32> %v, <4 x i1> %m, i32 zeroext %evl) {
717-
; RV32-LABEL: vpreduce_umax_v4i32:
718-
; RV32: # %bb.0:
719-
; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma
720-
; RV32-NEXT: vmv.s.x v9, a0
721-
; RV32-NEXT: vsetvli zero, a1, e32, m1, ta, ma
722-
; RV32-NEXT: vredmaxu.vs v9, v8, v9, v0.t
723-
; RV32-NEXT: vmv.x.s a0, v9
724-
; RV32-NEXT: ret
725-
;
726-
; RV64-LABEL: vpreduce_umax_v4i32:
727-
; RV64: # %bb.0:
728-
; RV64-NEXT: andi a0, a0, -1
729-
; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma
730-
; RV64-NEXT: vmv.s.x v9, a0
731-
; RV64-NEXT: vsetvli zero, a1, e32, m1, ta, ma
732-
; RV64-NEXT: vredmaxu.vs v9, v8, v9, v0.t
733-
; RV64-NEXT: vmv.x.s a0, v9
734-
; RV64-NEXT: ret
697+
; CHECK-LABEL: vpreduce_umax_v4i32:
698+
; CHECK: # %bb.0:
699+
; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma
700+
; CHECK-NEXT: vmv.s.x v9, a0
701+
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
702+
; CHECK-NEXT: vredmaxu.vs v9, v8, v9, v0.t
703+
; CHECK-NEXT: vmv.x.s a0, v9
704+
; CHECK-NEXT: ret
735705
%r = call i32 @llvm.vp.reduce.umax.v4i32(i32 %s, <4 x i32> %v, <4 x i1> %m, i32 %evl)
736706
ret i32 %r
737707
}
@@ -754,24 +724,14 @@ define signext i32 @vpreduce_smax_v4i32(i32 signext %s, <4 x i32> %v, <4 x i1> %
754724
declare i32 @llvm.vp.reduce.umin.v4i32(i32, <4 x i32>, <4 x i1>, i32)
755725

756726
define signext i32 @vpreduce_umin_v4i32(i32 signext %s, <4 x i32> %v, <4 x i1> %m, i32 zeroext %evl) {
757-
; RV32-LABEL: vpreduce_umin_v4i32:
758-
; RV32: # %bb.0:
759-
; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma
760-
; RV32-NEXT: vmv.s.x v9, a0
761-
; RV32-NEXT: vsetvli zero, a1, e32, m1, ta, ma
762-
; RV32-NEXT: vredminu.vs v9, v8, v9, v0.t
763-
; RV32-NEXT: vmv.x.s a0, v9
764-
; RV32-NEXT: ret
765-
;
766-
; RV64-LABEL: vpreduce_umin_v4i32:
767-
; RV64: # %bb.0:
768-
; RV64-NEXT: andi a0, a0, -1
769-
; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma
770-
; RV64-NEXT: vmv.s.x v9, a0
771-
; RV64-NEXT: vsetvli zero, a1, e32, m1, ta, ma
772-
; RV64-NEXT: vredminu.vs v9, v8, v9, v0.t
773-
; RV64-NEXT: vmv.x.s a0, v9
774-
; RV64-NEXT: ret
727+
; CHECK-LABEL: vpreduce_umin_v4i32:
728+
; CHECK: # %bb.0:
729+
; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma
730+
; CHECK-NEXT: vmv.s.x v9, a0
731+
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
732+
; CHECK-NEXT: vredminu.vs v9, v8, v9, v0.t
733+
; CHECK-NEXT: vmv.x.s a0, v9
734+
; CHECK-NEXT: ret
775735
%r = call i32 @llvm.vp.reduce.umin.v4i32(i32 %s, <4 x i32> %v, <4 x i1> %m, i32 %evl)
776736
ret i32 %r
777737
}

0 commit comments

Comments
 (0)