diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoM.td b/llvm/lib/Target/RISCV/RISCVInstrInfoM.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoM.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoM.td @@ -70,8 +70,13 @@ def : PatGprGpr; } // Predicates = [HasStdExtM] +// A 'mul' node with a single use. +def mul_oneuse : PatFrag<(ops node:$lhs, node:$rhs), (mul node:$lhs, node:$rhs), [{ + return N->hasOneUse(); +}]>; + let Predicates = [HasStdExtM, IsRV64] in { -def : Pat<(sext_inreg (mul GPR:$rs1, GPR:$rs2), i32), +def : Pat<(sext_inreg (mul_oneuse GPR:$rs1, GPR:$rs2), i32), (MULW GPR:$rs1, GPR:$rs2)>; def : PatGprGpr; diff --git a/llvm/test/CodeGen/RISCV/xaluo.ll b/llvm/test/CodeGen/RISCV/xaluo.ll --- a/llvm/test/CodeGen/RISCV/xaluo.ll +++ b/llvm/test/CodeGen/RISCV/xaluo.ll @@ -699,11 +699,11 @@ ; RV64: # %bb.0: # %entry ; RV64-NEXT: sext.w a1, a1 ; RV64-NEXT: sext.w a0, a0 -; RV64-NEXT: mul a3, a0, a1 -; RV64-NEXT: mulw a0, a0, a1 -; RV64-NEXT: xor a0, a0, a3 +; RV64-NEXT: mul a1, a0, a1 +; RV64-NEXT: sext.w a0, a1 +; RV64-NEXT: xor a0, a0, a1 ; RV64-NEXT: snez a0, a0 -; RV64-NEXT: sw a3, 0(a2) +; RV64-NEXT: sw a1, 0(a2) ; RV64-NEXT: ret ; ; RV32ZBA-LABEL: smulo.i32: @@ -720,11 +720,11 @@ ; RV64ZBA: # %bb.0: # %entry ; RV64ZBA-NEXT: sext.w a1, a1 ; RV64ZBA-NEXT: sext.w a0, a0 -; RV64ZBA-NEXT: mul a3, a0, a1 -; RV64ZBA-NEXT: mulw a0, a0, a1 -; RV64ZBA-NEXT: xor a0, a0, a3 +; RV64ZBA-NEXT: mul a1, a0, a1 +; RV64ZBA-NEXT: sext.w a0, a1 +; RV64ZBA-NEXT: xor a0, a0, a1 ; RV64ZBA-NEXT: snez a0, a0 -; RV64ZBA-NEXT: sw a3, 0(a2) +; RV64ZBA-NEXT: sw a1, 0(a2) ; RV64ZBA-NEXT: ret entry: %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) @@ -750,11 +750,11 @@ ; RV64: # %bb.0: # %entry ; RV64-NEXT: sext.w a0, a0 ; RV64-NEXT: addi a2, zero, 13 -; RV64-NEXT: mul a3, a0, a2 -; RV64-NEXT: mulw a0, a0, a2 -; RV64-NEXT: xor a0, a0, a3 +; RV64-NEXT: mul a2, a0, a2 +; RV64-NEXT: sext.w a0, a2 +; RV64-NEXT: xor a0, a0, a2 ; RV64-NEXT: snez a0, a0 -; RV64-NEXT: sw a3, 0(a1) +; RV64-NEXT: sw a2, 0(a1) ; RV64-NEXT: ret ; ; RV32ZBA-LABEL: smulo2.i32: @@ -772,11 +772,11 @@ ; RV64ZBA: # %bb.0: # %entry ; RV64ZBA-NEXT: sext.w a0, a0 ; RV64ZBA-NEXT: addi a2, zero, 13 -; RV64ZBA-NEXT: mul a3, a0, a2 -; RV64ZBA-NEXT: mulw a0, a0, a2 -; RV64ZBA-NEXT: xor a0, a0, a3 +; RV64ZBA-NEXT: mul a2, a0, a2 +; RV64ZBA-NEXT: sext.w a0, a2 +; RV64ZBA-NEXT: xor a0, a0, a2 ; RV64ZBA-NEXT: snez a0, a0 -; RV64ZBA-NEXT: sw a3, 0(a1) +; RV64ZBA-NEXT: sw a2, 0(a1) ; RV64ZBA-NEXT: ret entry: %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 13) @@ -1045,13 +1045,11 @@ ; 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 ; @@ -1068,11 +1066,11 @@ ; RV64ZBA: # %bb.0: ; RV64ZBA-NEXT: zext.w a1, a1 ; RV64ZBA-NEXT: zext.w a0, a0 -; RV64ZBA-NEXT: mul a3, a0, a1 -; RV64ZBA-NEXT: srli a3, a3, 32 -; RV64ZBA-NEXT: snez a3, a3 -; RV64ZBA-NEXT: mulw a0, a0, a1 -; RV64ZBA-NEXT: sw a3, 0(a2) +; RV64ZBA-NEXT: mul a0, a0, a1 +; RV64ZBA-NEXT: srli a1, a0, 32 +; RV64ZBA-NEXT: snez a1, a1 +; RV64ZBA-NEXT: sext.w a0, a0 +; RV64ZBA-NEXT: sw a1, 0(a2) ; RV64ZBA-NEXT: ret %4 = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %0, i32 %1) %5 = extractvalue { i32, i1 } %4, 1 @@ -2048,9 +2046,9 @@ ; RV64: # %bb.0: # %entry ; RV64-NEXT: sext.w a2, a1 ; RV64-NEXT: sext.w a3, a0 -; RV64-NEXT: mul a4, a3, a2 -; RV64-NEXT: mulw a2, a3, a2 -; RV64-NEXT: bne a2, a4, .LBB39_2 +; RV64-NEXT: mul a2, a3, a2 +; RV64-NEXT: sext.w a3, a2 +; RV64-NEXT: bne a3, a2, .LBB39_2 ; RV64-NEXT: # %bb.1: # %entry ; RV64-NEXT: mv a0, a1 ; RV64-NEXT: .LBB39_2: # %entry @@ -2071,9 +2069,9 @@ ; RV64ZBA: # %bb.0: # %entry ; RV64ZBA-NEXT: sext.w a2, a1 ; RV64ZBA-NEXT: sext.w a3, a0 -; RV64ZBA-NEXT: mul a4, a3, a2 -; RV64ZBA-NEXT: mulw a2, a3, a2 -; RV64ZBA-NEXT: bne a2, a4, .LBB39_2 +; RV64ZBA-NEXT: mul a2, a3, a2 +; RV64ZBA-NEXT: sext.w a3, a2 +; RV64ZBA-NEXT: bne a3, a2, .LBB39_2 ; RV64ZBA-NEXT: # %bb.1: # %entry ; RV64ZBA-NEXT: mv a0, a1 ; RV64ZBA-NEXT: .LBB39_2: # %entry @@ -2099,9 +2097,9 @@ ; RV64: # %bb.0: # %entry ; RV64-NEXT: sext.w a1, a1 ; RV64-NEXT: sext.w a0, a0 -; RV64-NEXT: mul a2, a0, a1 -; RV64-NEXT: mulw a0, a0, a1 -; RV64-NEXT: xor a0, a0, a2 +; RV64-NEXT: mul a0, a0, a1 +; RV64-NEXT: sext.w a1, a0 +; RV64-NEXT: xor a0, a1, a0 ; RV64-NEXT: seqz a0, a0 ; RV64-NEXT: ret ; @@ -2118,9 +2116,9 @@ ; RV64ZBA: # %bb.0: # %entry ; RV64ZBA-NEXT: sext.w a1, a1 ; RV64ZBA-NEXT: sext.w a0, a0 -; RV64ZBA-NEXT: mul a2, a0, a1 -; RV64ZBA-NEXT: mulw a0, a0, a1 -; RV64ZBA-NEXT: xor a0, a0, a2 +; RV64ZBA-NEXT: mul a0, a0, a1 +; RV64ZBA-NEXT: sext.w a1, a0 +; RV64ZBA-NEXT: xor a0, a1, a0 ; RV64ZBA-NEXT: seqz a0, a0 ; RV64ZBA-NEXT: ret entry: @@ -3076,9 +3074,9 @@ ; RV64: # %bb.0: # %entry ; RV64-NEXT: sext.w a1, a1 ; RV64-NEXT: sext.w a0, a0 -; RV64-NEXT: mul a2, a0, a1 -; RV64-NEXT: mulw a0, a0, a1 -; RV64-NEXT: beq a0, a2, .LBB55_2 +; RV64-NEXT: mul a0, a0, a1 +; RV64-NEXT: sext.w a1, a0 +; RV64-NEXT: beq a1, a0, .LBB55_2 ; RV64-NEXT: # %bb.1: # %overflow ; RV64-NEXT: mv a0, zero ; RV64-NEXT: ret @@ -3103,9 +3101,9 @@ ; RV64ZBA: # %bb.0: # %entry ; RV64ZBA-NEXT: sext.w a1, a1 ; RV64ZBA-NEXT: sext.w a0, a0 -; RV64ZBA-NEXT: mul a2, a0, a1 -; RV64ZBA-NEXT: mulw a0, a0, a1 -; RV64ZBA-NEXT: beq a0, a2, .LBB55_2 +; RV64ZBA-NEXT: mul a0, a0, a1 +; RV64ZBA-NEXT: sext.w a1, a0 +; RV64ZBA-NEXT: beq a1, a0, .LBB55_2 ; RV64ZBA-NEXT: # %bb.1: # %overflow ; RV64ZBA-NEXT: mv a0, zero ; RV64ZBA-NEXT: ret