Index: llvm/lib/Target/RISCV/RISCVInstrInfoB.td =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfoB.td +++ llvm/lib/Target/RISCV/RISCVInstrInfoB.td @@ -171,6 +171,21 @@ SDLoc(N), N->getValueType(0)); }]>; +def C3LeftShift : PatLeaf<(imm), [{ + uint64_t C = N->getZExtValue(); + return C > 3 && ((C % 3) == 0) && isPowerOf2_64(C / 3); +}]>; + +def C5LeftShift : PatLeaf<(imm), [{ + uint64_t C = N->getZExtValue(); + return C > 5 && ((C % 5) == 0) && isPowerOf2_64(C / 5); +}]>; + +def C9LeftShift : PatLeaf<(imm), [{ + uint64_t C = N->getZExtValue(); + return C > 9 && ((C % 9) == 0) && isPowerOf2_64(C / 9); +}]>; + //===----------------------------------------------------------------------===// // Instruction class templates //===----------------------------------------------------------------------===// @@ -995,6 +1010,16 @@ (SH3ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>; def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2), (SH3ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>; + +def : Pat<(mul GPR:$r, C3LeftShift:$i), + (SLLI (SH1ADD GPR:$r, GPR:$r), + (BSETINVTwoBitsMaskLow C3LeftShift:$i))>; +def : Pat<(mul GPR:$r, C5LeftShift:$i), + (SLLI (SH2ADD GPR:$r, GPR:$r), + (BSETINVTwoBitsMaskLow C5LeftShift:$i))>; +def : Pat<(mul GPR:$r, C9LeftShift:$i), + (SLLI (SH3ADD GPR:$r, GPR:$r), + (BSETINVTwoBitsMaskLow C9LeftShift:$i))>; } // Predicates = [HasStdExtZba] let Predicates = [HasStdExtZba, IsRV64] in { Index: llvm/test/CodeGen/RISCV/rv32zba.ll =================================================================== --- llvm/test/CodeGen/RISCV/rv32zba.ll +++ llvm/test/CodeGen/RISCV/rv32zba.ll @@ -306,14 +306,14 @@ ; ; RV32IB-LABEL: mul96: ; RV32IB: # %bb.0: -; RV32IB-NEXT: addi a1, zero, 96 -; RV32IB-NEXT: mul a0, a0, a1 +; RV32IB-NEXT: sh1add a0, a0, a0 +; RV32IB-NEXT: slli a0, a0, 5 ; RV32IB-NEXT: ret ; ; RV32IBA-LABEL: mul96: ; RV32IBA: # %bb.0: -; RV32IBA-NEXT: addi a1, zero, 96 -; RV32IBA-NEXT: mul a0, a0, a1 +; RV32IBA-NEXT: sh1add a0, a0, a0 +; RV32IBA-NEXT: slli a0, a0, 5 ; RV32IBA-NEXT: ret %c = mul i32 %a, 96 ret i32 %c @@ -328,14 +328,14 @@ ; ; RV32IB-LABEL: mul160: ; RV32IB: # %bb.0: -; RV32IB-NEXT: addi a1, zero, 160 -; RV32IB-NEXT: mul a0, a0, a1 +; RV32IB-NEXT: sh2add a0, a0, a0 +; RV32IB-NEXT: slli a0, a0, 5 ; RV32IB-NEXT: ret ; ; RV32IBA-LABEL: mul160: ; RV32IBA: # %bb.0: -; RV32IBA-NEXT: addi a1, zero, 160 -; RV32IBA-NEXT: mul a0, a0, a1 +; RV32IBA-NEXT: sh2add a0, a0, a0 +; RV32IBA-NEXT: slli a0, a0, 5 ; RV32IBA-NEXT: ret %c = mul i32 %a, 160 ret i32 %c @@ -350,14 +350,14 @@ ; ; RV32IB-LABEL: mul288: ; RV32IB: # %bb.0: -; RV32IB-NEXT: addi a1, zero, 288 -; RV32IB-NEXT: mul a0, a0, a1 +; RV32IB-NEXT: sh3add a0, a0, a0 +; RV32IB-NEXT: slli a0, a0, 5 ; RV32IB-NEXT: ret ; ; RV32IBA-LABEL: mul288: ; RV32IBA: # %bb.0: -; RV32IBA-NEXT: addi a1, zero, 288 -; RV32IBA-NEXT: mul a0, a0, a1 +; RV32IBA-NEXT: sh3add a0, a0, a0 +; RV32IBA-NEXT: slli a0, a0, 5 ; RV32IBA-NEXT: ret %c = mul i32 %a, 288 ret i32 %c Index: llvm/test/CodeGen/RISCV/rv64zba.ll =================================================================== --- llvm/test/CodeGen/RISCV/rv64zba.ll +++ llvm/test/CodeGen/RISCV/rv64zba.ll @@ -596,14 +596,14 @@ ; ; RV64IB-LABEL: mul96: ; RV64IB: # %bb.0: -; RV64IB-NEXT: addi a1, zero, 96 -; RV64IB-NEXT: mul a0, a0, a1 +; RV64IB-NEXT: sh1add a0, a0, a0 +; RV64IB-NEXT: slli a0, a0, 5 ; RV64IB-NEXT: ret ; ; RV64IBA-LABEL: mul96: ; RV64IBA: # %bb.0: -; RV64IBA-NEXT: addi a1, zero, 96 -; RV64IBA-NEXT: mul a0, a0, a1 +; RV64IBA-NEXT: sh1add a0, a0, a0 +; RV64IBA-NEXT: slli a0, a0, 5 ; RV64IBA-NEXT: ret %c = mul i64 %a, 96 ret i64 %c @@ -618,14 +618,14 @@ ; ; RV64IB-LABEL: mul160: ; RV64IB: # %bb.0: -; RV64IB-NEXT: addi a1, zero, 160 -; RV64IB-NEXT: mul a0, a0, a1 +; RV64IB-NEXT: sh2add a0, a0, a0 +; RV64IB-NEXT: slli a0, a0, 5 ; RV64IB-NEXT: ret ; ; RV64IBA-LABEL: mul160: ; RV64IBA: # %bb.0: -; RV64IBA-NEXT: addi a1, zero, 160 -; RV64IBA-NEXT: mul a0, a0, a1 +; RV64IBA-NEXT: sh2add a0, a0, a0 +; RV64IBA-NEXT: slli a0, a0, 5 ; RV64IBA-NEXT: ret %c = mul i64 %a, 160 ret i64 %c @@ -640,14 +640,14 @@ ; ; RV64IB-LABEL: mul288: ; RV64IB: # %bb.0: -; RV64IB-NEXT: addi a1, zero, 288 -; RV64IB-NEXT: mul a0, a0, a1 +; RV64IB-NEXT: sh3add a0, a0, a0 +; RV64IB-NEXT: slli a0, a0, 5 ; RV64IB-NEXT: ret ; ; RV64IBA-LABEL: mul288: ; RV64IBA: # %bb.0: -; RV64IBA-NEXT: addi a1, zero, 288 -; RV64IBA-NEXT: mul a0, a0, a1 +; RV64IBA-NEXT: sh3add a0, a0, a0 +; RV64IBA-NEXT: slli a0, a0, 5 ; RV64IBA-NEXT: ret %c = mul i64 %a, 288 ret i64 %c