================ @@ -294,4 +294,13 @@ def : Pat<(f32 fpnegimm0), (FNEGS (FZEROS))>; // VIS3 instruction patterns. let Predicates = [HasVIS3] in { def : Pat<(i64 (adde i64:$lhs, i64:$rhs)), (ADDXCCC $lhs, $rhs)>; + +def : Pat<(i64 (mulhu i64:$lhs, i64:$rhs)), (UMULXHI $lhs, $rhs)>; +// Signed "MULXHI". +// Based on the formula presented in OSA2011 ยง7.140, but with bitops to select +// the values to be added. +def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)), + (SUBrr (UMULXHI $lhs, $rhs), + (ADDrr (ANDrr (SRAXri $lhs, 63), $rhs), + (ANDrr (SRAXri $rhs, 63), $lhs)))>; ---------------- s-barannikov wrote:
I've just realized than on my target there is the same issue (two additional muls). I solved it by adding a simple DAG combiner optimization (`setTargetDAGCombine(ISD::MUL)`). As I noted in the other PR, doing longer expansions earlier opens opportunities for other optimizations. This is how it looks like: ```C++ SDValue <...>TargetLowering::combineMUL(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; SDValue LHS = N->getOperand(0); SDValue RHS = N->getOperand(1); EVT VT = N->getValueType(0); SDLoc DL(N); // (mul X, sign_mask) -> (and (sub 0, X), sign_mask). if (DAG.ComputeNumSignBits(LHS) == VT.getFixedSizeInBits()) { SDValue Neg = DAG.getNegative(RHS, DL, VT); return DAG.getNode(ISD::AND, DL, VT, LHS, Neg); } if (DAG.ComputeNumSignBits(RHS) == VT.getFixedSizeInBits()) { SDValue Neg = DAG.getNegative(LHS, DL, VT); return DAG.getNode(ISD::AND, DL, VT, RHS, Neg); } return SDValue(); } ``` This could be done by the generic DAG combiner, but it replaces one instruction with two, so I didn't try upstream it. Can you try it with MULHS set to Expand? https://github.com/llvm/llvm-project/pull/135714 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits