Skip to content

Commit fc69f25

Browse files
authored
[RISCV] Convert LWU to LW if possible in RISCVOptWInstrs (#144703)
After the refactoring in #149710 the logic change is trivial. Motivation for preferring sign-extended 32-bit loads (LW) vs zero-extended (LWU): * LW is compressible while LWU is not. * Helps to minimise the diff vs RV32 (e.g. LWU vs LW) * Helps to minimise distracting diffs vs GCC. I see this come up frequently when comparing GCC code and in these cases it's a red herring. Similar normalisation could be done for LHU and LH, but this is less well motivated as there is a compressed LHU (and if performing the change in RISCVOptWInstrs it wouldn't be done for RV32). There is a compressed LBU but not LB, meaning doing a similar normalisation for byte-sized loads would actually be a regression in terms of code size. Load narrowing when allowed by hasAllNBitUsers isn't explored in this patch. This changes ~20500 instructions in an RVA22 build of the llvm-test-suite including SPEC 2017. As part of the review, the option of doing the change at ISel time was explored but was found to be less effective.
1 parent a11c5dd commit fc69f25

24 files changed

+112
-193
lines changed

llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,8 @@ bool RISCVOptWInstrs::canonicalizeWSuffixes(MachineFunction &MF,
736736
for (MachineInstr &MI : MBB) {
737737
std::optional<unsigned> WOpc;
738738
std::optional<unsigned> NonWOpc;
739-
switch (MI.getOpcode()) {
739+
unsigned OrigOpc = MI.getOpcode();
740+
switch (OrigOpc) {
740741
default:
741742
continue;
742743
case RISCV::ADDW:
@@ -786,7 +787,10 @@ bool RISCVOptWInstrs::canonicalizeWSuffixes(MachineFunction &MF,
786787
MadeChange = true;
787788
continue;
788789
}
789-
if (ShouldPreferW && WOpc.has_value() && hasAllWUsers(MI, ST, MRI)) {
790+
// LWU is always converted to LW when possible as 1) LW is compressible
791+
// and 2) it helps minimise differences vs RV32.
792+
if ((ShouldPreferW || OrigOpc == RISCV::LWU) && WOpc.has_value() &&
793+
hasAllWUsers(MI, ST, MRI)) {
790794
LLVM_DEBUG(dbgs() << "Replacing " << MI);
791795
MI.setDesc(TII.get(WOpc.value()));
792796
MI.clearFlag(MachineInstr::MIFlag::NoSWrap);

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,11 @@ define double @fcvt_d_wu(i32 %a) nounwind {
246246
}
247247

248248
define double @fcvt_d_wu_load(ptr %p) nounwind {
249-
; RV32IFD-LABEL: fcvt_d_wu_load:
250-
; RV32IFD: # %bb.0:
251-
; RV32IFD-NEXT: lw a0, 0(a0)
252-
; RV32IFD-NEXT: fcvt.d.wu fa0, a0
253-
; RV32IFD-NEXT: ret
254-
;
255-
; RV64IFD-LABEL: fcvt_d_wu_load:
256-
; RV64IFD: # %bb.0:
257-
; RV64IFD-NEXT: lwu a0, 0(a0)
258-
; RV64IFD-NEXT: fcvt.d.wu fa0, a0
259-
; RV64IFD-NEXT: ret
249+
; CHECKIFD-LABEL: fcvt_d_wu_load:
250+
; CHECKIFD: # %bb.0:
251+
; CHECKIFD-NEXT: lw a0, 0(a0)
252+
; CHECKIFD-NEXT: fcvt.d.wu fa0, a0
253+
; CHECKIFD-NEXT: ret
260254
;
261255
; RV32I-LABEL: fcvt_d_wu_load:
262256
; RV32I: # %bb.0:

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -232,17 +232,11 @@ define float @fcvt_s_wu(i32 %a) nounwind {
232232
}
233233

234234
define float @fcvt_s_wu_load(ptr %p) nounwind {
235-
; RV32IF-LABEL: fcvt_s_wu_load:
236-
; RV32IF: # %bb.0:
237-
; RV32IF-NEXT: lw a0, 0(a0)
238-
; RV32IF-NEXT: fcvt.s.wu fa0, a0
239-
; RV32IF-NEXT: ret
240-
;
241-
; RV64IF-LABEL: fcvt_s_wu_load:
242-
; RV64IF: # %bb.0:
243-
; RV64IF-NEXT: lwu a0, 0(a0)
244-
; RV64IF-NEXT: fcvt.s.wu fa0, a0
245-
; RV64IF-NEXT: ret
235+
; CHECKIF-LABEL: fcvt_s_wu_load:
236+
; CHECKIF: # %bb.0:
237+
; CHECKIF-NEXT: lw a0, 0(a0)
238+
; CHECKIF-NEXT: fcvt.s.wu fa0, a0
239+
; CHECKIF-NEXT: ret
246240
;
247241
; RV32I-LABEL: fcvt_s_wu_load:
248242
; RV32I: # %bb.0:

llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ define signext i32 @ctpop_i32_load(ptr %p) nounwind {
748748
;
749749
; RV64ZBB-LABEL: ctpop_i32_load:
750750
; RV64ZBB: # %bb.0:
751-
; RV64ZBB-NEXT: lwu a0, 0(a0)
751+
; RV64ZBB-NEXT: lw a0, 0(a0)
752752
; RV64ZBB-NEXT: cpopw a0, a0
753753
; RV64ZBB-NEXT: ret
754754
%a = load i32, ptr %p

llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,16 @@ define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
114114
define i64 @pack_i64_3(ptr %0, ptr %1) {
115115
; RV64I-LABEL: pack_i64_3:
116116
; RV64I: # %bb.0:
117-
; RV64I-NEXT: lwu a0, 0(a0)
117+
; RV64I-NEXT: lw a0, 0(a0)
118118
; RV64I-NEXT: lwu a1, 0(a1)
119119
; RV64I-NEXT: slli a0, a0, 32
120120
; RV64I-NEXT: or a0, a0, a1
121121
; RV64I-NEXT: ret
122122
;
123123
; RV64ZBKB-LABEL: pack_i64_3:
124124
; RV64ZBKB: # %bb.0:
125-
; RV64ZBKB-NEXT: lwu a0, 0(a0)
126-
; RV64ZBKB-NEXT: lwu a1, 0(a1)
125+
; RV64ZBKB-NEXT: lw a0, 0(a0)
126+
; RV64ZBKB-NEXT: lw a1, 0(a1)
127127
; RV64ZBKB-NEXT: pack a0, a1, a0
128128
; RV64ZBKB-NEXT: ret
129129
%3 = load i32, ptr %0, align 4

llvm/test/CodeGen/RISCV/atomic-signext.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4582,7 +4582,7 @@ define signext i32 @atomicrmw_and_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind
45824582
; RV64I-NEXT: sext.w a0, a0
45834583
; RV64I-NEXT: ret
45844584
; RV64I-NEXT: .LBB56_2: # %else
4585-
; RV64I-NEXT: lwu a1, 0(a0)
4585+
; RV64I-NEXT: lw a1, 0(a0)
45864586
; RV64I-NEXT: andi a2, a1, 1
45874587
; RV64I-NEXT: sw a2, 0(a0)
45884588
; RV64I-NEXT: sext.w a0, a1
@@ -4700,7 +4700,7 @@ define signext i32 @atomicrmw_nand_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind
47004700
; RV64I-NEXT: sext.w a0, a0
47014701
; RV64I-NEXT: ret
47024702
; RV64I-NEXT: .LBB57_2: # %else
4703-
; RV64I-NEXT: lwu a1, 0(a0)
4703+
; RV64I-NEXT: lw a1, 0(a0)
47044704
; RV64I-NEXT: andi a2, a1, 1
47054705
; RV64I-NEXT: sw a2, 0(a0)
47064706
; RV64I-NEXT: sext.w a0, a1

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ define bfloat @fcvt_bf16_wu_load(ptr %p) nounwind {
10741074
;
10751075
; CHECK64ZFBFMIN-LABEL: fcvt_bf16_wu_load:
10761076
; CHECK64ZFBFMIN: # %bb.0:
1077-
; CHECK64ZFBFMIN-NEXT: lwu a0, 0(a0)
1077+
; CHECK64ZFBFMIN-NEXT: lw a0, 0(a0)
10781078
; CHECK64ZFBFMIN-NEXT: fcvt.s.wu fa5, a0
10791079
; CHECK64ZFBFMIN-NEXT: fcvt.bf16.s fa0, fa5
10801080
; CHECK64ZFBFMIN-NEXT: ret
@@ -1083,7 +1083,7 @@ define bfloat @fcvt_bf16_wu_load(ptr %p) nounwind {
10831083
; RV64ID: # %bb.0:
10841084
; RV64ID-NEXT: addi sp, sp, -16
10851085
; RV64ID-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1086-
; RV64ID-NEXT: lwu a0, 0(a0)
1086+
; RV64ID-NEXT: lw a0, 0(a0)
10871087
; RV64ID-NEXT: fcvt.s.wu fa0, a0
10881088
; RV64ID-NEXT: call __truncsfbf2
10891089
; RV64ID-NEXT: fmv.x.w a0, fa0

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

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -347,17 +347,11 @@ define double @fcvt_d_wu(i32 %a) nounwind strictfp {
347347
declare double @llvm.experimental.constrained.uitofp.f64.i32(i32, metadata, metadata)
348348

349349
define double @fcvt_d_wu_load(ptr %p) nounwind strictfp {
350-
; RV32IFD-LABEL: fcvt_d_wu_load:
351-
; RV32IFD: # %bb.0:
352-
; RV32IFD-NEXT: lw a0, 0(a0)
353-
; RV32IFD-NEXT: fcvt.d.wu fa0, a0
354-
; RV32IFD-NEXT: ret
355-
;
356-
; RV64IFD-LABEL: fcvt_d_wu_load:
357-
; RV64IFD: # %bb.0:
358-
; RV64IFD-NEXT: lwu a0, 0(a0)
359-
; RV64IFD-NEXT: fcvt.d.wu fa0, a0
360-
; RV64IFD-NEXT: ret
350+
; CHECKIFD-LABEL: fcvt_d_wu_load:
351+
; CHECKIFD: # %bb.0:
352+
; CHECKIFD-NEXT: lw a0, 0(a0)
353+
; CHECKIFD-NEXT: fcvt.d.wu fa0, a0
354+
; CHECKIFD-NEXT: ret
361355
;
362356
; RV32IZFINXZDINX-LABEL: fcvt_d_wu_load:
363357
; RV32IZFINXZDINX: # %bb.0:
@@ -367,7 +361,7 @@ define double @fcvt_d_wu_load(ptr %p) nounwind strictfp {
367361
;
368362
; RV64IZFINXZDINX-LABEL: fcvt_d_wu_load:
369363
; RV64IZFINXZDINX: # %bb.0:
370-
; RV64IZFINXZDINX-NEXT: lwu a0, 0(a0)
364+
; RV64IZFINXZDINX-NEXT: lw a0, 0(a0)
371365
; RV64IZFINXZDINX-NEXT: fcvt.d.wu a0, a0
372366
; RV64IZFINXZDINX-NEXT: ret
373367
;

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

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -582,17 +582,11 @@ define double @fcvt_d_wu(i32 %a) nounwind {
582582
}
583583

584584
define double @fcvt_d_wu_load(ptr %p) nounwind {
585-
; RV32IFD-LABEL: fcvt_d_wu_load:
586-
; RV32IFD: # %bb.0:
587-
; RV32IFD-NEXT: lw a0, 0(a0)
588-
; RV32IFD-NEXT: fcvt.d.wu fa0, a0
589-
; RV32IFD-NEXT: ret
590-
;
591-
; RV64IFD-LABEL: fcvt_d_wu_load:
592-
; RV64IFD: # %bb.0:
593-
; RV64IFD-NEXT: lwu a0, 0(a0)
594-
; RV64IFD-NEXT: fcvt.d.wu fa0, a0
595-
; RV64IFD-NEXT: ret
585+
; CHECKIFD-LABEL: fcvt_d_wu_load:
586+
; CHECKIFD: # %bb.0:
587+
; CHECKIFD-NEXT: lw a0, 0(a0)
588+
; CHECKIFD-NEXT: fcvt.d.wu fa0, a0
589+
; CHECKIFD-NEXT: ret
596590
;
597591
; RV32IZFINXZDINX-LABEL: fcvt_d_wu_load:
598592
; RV32IZFINXZDINX: # %bb.0:
@@ -602,7 +596,7 @@ define double @fcvt_d_wu_load(ptr %p) nounwind {
602596
;
603597
; RV64IZFINXZDINX-LABEL: fcvt_d_wu_load:
604598
; RV64IZFINXZDINX: # %bb.0:
605-
; RV64IZFINXZDINX-NEXT: lwu a0, 0(a0)
599+
; RV64IZFINXZDINX-NEXT: lw a0, 0(a0)
606600
; RV64IZFINXZDINX-NEXT: fcvt.d.wu a0, a0
607601
; RV64IZFINXZDINX-NEXT: ret
608602
;

llvm/test/CodeGen/RISCV/float-convert-strict.ll

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -236,29 +236,17 @@ define float @fcvt_s_wu(i32 %a) nounwind strictfp {
236236
declare float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata, metadata)
237237

238238
define float @fcvt_s_wu_load(ptr %p) nounwind strictfp {
239-
; RV32IF-LABEL: fcvt_s_wu_load:
240-
; RV32IF: # %bb.0:
241-
; RV32IF-NEXT: lw a0, 0(a0)
242-
; RV32IF-NEXT: fcvt.s.wu fa0, a0
243-
; RV32IF-NEXT: ret
244-
;
245-
; RV64IF-LABEL: fcvt_s_wu_load:
246-
; RV64IF: # %bb.0:
247-
; RV64IF-NEXT: lwu a0, 0(a0)
248-
; RV64IF-NEXT: fcvt.s.wu fa0, a0
249-
; RV64IF-NEXT: ret
250-
;
251-
; RV32IZFINX-LABEL: fcvt_s_wu_load:
252-
; RV32IZFINX: # %bb.0:
253-
; RV32IZFINX-NEXT: lw a0, 0(a0)
254-
; RV32IZFINX-NEXT: fcvt.s.wu a0, a0
255-
; RV32IZFINX-NEXT: ret
239+
; CHECKIF-LABEL: fcvt_s_wu_load:
240+
; CHECKIF: # %bb.0:
241+
; CHECKIF-NEXT: lw a0, 0(a0)
242+
; CHECKIF-NEXT: fcvt.s.wu fa0, a0
243+
; CHECKIF-NEXT: ret
256244
;
257-
; RV64IZFINX-LABEL: fcvt_s_wu_load:
258-
; RV64IZFINX: # %bb.0:
259-
; RV64IZFINX-NEXT: lwu a0, 0(a0)
260-
; RV64IZFINX-NEXT: fcvt.s.wu a0, a0
261-
; RV64IZFINX-NEXT: ret
245+
; CHECKIZFINX-LABEL: fcvt_s_wu_load:
246+
; CHECKIZFINX: # %bb.0:
247+
; CHECKIZFINX-NEXT: lw a0, 0(a0)
248+
; CHECKIZFINX-NEXT: fcvt.s.wu a0, a0
249+
; CHECKIZFINX-NEXT: ret
262250
;
263251
; RV32I-LABEL: fcvt_s_wu_load:
264252
; RV32I: # %bb.0:

0 commit comments

Comments
 (0)