diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoM.td b/llvm/lib/Target/RISCV/RISCVInstrInfoM.td index d6f8287f199ced..e841d7fdea0b52 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoM.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoM.td @@ -104,4 +104,11 @@ let Predicates = [HasStdExtM, IsRV64, NotHasStdExtZba] in { // still be better off shifting both left by 32. def : Pat<(i64 (mul (and GPR:$rs1, 0xffffffff), (and GPR:$rs2, 0xffffffff))), (MULHU (SLLI GPR:$rs1, 32), (SLLI GPR:$rs2, 32))>; +// Prevent matching the first part of this pattern to mulw. The mul here has +// additionals users or the ANDs would have been removed. The above pattern +// will be used for the other users. If we form a mulw we'll keep the ANDs alive +// and they'll still become SLLI+SRLI. +def : Pat<(sext_inreg (mul (and GPR:$rs1, 0xffffffff), + (and GPR:$rs2, 0xffffffff)), i32), + (ADDIW (MULHU (SLLI GPR:$rs1, 32), (SLLI GPR:$rs2, 32)), 0)>; } // Predicates = [HasStdExtM, IsRV64, NotHasStdExtZba] diff --git a/llvm/test/CodeGen/RISCV/xaluo.ll b/llvm/test/CodeGen/RISCV/xaluo.ll index b535fd93be76b4..707d1621d6ef81 100644 --- a/llvm/test/CodeGen/RISCV/xaluo.ll +++ b/llvm/test/CodeGen/RISCV/xaluo.ll @@ -1045,13 +1045,11 @@ define signext i32 @umulo3.i32(i32 signext %0, i32 signext %1, i32* %2) { ; RV64-LABEL: umulo3.i32: ; RV64: # %bb.0: ; RV64-NEXT: slli a1, a1, 32 -; RV64-NEXT: srli a3, a1, 32 ; RV64-NEXT: slli a0, a0, 32 -; RV64-NEXT: srli a4, a0, 32 ; RV64-NEXT: mulhu a0, a0, a1 -; RV64-NEXT: srli a0, a0, 32 -; RV64-NEXT: snez a1, a0 -; RV64-NEXT: mulw a0, a4, a3 +; RV64-NEXT: srli a1, a0, 32 +; RV64-NEXT: snez a1, a1 +; RV64-NEXT: sext.w a0, a0 ; RV64-NEXT: sw a1, 0(a2) ; RV64-NEXT: ret ;