From ae89bb14431c6df4f784ae1af7019e72ec79b3ca Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 11 Nov 2008 08:25:46 +0000 Subject: [PATCH] Fix for PR3040: The CC was changed, but wasn't checked to see if it was legal if the DAG combiner was being run after legalization. Threw in a couple of checks just to make sure that it's okay. As far as the PR is concerned, no back-end target actually exhibited this problem, so there isn't an associated testcase. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59035 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 53 ++++++++++++++++-------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0b6809b56f1..eb6481c996a 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -892,16 +892,18 @@ SDValue combineShlAddConstant(SDValue N0, SDValue N1, SelectionDAG &DAG) { static SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, - SelectionDAG &DAG) { + SelectionDAG &DAG, const TargetLowering &TLI, + bool AfterLegalize) { MVT VT = N->getValueType(0); unsigned Opc = N->getOpcode(); bool isSlctCC = Slct.getOpcode() == ISD::SELECT_CC; SDValue LHS = isSlctCC ? Slct.getOperand(2) : Slct.getOperand(1); SDValue RHS = isSlctCC ? Slct.getOperand(3) : Slct.getOperand(2); ISD::CondCode CC = ISD::SETCC_INVALID; - if (isSlctCC) + + if (isSlctCC) { CC = cast(Slct.getOperand(4))->get(); - else { + } else { SDValue CCOp = Slct.getOperand(0); if (CCOp.getOpcode() == ISD::SETCC) CC = cast(CCOp.getOperand(2))->get(); @@ -911,17 +913,23 @@ SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, bool InvCC = false; assert ((Opc == ISD::ADD || (Opc == ISD::SUB && Slct == N->getOperand(1))) && "Bad input!"); + if (LHS.getOpcode() == ISD::Constant && - cast(LHS)->isNullValue()) + cast(LHS)->isNullValue()) { DoXform = true; - else if (CC != ISD::SETCC_INVALID && - RHS.getOpcode() == ISD::Constant && - cast(RHS)->isNullValue()) { + } else if (CC != ISD::SETCC_INVALID && + RHS.getOpcode() == ISD::Constant && + cast(RHS)->isNullValue()) { std::swap(LHS, RHS); SDValue Op0 = Slct.getOperand(0); - bool isInt = (isSlctCC ? Op0.getValueType() : - Op0.getOperand(0).getValueType()).isInteger(); + MVT OpVT = isSlctCC ? Op0.getValueType() : + Op0.getOperand(0).getValueType(); + bool isInt = OpVT.isInteger(); CC = ISD::getSetCCInverse(CC, isInt); + + if (AfterLegalize && !TLI.isCondCodeLegal(CC, OpVT)) + return SDValue(); // Inverse operator isn't legal. + DoXform = true; InvCC = true; } @@ -1029,11 +1037,11 @@ SDValue DAGCombiner::visitADD(SDNode *N) { // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c)) if (N0.getOpcode() == ISD::SELECT && N0.getNode()->hasOneUse()) { - SDValue Result = combineSelectAndUse(N, N0, N1, DAG); + SDValue Result = combineSelectAndUse(N, N0, N1, DAG, TLI, AfterLegalize); if (Result.getNode()) return Result; } if (N1.getOpcode() == ISD::SELECT && N1.getNode()->hasOneUse()) { - SDValue Result = combineSelectAndUse(N, N1, N0, DAG); + SDValue Result = combineSelectAndUse(N, N1, N0, DAG, TLI, AfterLegalize); if (Result.getNode()) return Result; } @@ -1131,7 +1139,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) { return N0.getOperand(0); // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c)) if (N1.getOpcode() == ISD::SELECT && N1.getNode()->hasOneUse()) { - SDValue Result = combineSelectAndUse(N, N1, N0, DAG); + SDValue Result = combineSelectAndUse(N, N1, N0, DAG, TLI, AfterLegalize); if (Result.getNode()) return Result; } // If either operand of a sub is undef, the result is undef @@ -2156,18 +2164,27 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { SDValue RXOR = ReassociateOps(ISD::XOR, N0, N1); if (RXOR.getNode() != 0) return RXOR; + // fold !(x cc y) -> (x !cc y) if (N1C && N1C->getAPIntValue() == 1 && isSetCCEquivalent(N0, LHS, RHS, CC)) { bool isInt = LHS.getValueType().isInteger(); ISD::CondCode NotCC = ISD::getSetCCInverse(cast(CC)->get(), isInt); - if (N0.getOpcode() == ISD::SETCC) - return DAG.getSetCC(VT, LHS, RHS, NotCC); - if (N0.getOpcode() == ISD::SELECT_CC) - return DAG.getSelectCC(LHS, RHS, N0.getOperand(2),N0.getOperand(3),NotCC); - assert(0 && "Unhandled SetCC Equivalent!"); - abort(); + + if (!AfterLegalize || TLI.isCondCodeLegal(NotCC, LHS.getValueType())) { + switch (N0.getOpcode()) { + default: + assert(0 && "Unhandled SetCC Equivalent!"); + abort(); + case ISD::SETCC: + return DAG.getSetCC(VT, LHS, RHS, NotCC); + case ISD::SELECT_CC: + return DAG.getSelectCC(LHS, RHS, N0.getOperand(2), + N0.getOperand(3), NotCC); + } + } } + // fold (not (zext (setcc x, y))) -> (zext (not (setcc x, y))) if (N1C && N1C->getAPIntValue() == 1 && N0.getOpcode() == ISD::ZERO_EXTEND && N0.getNode()->hasOneUse() && -- 2.34.1