X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FDAGCombiner.cpp;h=f119023d217b03ea185eb29990623f5f498b1469;hp=bc2405b952a60dd6d90ea2c8b447ce40709655a5;hb=20a42bb20d43b80e322c95dd99b64a5a4566fe08;hpb=0fcad92ee35f13d1d7f4da235f11c684e95640b8 diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index bc2405b952a..f119023d217 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -924,6 +924,62 @@ CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO) { bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) { TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations); APInt KnownZero, KnownOne; + + // XXX-disabled: + auto Opcode = Op.getOpcode(); + if (Opcode == ISD::AND || Opcode == ISD::OR) { + auto* Op1 = Op.getOperand(0).getNode(); + auto* Op2 = Op.getOperand(1).getNode(); + auto* Op1C = dyn_cast(Op1); + auto* Op2C = dyn_cast(Op2); + + // and X, 0 + if (Opcode == ISD::AND && !Op1C && Op2C && Op2C->isNullValue()) { + return false; + } + + // or (and X, 0), Y + if (Opcode == ISD::OR) { + if (Op1->getOpcode() == ISD::AND) { + auto* Op11 = Op1->getOperand(0).getNode(); + auto* Op12 = Op1->getOperand(1).getNode(); + auto* Op11C = dyn_cast(Op11); + auto* Op12C = dyn_cast(Op12); + if (!Op11C && Op12C && Op12C->isNullValue()) { + return false; + } + } + if (Op1->getOpcode() == ISD::TRUNCATE) { + // or (trunc (and %0, 0)), Y + auto* Op11 = Op1->getOperand(0).getNode(); + if (Op11->getOpcode() == ISD::AND) { + auto* Op111 = Op11->getOperand(0).getNode(); + auto* Op112 = Op11->getOperand(1).getNode(); + auto* Op111C = dyn_cast(Op111); + auto* Op112C = dyn_cast(Op112); + if (!Op111C && Op112C && Op112C->isNullValue()) { + // or (and X, 0), Y + return false; + } + } + } + } + } + + // trunc (and X, 0) + if (Opcode == ISD::TRUNCATE) { + auto* Op1 = Op.getOperand(0).getNode(); + if (Op1->getOpcode() == ISD::AND) { + auto* Op11 = Op1->getOperand(0).getNode(); + auto* Op12 = Op1->getOperand(1).getNode(); + auto* Op11C = dyn_cast(Op11); + auto* Op12C = dyn_cast(Op12); + if (!Op11C && Op12C && Op12C->isNullValue()) { + return false; + } + } + } + if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO)) return false; @@ -3042,6 +3098,22 @@ SDValue DAGCombiner::visitAND(SDNode *N) { // fold (and c1, c2) -> c1&c2 ConstantSDNode *N0C = getAsNonOpaqueConstant(N0); ConstantSDNode *N1C = dyn_cast(N1); + + // XXX-disabled: (and x, 0) should not be folded. + // (and (and x, 0), y) shouldn't either. + if (!N0C && N1C && N1C->isNullValue()) { + return SDValue(); + } + if (!N0C) { + if (N0.getOpcode() == ISD::AND) { + auto* N01 = N0.getOperand(1).getNode(); + auto* N01C = dyn_cast(N01); + if (N01C && N01C->isNullValue()) { + return SDValue(); + } + } + } + if (N0C && N1C && !N1C->isOpaque()) return DAG.FoldConstantArithmetic(ISD::AND, SDLoc(N), VT, N0C, N1C); // canonicalize constant to RHS @@ -7325,6 +7397,7 @@ SDValue DAGCombiner::visitBITCAST(SDNode *N) { // fold (bitcast (fneg x)) -> // flipbit = signbit // (xor (bitcast x) (build_pair flipbit, flipbit)) + // // fold (bitcast (fabs x)) -> // flipbit = (and (extract_element (bitcast x), 0), signbit) // (xor (bitcast x) (build_pair flipbit, flipbit)) @@ -8794,20 +8867,21 @@ SDValue DAGCombiner::visitFSQRT(SDNode *N) { ZeroCmp, Zero, RV); } +/// copysign(x, fp_extend(y)) -> copysign(x, y) +/// copysign(x, fp_round(y)) -> copysign(x, y) static inline bool CanCombineFCOPYSIGN_EXTEND_ROUND(SDNode *N) { - // copysign(x, fp_extend(y)) -> copysign(x, y) - // copysign(x, fp_round(y)) -> copysign(x, y) - // Do not optimize out type conversion of f128 type yet. - // For some target like x86_64, configuration is changed - // to keep one f128 value in one SSE register, but - // instruction selection cannot handle FCOPYSIGN on - // SSE registers yet. SDValue N1 = N->getOperand(1); - EVT N1VT = N1->getValueType(0); - EVT N1Op0VT = N1->getOperand(0)->getValueType(0); - return (N1.getOpcode() == ISD::FP_EXTEND || - N1.getOpcode() == ISD::FP_ROUND) && - (N1VT == N1Op0VT || N1Op0VT != MVT::f128); + if ((N1.getOpcode() == ISD::FP_EXTEND || + N1.getOpcode() == ISD::FP_ROUND)) { + // Do not optimize out type conversion of f128 type yet. + // For some targets like x86_64, configuration is changed to keep one f128 + // value in one SSE register, but instruction selection cannot handle + // FCOPYSIGN on SSE registers yet. + EVT N1VT = N1->getValueType(0); + EVT N1Op0VT = N1->getOperand(0)->getValueType(0); + return (N1VT == N1Op0VT || N1Op0VT != MVT::f128); + } + return false; } SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {