Index: include/llvm/CodeGen/ISDOpcodes.h =================================================================== --- include/llvm/CodeGen/ISDOpcodes.h +++ include/llvm/CodeGen/ISDOpcodes.h @@ -49,6 +49,12 @@ /// operators are independent of each other. TokenFactor, + /// This node records if a register contains a value that has been masked + /// by an and with constant. This node takes two operands. The first is + /// the node that has already been masked by an and operation, and the + /// second is the constant mask that was used. + AssertAnd, + /// AssertSext, AssertZext - These nodes record if a register contains a /// value that has already been zero or sign extended from a narrower type. /// These nodes take two operands. The first is the node that has already Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2034,6 +2034,7 @@ KnownOne = cast(Op)->getAPIntValue(); KnownZero = ~KnownOne; break; + case ISD::AssertAnd: case ISD::AND: // If either the LHS or the RHS are Zero, the result is zero. computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); @@ -2537,6 +2538,7 @@ return Tmp - C->getZExtValue(); } break; + case ISD::AssertAnd: case ISD::AND: case ISD::OR: case ISD::XOR: // NOT is handled here. @@ -3452,6 +3454,13 @@ isa(N2) && "Invalid FP_ROUND!"); if (N1.getValueType() == VT) return N1; // noop conversion. break; + case ISD::AssertAnd: { + ConstantSDNode *C2 = cast(N2); + assert(N1.getValueType() == N2.getValueType() && + N1.getValueType() == VT && "Binary operator types must match!"); + if (C2->isAllOnesValue()) return N1; // noop mask. + break; + } case ISD::AssertSext: case ISD::AssertZext: { EVT EVT = cast(N2)->getVT(); Index: lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -76,6 +76,7 @@ case ISD::MDNODE_SDNODE: return "MDNode"; case ISD::EntryToken: return "EntryToken"; case ISD::TokenFactor: return "TokenFactor"; + case ISD::AssertAnd: return "AssertAnd"; case ISD::AssertSext: return "AssertSext"; case ISD::AssertZext: return "AssertZext"; Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2575,6 +2575,7 @@ case ISD::LIFETIME_END: NodeToMatch->setNodeId(-1); // Mark selected. return nullptr; + case ISD::AssertAnd: case ISD::AssertSext: case ISD::AssertZext: CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, 0),