Index: llvm/include/llvm/CodeGen/SelectionDAG.h =================================================================== --- llvm/include/llvm/CodeGen/SelectionDAG.h +++ llvm/include/llvm/CodeGen/SelectionDAG.h @@ -926,6 +926,9 @@ /// BooleanContent for type OpVT or truncating it. SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT); + /// Create negative operation as (SUB 0, Val). + SDValue getNegative(SDValue Val, const SDLoc &DL, EVT VT); + /// Create a bitwise NOT operation as (XOR Val, -1). SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT); Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3981,8 +3981,7 @@ // fold (mul x, -1) -> 0-x if (N1IsConst && ConstValue1.isAllOnes()) - return DAG.getNode(ISD::SUB, DL, VT, - DAG.getConstant(0, DL, VT), N0); + return DAG.getNegative(N0, DL, VT); // fold (mul x, (1 << c)) -> x << c if (isConstantOrConstantVector(N1, /*NoOpaques*/ true) && @@ -4049,7 +4048,7 @@ DAG.getConstant(TZeros, DL, VT))) : DAG.getNode(MathOp, DL, VT, Shl, N0); if (ConstValue1.isNegative()) - R = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), R); + R = DAG.getNegative(R, DL, VT); return R; } } @@ -4303,7 +4302,7 @@ // fold (sdiv X, -1) -> 0-X ConstantSDNode *N1C = isConstOrConstSplat(N1); if (N1C && N1C->isAllOnes()) - return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), N0); + return DAG.getNegative(N0, DL, VT); // fold (sdiv X, MIN_SIGNED) -> select(X == MIN_SIGNED, 1, 0) if (N1C && N1C->getAPIntValue().isMinSignedValue()) @@ -8682,8 +8681,7 @@ // fold (not (add X, -1)) -> (neg X) if (isAllOnesConstant(N1) && N0.getOpcode() == ISD::ADD && isAllOnesOrAllOnesSplat(N0.getOperand(1))) { - return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), - N0.getOperand(0)); + return DAG.getNegative(N0.getOperand(0), DL, VT); } // fold (xor (and x, y), y) -> (and (not x), y) @@ -11305,8 +11303,7 @@ if (SatCC == ISD::SETUGT && Other.getOpcode() == ISD::ADD && ISD::matchBinaryPredicate(OpRHS, CondRHS, MatchUSUBSAT, /*AllowUndefs*/ true)) { - OpRHS = DAG.getNode(ISD::SUB, DL, VT, - DAG.getConstant(0, DL, VT), OpRHS); + OpRHS = DAG.getNegative(OpRHS, DL, VT); return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS); } @@ -12394,7 +12391,7 @@ N0.getOperand(1).getOpcode() == ISD::ZERO_EXTEND && TLI.isOperationLegalOrCustom(ISD::SUB, VT)) { SDValue Zext = DAG.getZExtOrTrunc(N0.getOperand(1).getOperand(0), DL, VT); - return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Zext); + return DAG.getNegative(Zext, DL, VT); } // Eliminate this sign extend by doing a decrement in the destination type: // sext i32 ((zext i8 X to i32) + (-1)) to i64 --> (zext i8 X to i64) + (-1) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1461,6 +1461,10 @@ return getZeroExtendInReg(Op, DL, VT); } +SDValue SelectionDAG::getNegative(SDValue Val, const SDLoc &DL, EVT VT) { + return getNode(ISD::SUB, DL, VT, getConstant(0, DL, VT), Val); +} + /// getNOT - Create a bitwise NOT operation as (XOR Val, -1). SDValue SelectionDAG::getNOT(const SDLoc &DL, SDValue Val, EVT VT) { return getNode(ISD::XOR, DL, VT, Val, getAllOnesConstant(DL, VT)); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3421,8 +3421,7 @@ Values[i] = DAG.getNode(OpCode, dl, VT, LHSVal.getValue(LHSVal.getResNo() + i)); if (Negate) - Values[i] = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, dl, VT), - Values[i]); + Values[i] = DAG.getNegative(Values[i], dl, VT); } } else { for (unsigned i = 0; i != NumValues; ++i) { Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3241,8 +3241,7 @@ // For CTTZ_ZERO_UNDEF, we need to extract the lowest set bit using X & -X. // The trailing zero count is equal to log2 of this single bit value. if (Op.getOpcode() == ISD::CTTZ_ZERO_UNDEF) { - SDValue Neg = - DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Src); + SDValue Neg = DAG.getNegative(Src, DL, VT); Src = DAG.getNode(ISD::AND, DL, VT, Src, Neg); } @@ -8194,8 +8193,7 @@ DAG.ComputeNumSignBits(Src.getOperand(0)) > 32) { SDLoc DL(N); SDValue Freeze = DAG.getFreeze(Src.getOperand(0)); - SDValue Neg = - DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, MVT::i64), Freeze); + SDValue Neg = DAG.getNegative(Freeze, DL, VT); Neg = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, Neg, DAG.getValueType(MVT::i32)); return DAG.getNode(ISD::SMAX, DL, MVT::i64, Freeze, Neg); @@ -9070,8 +9068,7 @@ DAG.getConstant(1, DL, VT)); else Neg = LHS; - SDValue Mask = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), - Neg); // -(and (x, 0x1)) + SDValue Mask = DAG.getNegative(Neg, DL, VT); // -x SDValue And = DAG.getNode(ISD::AND, DL, VT, Mask, Src1); // Mask & z return DAG.getNode(Opcode, DL, VT, And, Src2); // And Op y }