From e05a560931eb64d955a2381c2c88256a710869c1 Mon Sep 17 00:00:00 2001 From: Rose Date: Wed, 9 Jul 2025 21:04:24 -0400 Subject: [PATCH] [SelectionDAG] fold (not (sub Y, X)) -> (add X, ~Y) This replaces (not (neg x)) -> (add X, -1) because that is covered by this. --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9ffdda28f7899..b74903564f785 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -9979,13 +9979,15 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { } } - // fold (not (neg x)) -> (add X, -1) - // FIXME: This can be generalized to (not (sub Y, X)) -> (add X, ~Y) if - // Y is a constant or the subtract has a single use. - if (isAllOnesConstant(N1) && N0.getOpcode() == ISD::SUB && - isNullConstant(N0.getOperand(0))) { - return DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(1), - DAG.getAllOnesConstant(DL, VT)); + // fold (not (sub Y, X)) -> (add X, ~Y) if Y is a constant. + // FIXME: We can also do this with single-use sub, but this causes an infinite + // loop + if (isAllOnesConstant(N1) && N0.getOpcode() == ISD::SUB) { + SDValue N00 = N0.getOperand(0), N01 = N0.getOperand(1); + if (isa(N00)) { + SDValue NotY = DAG.getNOT(DL, N00, VT); // N00 = ~N00 + return DAG.getNode(ISD::ADD, DL, VT, N01, NotY); + } } // fold (not (add X, -1)) -> (neg X)