Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3871,30 +3871,32 @@ } // Hoist one-use addition by non-opaque constant: - // (x + C) - y -> (x - y) + C - if (N0.getOpcode() == ISD::ADD && N0.hasOneUse() && - isConstantOrConstantVector(N0.getOperand(1), /*NoOpaques=*/true)) { - SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), N1); - return DAG.getNode(ISD::ADD, DL, VT, Sub, N0.getOperand(1)); - } - // y - (x + C) -> (y - x) - C - if (N1.getOpcode() == ISD::ADD && N1.hasOneUse() && - isConstantOrConstantVector(N1.getOperand(1), /*NoOpaques=*/true)) { - SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, N1.getOperand(0)); - return DAG.getNode(ISD::SUB, DL, VT, Sub, N1.getOperand(1)); - } - // (x - C) - y -> (x - y) - C - // This is necessary because SUB(X,C) -> ADD(X,-C) doesn't work for vectors. - if (N0.getOpcode() == ISD::SUB && N0.hasOneUse() && - isConstantOrConstantVector(N0.getOperand(1), /*NoOpaques=*/true)) { - SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), N1); - return DAG.getNode(ISD::SUB, DL, VT, Sub, N0.getOperand(1)); - } - // (C - x) - y -> C - (x + y) - if (N0.getOpcode() == ISD::SUB && N0.hasOneUse() && - isConstantOrConstantVector(N0.getOperand(0), /*NoOpaques=*/true)) { - SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(1), N1); - return DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), Add); + if (N0->isDivergent() == N1->isDivergent()) { + // (x + C) - y -> (x - y) + C + if (N0.getOpcode() == ISD::ADD && N0.hasOneUse() && + isConstantOrConstantVector(N0.getOperand(1), /*NoOpaques=*/true)) { + SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), N1); + return DAG.getNode(ISD::ADD, DL, VT, Sub, N0.getOperand(1)); + } + // y - (x + C) -> (y - x) - C + if (N1.getOpcode() == ISD::ADD && N1.hasOneUse() && + isConstantOrConstantVector(N1.getOperand(1), /*NoOpaques=*/true)) { + SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, N1.getOperand(0)); + return DAG.getNode(ISD::SUB, DL, VT, Sub, N1.getOperand(1)); + } + // (x - C) - y -> (x - y) - C + // This is necessary because SUB(X,C) -> ADD(X,-C) doesn't work for vectors. + if (N0.getOpcode() == ISD::SUB && N0.hasOneUse() && + isConstantOrConstantVector(N0.getOperand(1), /*NoOpaques=*/true)) { + SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), N1); + return DAG.getNode(ISD::SUB, DL, VT, Sub, N0.getOperand(1)); + } + // (C - x) - y -> C - (x + y) + if (N0.getOpcode() == ISD::SUB && N0.hasOneUse() && + isConstantOrConstantVector(N0.getOperand(0), /*NoOpaques=*/true)) { + SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(1), N1); + return DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), Add); + } } // If the target's bool is represented as 0/-1, prefer to make this 'add 0/-1'