diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -1467,7 +1467,7 @@ const SDNode *N2); SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, - SDNode *N1, SDNode *N2); + ArrayRef Ops); SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, const ConstantSDNode *C1, diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -955,10 +955,11 @@ if (N0->getFlags().hasVectorReduction()) return SDValue(); - if (SDNode *C1 = DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1))) { - if (SDNode *C2 = DAG.isConstantIntBuildVectorOrConstantInt(N1)) { + if (DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1))) { + if (DAG.isConstantIntBuildVectorOrConstantInt(N1)) { // Reassociate: (op (op x, c1), c2) -> (op x, (op c1, c2)) - if (SDValue OpNode = DAG.FoldConstantArithmetic(Opc, DL, VT, C1, C2)) + if (SDValue OpNode = + DAG.FoldConstantArithmetic(Opc, DL, VT, {N0.getOperand(1), N1})) return DAG.getNode(Opc, DL, VT, N0.getOperand(0), OpNode); return SDValue(); } @@ -2109,8 +2110,7 @@ if (!DAG.isConstantIntBuildVectorOrConstantInt(N1)) return DAG.getNode(ISD::ADD, DL, VT, N1, N0); // fold (add c1, c2) -> c1+c2 - return DAG.FoldConstantArithmetic(ISD::ADD, DL, VT, N0.getNode(), - N1.getNode()); + return DAG.FoldConstantArithmetic(ISD::ADD, DL, VT, {N0, N1}); } // fold (add x, 0) -> x @@ -2121,8 +2121,8 @@ // fold ((A-c1)+c2) -> (A+(c2-c1)) if (N0.getOpcode() == ISD::SUB && isConstantOrConstantVector(N0.getOperand(1), /* NoOpaque */ true)) { - SDValue Sub = DAG.FoldConstantArithmetic(ISD::SUB, DL, VT, N1.getNode(), - N0.getOperand(1).getNode()); + SDValue Sub = + DAG.FoldConstantArithmetic(ISD::SUB, DL, VT, {N1, N0.getOperand(1)}); assert(Sub && "Constant folding failed"); return DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(0), Sub); } @@ -2130,8 +2130,8 @@ // fold ((c1-A)+c2) -> (c1+c2)-A if (N0.getOpcode() == ISD::SUB && isConstantOrConstantVector(N0.getOperand(0), /* NoOpaque */ true)) { - SDValue Add = DAG.FoldConstantArithmetic(ISD::ADD, DL, VT, N1.getNode(), - N0.getOperand(0).getNode()); + SDValue Add = + DAG.FoldConstantArithmetic(ISD::ADD, DL, VT, {N1, N0.getOperand(0)}); assert(Add && "Constant folding failed"); return DAG.getNode(ISD::SUB, DL, VT, Add, N0.getOperand(1)); } @@ -2347,8 +2347,7 @@ if (!DAG.isConstantIntBuildVectorOrConstantInt(N1)) return DAG.getNode(Opcode, DL, VT, N1, N0); // fold (add_sat c1, c2) -> c3 - return DAG.FoldConstantArithmetic(Opcode, DL, VT, N0.getNode(), - N1.getNode()); + return DAG.FoldConstantArithmetic(Opcode, DL, VT, {N0, N1}); } // fold (add_sat x, 0) -> x @@ -2971,8 +2970,7 @@ if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && DAG.isConstantIntBuildVectorOrConstantInt(N1)) { // fold (sub c1, c2) -> c1-c2 - return DAG.FoldConstantArithmetic(ISD::SUB, DL, VT, N0.getNode(), - N1.getNode()); + return DAG.FoldConstantArithmetic(ISD::SUB, DL, VT, {N0, N1}); } if (SDValue NewSel = foldBinOpIntoSelect(N)) @@ -3040,8 +3038,8 @@ if (N0.getOpcode() == ISD::ADD && isConstantOrConstantVector(N1, /* NoOpaques */ true) && isConstantOrConstantVector(N0.getOperand(1), /* NoOpaques */ true)) { - SDValue NewC = DAG.FoldConstantArithmetic( - ISD::SUB, DL, VT, N0.getOperand(1).getNode(), N1.getNode()); + SDValue NewC = + DAG.FoldConstantArithmetic(ISD::SUB, DL, VT, {N0.getOperand(1), N1}); assert(NewC && "Constant folding failed"); return DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(0), NewC); } @@ -3051,8 +3049,7 @@ SDValue N11 = N1.getOperand(1); if (isConstantOrConstantVector(N0, /* NoOpaques */ true) && isConstantOrConstantVector(N11, /* NoOpaques */ true)) { - SDValue NewC = DAG.FoldConstantArithmetic(ISD::SUB, DL, VT, N0.getNode(), - N11.getNode()); + SDValue NewC = DAG.FoldConstantArithmetic(ISD::SUB, DL, VT, {N0, N11}); assert(NewC && "Constant folding failed"); return DAG.getNode(ISD::SUB, DL, VT, NewC, N1.getOperand(0)); } @@ -3062,8 +3059,8 @@ if (N0.getOpcode() == ISD::SUB && isConstantOrConstantVector(N1, /* NoOpaques */ true) && isConstantOrConstantVector(N0.getOperand(1), /* NoOpaques */ true)) { - SDValue NewC = DAG.FoldConstantArithmetic( - ISD::ADD, DL, VT, N0.getOperand(1).getNode(), N1.getNode()); + SDValue NewC = + DAG.FoldConstantArithmetic(ISD::ADD, DL, VT, {N0.getOperand(1), N1}); assert(NewC && "Constant folding failed"); return DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), NewC); } @@ -3072,8 +3069,8 @@ if (N0.getOpcode() == ISD::SUB && isConstantOrConstantVector(N1, /* NoOpaques */ true) && isConstantOrConstantVector(N0.getOperand(0), /* NoOpaques */ true)) { - SDValue NewC = DAG.FoldConstantArithmetic( - ISD::SUB, DL, VT, N0.getOperand(0).getNode(), N1.getNode()); + SDValue NewC = + DAG.FoldConstantArithmetic(ISD::SUB, DL, VT, {N0.getOperand(0), N1}); assert(NewC && "Constant folding failed"); return DAG.getNode(ISD::SUB, DL, VT, NewC, N0.getOperand(1)); } @@ -3297,8 +3294,7 @@ if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && DAG.isConstantIntBuildVectorOrConstantInt(N1)) { // fold (sub_sat c1, c2) -> c3 - return DAG.FoldConstantArithmetic(N->getOpcode(), DL, VT, N0.getNode(), - N1.getNode()); + return DAG.FoldConstantArithmetic(N->getOpcode(), DL, VT, {N0, N1}); } // fold (sub_sat x, 0) -> x @@ -3468,8 +3464,7 @@ // fold (mul c1, c2) -> c1*c2 if (N0IsConst && N1IsConst && !N0IsOpaqueConst && !N1IsOpaqueConst) - return DAG.FoldConstantArithmetic(ISD::MUL, SDLoc(N), VT, - N0.getNode(), N1.getNode()); + return DAG.FoldConstantArithmetic(ISD::MUL, SDLoc(N), VT, {N0, N1}); // canonicalize constant to RHS (vector doesn't have to splat) if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && @@ -5920,8 +5915,8 @@ }; if (N0.getOpcode() == ISD::AND && N0.getNode()->hasOneUse() && ISD::matchBinaryPredicate(N0.getOperand(1), N1, MatchIntersect, true)) { - if (SDValue COR = DAG.FoldConstantArithmetic( - ISD::OR, SDLoc(N1), VT, N1.getNode(), N0.getOperand(1).getNode())) { + if (SDValue COR = DAG.FoldConstantArithmetic(ISD::OR, SDLoc(N1), VT, + {N1, N0.getOperand(1)})) { SDValue IOR = DAG.getNode(ISD::OR, SDLoc(N0), VT, N0.getOperand(0), N1); AddToWorklist(IOR.getNode()); return DAG.getNode(ISD::AND, SDLoc(N), VT, COR, IOR); @@ -7430,12 +7425,11 @@ EVT ShiftVT = C1->getValueType(0); bool SameSide = (N->getOpcode() == NextOp); unsigned CombineOp = SameSide ? ISD::ADD : ISD::SUB; - if (SDValue CombinedShift = - DAG.FoldConstantArithmetic(CombineOp, dl, ShiftVT, C1, C2)) { + if (SDValue CombinedShift = DAG.FoldConstantArithmetic( + CombineOp, dl, ShiftVT, {N1, N0.getOperand(1)})) { SDValue BitsizeC = DAG.getConstant(Bitsize, dl, ShiftVT); SDValue CombinedShiftNorm = DAG.FoldConstantArithmetic( - ISD::SREM, dl, ShiftVT, CombinedShift.getNode(), - BitsizeC.getNode()); + ISD::SREM, dl, ShiftVT, {CombinedShift, BitsizeC}); return DAG.getNode(N->getOpcode(), dl, VT, N0->getOperand(0), CombinedShiftNorm); } @@ -7471,8 +7465,8 @@ if (N01CV && N01CV->isConstant() && N00.getOpcode() == ISD::SETCC && TLI.getBooleanContents(N00.getOperand(0).getValueType()) == TargetLowering::ZeroOrNegativeOneBooleanContent) { - if (SDValue C = DAG.FoldConstantArithmetic(ISD::SHL, SDLoc(N), VT, - N01CV, N1CV)) + if (SDValue C = + DAG.FoldConstantArithmetic(ISD::SHL, SDLoc(N), VT, {N01, N1})) return DAG.getNode(ISD::AND, SDLoc(N), VT, N00, C); } } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4881,16 +4881,26 @@ } SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, - EVT VT, SDNode *N1, SDNode *N2) { + EVT VT, ArrayRef Ops) { // If the opcode is a target-specific ISD node, there's nothing we can // do here and the operand rules may not line up with the below, so // bail early. if (Opcode >= ISD::BUILTIN_OP_END) return SDValue(); - if (isUndef(Opcode, {SDValue(N1, 0), SDValue(N2, 0)})) + // For now, the array Ops should only contain two values. + // This enforcement will be removed once this function is merged with + // FoldConstantVectorArithmetic + if (Ops.size() != 2) { + return SDValue(); + } + + if (isUndef(Opcode, Ops)) return getUNDEF(VT); + SDNode *N1 = Ops[0].getNode(); + SDNode *N2 = Ops[1].getNode(); + // Handle the case of two scalars. if (auto *C1 = dyn_cast(N1)) { if (auto *C2 = dyn_cast(N2)) { @@ -5448,8 +5458,7 @@ } // Perform trivial constant folding. - if (SDValue SV = - FoldConstantArithmetic(Opcode, DL, VT, N1.getNode(), N2.getNode())) + if (SDValue SV = FoldConstantArithmetic(Opcode, DL, VT, {N1, N2})) return SV; if (SDValue V = foldConstantFPMath(Opcode, DL, VT, N1, N2)) diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -253,7 +253,7 @@ SDLoc DL(Node); SDValue NegC = CurDAG->FoldConstantArithmetic( - ISD::SUB, DL, VT, CurDAG->getConstant(0, DL, VT).getNode(), C.getNode()); + ISD::SUB, DL, VT, {CurDAG->getConstant(0, DL, VT), C}); assert(NegC && "Constant-folding failed!"); SDValue NewNode = CurDAG->getNode(ISD::SUB, DL, VT, X, NegC); diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -5549,8 +5549,7 @@ SDValue O1 = UserO1.getNode() == N ? Val : UserO1; return CurDAG->FoldConstantArithmetic(User->getOpcode(), dl, - User->getValueType(0), - O0.getNode(), O1.getNode()); + User->getValueType(0), {O0, O1}); }; // FIXME: When the semantics of the interaction between select and undef