diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -8941,6 +8941,11 @@ if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() || (1 - Imm).isPowerOf2() || (-1 - Imm).isPowerOf2()) return true; + // Optimize the MUL to (SH*ADD x, (SLLI x, bits)) if Imm is not simm12. + if (Subtarget.hasStdExtZba() && !Imm.isSignedIntN(12) && + ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2() || + (Imm - 8).isPowerOf2())) + return true; // Omit the following optimization if the sub target has the M extension // and the data size >= XLen. if (Subtarget.hasStdExtM() && VT.getSizeInBits() >= Subtarget.getXLen()) diff --git a/llvm/test/CodeGen/RISCV/rv32zba.ll b/llvm/test/CodeGen/RISCV/rv32zba.ll --- a/llvm/test/CodeGen/RISCV/rv32zba.ll +++ b/llvm/test/CodeGen/RISCV/rv32zba.ll @@ -615,16 +615,14 @@ ; ; RV32IB-LABEL: mul4098: ; RV32IB: # %bb.0: -; RV32IB-NEXT: lui a1, 1 -; RV32IB-NEXT: addi a1, a1, 2 -; RV32IB-NEXT: mul a0, a0, a1 +; RV32IB-NEXT: slli a1, a0, 12 +; RV32IB-NEXT: sh1add a0, a0, a1 ; RV32IB-NEXT: ret ; ; RV32IBA-LABEL: mul4098: ; RV32IBA: # %bb.0: -; RV32IBA-NEXT: lui a1, 1 -; RV32IBA-NEXT: addi a1, a1, 2 -; RV32IBA-NEXT: mul a0, a0, a1 +; RV32IBA-NEXT: slli a1, a0, 12 +; RV32IBA-NEXT: sh1add a0, a0, a1 ; RV32IBA-NEXT: ret %c = mul i32 %a, 4098 ret i32 %c @@ -640,16 +638,14 @@ ; ; RV32IB-LABEL: mul4100: ; RV32IB: # %bb.0: -; RV32IB-NEXT: lui a1, 1 -; RV32IB-NEXT: addi a1, a1, 4 -; RV32IB-NEXT: mul a0, a0, a1 +; RV32IB-NEXT: slli a1, a0, 12 +; RV32IB-NEXT: sh2add a0, a0, a1 ; RV32IB-NEXT: ret ; ; RV32IBA-LABEL: mul4100: ; RV32IBA: # %bb.0: -; RV32IBA-NEXT: lui a1, 1 -; RV32IBA-NEXT: addi a1, a1, 4 -; RV32IBA-NEXT: mul a0, a0, a1 +; RV32IBA-NEXT: slli a1, a0, 12 +; RV32IBA-NEXT: sh2add a0, a0, a1 ; RV32IBA-NEXT: ret %c = mul i32 %a, 4100 ret i32 %c @@ -665,16 +661,14 @@ ; ; RV32IB-LABEL: mul4104: ; RV32IB: # %bb.0: -; RV32IB-NEXT: lui a1, 1 -; RV32IB-NEXT: addi a1, a1, 8 -; RV32IB-NEXT: mul a0, a0, a1 +; RV32IB-NEXT: slli a1, a0, 12 +; RV32IB-NEXT: sh3add a0, a0, a1 ; RV32IB-NEXT: ret ; ; RV32IBA-LABEL: mul4104: ; RV32IBA: # %bb.0: -; RV32IBA-NEXT: lui a1, 1 -; RV32IBA-NEXT: addi a1, a1, 8 -; RV32IBA-NEXT: mul a0, a0, a1 +; RV32IBA-NEXT: slli a1, a0, 12 +; RV32IBA-NEXT: sh3add a0, a0, a1 ; RV32IBA-NEXT: ret %c = mul i32 %a, 4104 ret i32 %c diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll --- a/llvm/test/CodeGen/RISCV/rv64zba.ll +++ b/llvm/test/CodeGen/RISCV/rv64zba.ll @@ -1120,16 +1120,14 @@ ; ; RV64IB-LABEL: mul4098: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a1, 1 -; RV64IB-NEXT: addiw a1, a1, 2 -; RV64IB-NEXT: mul a0, a0, a1 +; RV64IB-NEXT: slli a1, a0, 12 +; RV64IB-NEXT: sh1add a0, a0, a1 ; RV64IB-NEXT: ret ; ; RV64IBA-LABEL: mul4098: ; RV64IBA: # %bb.0: -; RV64IBA-NEXT: lui a1, 1 -; RV64IBA-NEXT: addiw a1, a1, 2 -; RV64IBA-NEXT: mul a0, a0, a1 +; RV64IBA-NEXT: slli a1, a0, 12 +; RV64IBA-NEXT: sh1add a0, a0, a1 ; RV64IBA-NEXT: ret %c = mul i64 %a, 4098 ret i64 %c @@ -1145,16 +1143,14 @@ ; ; RV64IB-LABEL: mul4100: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a1, 1 -; RV64IB-NEXT: addiw a1, a1, 4 -; RV64IB-NEXT: mul a0, a0, a1 +; RV64IB-NEXT: slli a1, a0, 12 +; RV64IB-NEXT: sh2add a0, a0, a1 ; RV64IB-NEXT: ret ; ; RV64IBA-LABEL: mul4100: ; RV64IBA: # %bb.0: -; RV64IBA-NEXT: lui a1, 1 -; RV64IBA-NEXT: addiw a1, a1, 4 -; RV64IBA-NEXT: mul a0, a0, a1 +; RV64IBA-NEXT: slli a1, a0, 12 +; RV64IBA-NEXT: sh2add a0, a0, a1 ; RV64IBA-NEXT: ret %c = mul i64 %a, 4100 ret i64 %c @@ -1170,16 +1166,14 @@ ; ; RV64IB-LABEL: mul4104: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a1, 1 -; RV64IB-NEXT: addiw a1, a1, 8 -; RV64IB-NEXT: mul a0, a0, a1 +; RV64IB-NEXT: slli a1, a0, 12 +; RV64IB-NEXT: sh3add a0, a0, a1 ; RV64IB-NEXT: ret ; ; RV64IBA-LABEL: mul4104: ; RV64IBA: # %bb.0: -; RV64IBA-NEXT: lui a1, 1 -; RV64IBA-NEXT: addiw a1, a1, 8 -; RV64IBA-NEXT: mul a0, a0, a1 +; RV64IBA-NEXT: slli a1, a0, 12 +; RV64IBA-NEXT: sh3add a0, a0, a1 ; RV64IBA-NEXT: ret %c = mul i64 %a, 4104 ret i64 %c