Skip to content

[RISCV] Use addi rather than addiw for immediates materialised by lui+addi(w) pairs when possible #141663

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

Merged
merged 10 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,15 @@ static void generateInstSeqImpl(int64_t Val, const MCSubtargetInfo &STI,
Res.emplace_back(RISCV::LUI, Hi20);

if (Lo12 || Hi20 == 0) {
unsigned AddiOpc = (IsRV64 && Hi20) ? RISCV::ADDIW : RISCV::ADDI;
unsigned AddiOpc = RISCV::ADDI;
if (IsRV64 && Hi20) {
// Use ADDIW rather than ADDI only when necessary for correctness. As
// noted in RISCVOptWInstrs, this helps reduce test differences vs
// RV32 without being a pessimization.
int64_t LuiRes = SignExtend64<32>(Hi20 << 12);
if (!isInt<32>(LuiRes + Lo12))
AddiOpc = RISCV::ADDIW;
}
Res.emplace_back(AddiOpc, Lo12);
}
return;
Expand Down
22 changes: 21 additions & 1 deletion llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,14 +591,34 @@ static bool isSignExtendedW(Register SrcReg, const RISCVSubtarget &ST,
return false;
break;

case RISCV::ADDI: {
if (MI->getOperand(1).isReg() && MI->getOperand(1).getReg().isVirtual()) {
if (MachineInstr *SrcMI = MRI.getVRegDef(MI->getOperand(1).getReg())) {
if (SrcMI->getOpcode() == RISCV::LUI &&
SrcMI->getOperand(1).isImm()) {
uint64_t Imm = SrcMI->getOperand(1).getImm();
Imm = SignExtend64<32>(Imm << 12);
Imm += (uint64_t)MI->getOperand(2).getImm();
if (isInt<32>(Imm))
continue;
}
}
}

if (hasAllWUsers(*MI, ST, MRI)) {
FixableDef.insert(MI);
break;
}
return false;
}

// With these opcode, we can "fix" them with the W-version
// if we know all users of the result only rely on bits 31:0
case RISCV::SLLI:
// SLLIW reads the lowest 5 bits, while SLLI reads lowest 6 bits
if (MI->getOperand(2).getImm() >= 32)
return false;
[[fallthrough]];
case RISCV::ADDI:
case RISCV::ADD:
case RISCV::LD:
case RISCV::LWU:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ define i64 @subi_i64(i64 %a) {
; RV64IM-LABEL: subi_i64:
; RV64IM: # %bb.0: # %entry
; RV64IM-NEXT: lui a1, 1048275
; RV64IM-NEXT: addiw a1, a1, -1548
; RV64IM-NEXT: addi a1, a1, -1548
; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
entry:
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/RISCV/GlobalISel/bitmanip.ll
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ define i24 @bitreverse_i24(i24 %x) {
; RV64-NEXT: slli a1, a0, 16
; RV64-NEXT: lui a2, 4096
; RV64-NEXT: lui a3, 1048335
; RV64-NEXT: addiw a2, a2, -1
; RV64-NEXT: addiw a3, a3, 240
; RV64-NEXT: addi a2, a2, -1
; RV64-NEXT: addi a3, a3, 240
; RV64-NEXT: and a0, a0, a2
; RV64-NEXT: srli a0, a0, 16
; RV64-NEXT: or a0, a0, a1
Expand All @@ -184,15 +184,15 @@ define i24 @bitreverse_i24(i24 %x) {
; RV64-NEXT: slli a0, a0, 4
; RV64-NEXT: and a0, a0, a3
; RV64-NEXT: lui a3, 1047757
; RV64-NEXT: addiw a3, a3, -820
; RV64-NEXT: addi a3, a3, -820
; RV64-NEXT: srli a1, a1, 4
; RV64-NEXT: or a0, a1, a0
; RV64-NEXT: and a1, a3, a2
; RV64-NEXT: and a1, a0, a1
; RV64-NEXT: slli a0, a0, 2
; RV64-NEXT: and a0, a0, a3
; RV64-NEXT: lui a3, 1047211
; RV64-NEXT: addiw a3, a3, -1366
; RV64-NEXT: addi a3, a3, -1366
; RV64-NEXT: and a2, a3, a2
; RV64-NEXT: srli a1, a1, 2
; RV64-NEXT: or a0, a1, a0
Expand Down
14 changes: 7 additions & 7 deletions llvm/test/CodeGen/RISCV/GlobalISel/div-by-constant.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ define i32 @udiv_constant_no_add(i32 %a) nounwind {
; RV64IM-NEXT: slli a0, a0, 32
; RV64IM-NEXT: lui a1, 205
; RV64IM-NEXT: srli a0, a0, 32
; RV64IM-NEXT: addiw a1, a1, -819
; RV64IM-NEXT: addi a1, a1, -819
; RV64IM-NEXT: slli a1, a1, 12
; RV64IM-NEXT: addi a1, a1, -819
; RV64IM-NEXT: mul a0, a0, a1
Expand Down Expand Up @@ -62,7 +62,7 @@ define i32 @udiv_constant_add(i32 %a) nounwind {
; RV64IM: # %bb.0:
; RV64IM-NEXT: lui a1, 149797
; RV64IM-NEXT: slli a2, a0, 32
; RV64IM-NEXT: addiw a1, a1, -1755
; RV64IM-NEXT: addi a1, a1, -1755
; RV64IM-NEXT: srli a2, a2, 32
; RV64IM-NEXT: mul a1, a2, a1
; RV64IM-NEXT: srli a1, a1, 32
Expand All @@ -75,7 +75,7 @@ define i32 @udiv_constant_add(i32 %a) nounwind {
; RV64IMZB-LABEL: udiv_constant_add:
; RV64IMZB: # %bb.0:
; RV64IMZB-NEXT: lui a1, 149797
; RV64IMZB-NEXT: addiw a1, a1, -1755
; RV64IMZB-NEXT: addi a1, a1, -1755
; RV64IMZB-NEXT: zext.w a2, a0
; RV64IMZB-NEXT: mul a1, a2, a1
; RV64IMZB-NEXT: srli a1, a1, 32
Expand Down Expand Up @@ -286,7 +286,7 @@ define i16 @udiv16_constant_no_add(i16 %a) nounwind {
; RV64IM-NEXT: slli a0, a0, 48
; RV64IM-NEXT: lui a1, 13
; RV64IM-NEXT: srli a0, a0, 48
; RV64IM-NEXT: addiw a1, a1, -819
; RV64IM-NEXT: addi a1, a1, -819
; RV64IM-NEXT: mul a0, a0, a1
; RV64IM-NEXT: srli a0, a0, 18
; RV64IM-NEXT: ret
Expand All @@ -295,7 +295,7 @@ define i16 @udiv16_constant_no_add(i16 %a) nounwind {
; RV64IMZB: # %bb.0:
; RV64IMZB-NEXT: zext.h a0, a0
; RV64IMZB-NEXT: lui a1, 13
; RV64IMZB-NEXT: addiw a1, a1, -819
; RV64IMZB-NEXT: addi a1, a1, -819
; RV64IMZB-NEXT: mul a0, a0, a1
; RV64IMZB-NEXT: srli a0, a0, 18
; RV64IMZB-NEXT: ret
Expand Down Expand Up @@ -340,8 +340,8 @@ define i16 @udiv16_constant_add(i16 %a) nounwind {
; RV64IM: # %bb.0:
; RV64IM-NEXT: lui a1, 2
; RV64IM-NEXT: lui a2, 16
; RV64IM-NEXT: addiw a1, a1, 1171
; RV64IM-NEXT: addiw a2, a2, -1
; RV64IM-NEXT: addi a1, a1, 1171
; RV64IM-NEXT: addi a2, a2, -1
; RV64IM-NEXT: and a3, a0, a2
; RV64IM-NEXT: mul a1, a3, a1
; RV64IM-NEXT: srli a1, a1, 16
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/RISCV/GlobalISel/float-intrinsics.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ define i1 @fpclass(float %x) {
; RV64I-NEXT: lui a4, 2048
; RV64I-NEXT: lui a5, 520192
; RV64I-NEXT: srli a2, a2, 33
; RV64I-NEXT: addiw a6, a4, -1
; RV64I-NEXT: addi a6, a4, -1
; RV64I-NEXT: xor a0, a0, a2
; RV64I-NEXT: subw a3, a2, a3
; RV64I-NEXT: sltu a3, a3, a6
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ body: |
; CHECK: liveins: $x10
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288
; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], 648
; CHECK-NEXT: $x10 = COPY [[ADDIW]]
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], 648
; CHECK-NEXT: $x10 = COPY [[ADDI]]
; CHECK-NEXT: PseudoRET implicit $x10
%0:gprb(s64) = G_CONSTANT i64 -2147483000
$x10 = COPY %0(s64)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
# RUN: llc -mtriple=riscv32 -mattr=+zfh -run-pass=instruction-select \
# RUN: -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,RV32
# RUN: -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
# RUN: llc -mtriple=riscv64 -mattr=+zfh -run-pass=instruction-select \
# RUN: -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,RV64
# RUN: -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s

---
name: half_imm
legalized: true
regBankSelected: true
body: |
bb.1:
; RV32-LABEL: name: half_imm
; RV32: [[LUI:%[0-9]+]]:gpr = LUI 4
; RV32-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], 584
; RV32-NEXT: [[FMV_H_X:%[0-9]+]]:fpr16 = FMV_H_X [[ADDI]]
; RV32-NEXT: $f10_h = COPY [[FMV_H_X]]
; RV32-NEXT: PseudoRET implicit $f10_h
;
; RV64-LABEL: name: half_imm
; RV64: [[LUI:%[0-9]+]]:gpr = LUI 4
; RV64-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], 584
; RV64-NEXT: [[FMV_H_X:%[0-9]+]]:fpr16 = FMV_H_X [[ADDIW]]
; RV64-NEXT: $f10_h = COPY [[FMV_H_X]]
; RV64-NEXT: PseudoRET implicit $f10_h
; CHECK-LABEL: name: half_imm
; CHECK: [[LUI:%[0-9]+]]:gpr = LUI 4
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], 584
; CHECK-NEXT: [[FMV_H_X:%[0-9]+]]:fpr16 = FMV_H_X [[ADDI]]
; CHECK-NEXT: $f10_h = COPY [[FMV_H_X]]
; CHECK-NEXT: PseudoRET implicit $f10_h
%0:fprb(s16) = G_FCONSTANT half 0xH4248
$f10_h = COPY %0(s16)
PseudoRET implicit $f10_h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,12 @@ legalized: true
regBankSelected: true
body: |
bb.1:
; RV32-LABEL: name: float_imm
; RV32: [[LUI:%[0-9]+]]:gpr = LUI 263313
; RV32-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], -37
; RV32-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[ADDI]]
; RV32-NEXT: $f10_f = COPY [[FMV_W_X]]
; RV32-NEXT: PseudoRET implicit $f10_f
;
; RV64-LABEL: name: float_imm
; RV64: [[LUI:%[0-9]+]]:gpr = LUI 263313
; RV64-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], -37
; RV64-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[ADDIW]]
; RV64-NEXT: $f10_f = COPY [[FMV_W_X]]
; RV64-NEXT: PseudoRET implicit $f10_f
; CHECK-LABEL: name: float_imm
; CHECK: [[LUI:%[0-9]+]]:gpr = LUI 263313
; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], -37
; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[ADDI]]
; CHECK-NEXT: $f10_f = COPY [[FMV_W_X]]
; CHECK-NEXT: PseudoRET implicit $f10_f
%0:fprb(s32) = G_FCONSTANT float 0x400921FB60000000
$f10_f = COPY %0(s32)
PseudoRET implicit $f10_f
Expand Down Expand Up @@ -109,14 +102,14 @@ body: |
;
; RV64-LABEL: name: double_imm
; RV64: [[LUI:%[0-9]+]]:gpr = LUI 512
; RV64-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], 1169
; RV64-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDIW]], 15
; RV64-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[SLLI]], -299
; RV64-NEXT: [[SLLI1:%[0-9]+]]:gpr = SLLI [[ADDI]], 14
; RV64-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI [[SLLI1]], 1091
; RV64-NEXT: [[SLLI2:%[0-9]+]]:gpr = SLLI [[ADDI1]], 12
; RV64-NEXT: [[ADDI2:%[0-9]+]]:gpr = ADDI [[SLLI2]], -744
; RV64-NEXT: [[FMV_D_X:%[0-9]+]]:fpr64 = FMV_D_X [[ADDI2]]
; RV64-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], 1169
; RV64-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI]], 15
; RV64-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI [[SLLI]], -299
; RV64-NEXT: [[SLLI1:%[0-9]+]]:gpr = SLLI [[ADDI1]], 14
; RV64-NEXT: [[ADDI2:%[0-9]+]]:gpr = ADDI [[SLLI1]], 1091
; RV64-NEXT: [[SLLI2:%[0-9]+]]:gpr = SLLI [[ADDI2]], 12
; RV64-NEXT: [[ADDI3:%[0-9]+]]:gpr = ADDI [[SLLI2]], -744
; RV64-NEXT: [[FMV_D_X:%[0-9]+]]:fpr64 = FMV_D_X [[ADDI3]]
; RV64-NEXT: $f10_d = COPY [[FMV_D_X]]
; RV64-NEXT: PseudoRET implicit $f10_d
%0:fprb(s64) = G_FCONSTANT double 0x400921FB54442D18
Expand Down
Loading
Loading