[llvm] [RISCV] Use addi rather than addiw for immediates materialised by lui+addi(w) pairs when possible (PR #141663)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Tue May 27 22:00:16 PDT 2025
topperc wrote:
> Here's a test case where the sext.w isn't neutral in instruction count:
>
> ```
> target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
> target triple = "riscv64-unknown-linux-gnu"
>
> define i32 @Perm(i32 %0) {
> entry:
> %cmp1.not = icmp eq i32 %0, 43300
> br i1 %cmp1.not, label %if.end, label %if.then
>
> if.then: ; preds = %entry
> %.pre = load i32, ptr null, align 4
> br label %if.end
>
> if.end: ; preds = %if.then, %entry
> %1 = phi i32 [ %.pre, %if.then ], [ 43300, %entry ]
> %call2 = tail call i32 (ptr, ...) null(ptr null, i32 signext %1)
> ret i32 %call2
> }
> ```
>
> It does indeed look like RISCVOptWInstrs needs to be a little bit smarter. Thanks for pointing that out.
I think something like this should work.
```
diff --git a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
index 3b601bb43bf2..899c8068a971 100644
--- a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
+++ b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
@@ -591,6 +591,27 @@ 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))
+ return true;
+ }
+ }
+ }
+
+ 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:
@@ -598,7 +619,6 @@ static bool isSignExtendedW(Register SrcReg, const RISCVSubtarget &ST,
if (MI->getOperand(2).getImm() >= 32)
return false;
[[fallthrough]];
- case RISCV::ADDI:
case RISCV::ADD:
case RISCV::LD:
case RISCV::LWU
```
https://github.com/llvm/llvm-project/pull/141663
More information about the llvm-commits
mailing list