@@ -5519,8 +5519,9 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
55195519      APInt InVecDemandedElts = DemandedElts;
55205520      InVecDemandedElts.clearBit(IndexC->getZExtValue());
55215521      if (!!InVecDemandedElts &&
5522-           !isGuaranteedNotToBeUndefOrPoison(InVec, InVecDemandedElts,
5523-                                             PoisonOnly, Depth + 1))
5522+           !isGuaranteedNotToBeUndefOrPoison(
5523+               peekThroughInsertVectorElt(InVec, InVecDemandedElts),
5524+               InVecDemandedElts, PoisonOnly, Depth + 1))
55245525        return false;
55255526      return true;
55265527    }
@@ -8219,23 +8220,42 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
82198220    // INSERT_VECTOR_ELT into out-of-bounds element is an UNDEF, except
82208221    // for scalable vectors where we will generate appropriate code to
82218222    // deal with out-of-bounds cases correctly.
8222-     if (N3C && N1.getValueType() .isFixedLengthVector() &&
8223-         N3C->getZExtValue() >= N1.getValueType() .getVectorNumElements())
8223+     if (N3C && VT .isFixedLengthVector() &&
8224+         N3C->getZExtValue() >= VT .getVectorNumElements())
82248225      return getUNDEF(VT);
82258226
82268227    // Undefined index can be assumed out-of-bounds, so that's UNDEF too.
82278228    if (N3.isUndef())
82288229      return getUNDEF(VT);
82298230
8230-     // If the inserted element is an UNDEF , just use the input vector.
8231-     if (N2.isUndef() )
8231+     // If inserting poison , just use the input vector.
8232+     if (N2.getOpcode() == ISD::POISON )
82328233      return N1;
82338234
8235+     // Inserting undef into undef/poison is still undef.
8236+     if (N2.getOpcode() == ISD::UNDEF && N1.isUndef())
8237+       return getUNDEF(VT);
8238+ 
8239+     // If the inserted element is an UNDEF, just use the input vector.
8240+     // But not if skipping the insert could make the result more poisonous.
8241+     if (N2.isUndef()) {
8242+       if (N3C && VT.isFixedLengthVector()) {
8243+         APInt EltMask =
8244+             APInt::getOneBitSet(VT.getVectorNumElements(), N3C->getZExtValue());
8245+         if (isGuaranteedNotToBePoison(N1, EltMask))
8246+           return N1;
8247+       } else if (isGuaranteedNotToBePoison(N1))
8248+         return N1;
8249+     }
82348250    break;
82358251  }
82368252  case ISD::INSERT_SUBVECTOR: {
8237-     // Inserting undef into undef is still undef.
8238-     if (N1.isUndef() && N2.isUndef())
8253+     // If inserting poison, just use the input vector,
8254+     if (N2.getOpcode() == ISD::POISON)
8255+       return N1;
8256+ 
8257+     // Inserting undef into undef/poison is still undef.
8258+     if (N2.getOpcode() == ISD::UNDEF && N1.isUndef())
82398259      return getUNDEF(VT);
82408260
82418261    EVT N2VT = N2.getValueType();
@@ -8264,11 +8284,37 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
82648284    if (VT == N2VT)
82658285      return N2;
82668286
8267-     // If this is an insert of an extracted vector into an undef vector, we
8268-     // can just use the input to the extract.
8287+     // If this is an insert of an extracted vector into an undef/poison vector,
8288+     // we can just use the input to the extract. But not if skipping the
8289+     // extract+insert could make the result more poisonous.
82698290    if (N1.isUndef() && N2.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
8270-         N2.getOperand(1) == N3 && N2.getOperand(0).getValueType() == VT)
8271-       return N2.getOperand(0);
8291+         N2.getOperand(1) == N3 && N2.getOperand(0).getValueType() == VT) {
8292+       if (N1.getOpcode() == ISD::POISON)
8293+         return N2.getOperand(0);
8294+       if (VT.isFixedLengthVector() && N2VT.isFixedLengthVector()) {
8295+         unsigned LoBit = N3->getAsZExtVal();
8296+         unsigned HiBit = LoBit + N2VT.getVectorNumElements();
8297+         APInt EltMask =
8298+             APInt::getBitsSet(VT.getVectorNumElements(), LoBit, HiBit);
8299+         if (isGuaranteedNotToBePoison(N2.getOperand(0), ~EltMask))
8300+           return N2.getOperand(0);
8301+       } else if (isGuaranteedNotToBePoison(N2.getOperand(0)))
8302+         return N2.getOperand(0);
8303+     }
8304+ 
8305+     // If the inserted subvector is UNDEF, just use the input vector.
8306+     // But not if skipping the insert could make the result more poisonous.
8307+     if (N2.isUndef()) {
8308+       if (VT.isFixedLengthVector()) {
8309+         unsigned LoBit = N3->getAsZExtVal();
8310+         unsigned HiBit = LoBit + N2VT.getVectorNumElements();
8311+         APInt EltMask =
8312+             APInt::getBitsSet(VT.getVectorNumElements(), LoBit, HiBit);
8313+         if (isGuaranteedNotToBePoison(N1, EltMask))
8314+           return N1;
8315+       } else if (isGuaranteedNotToBePoison(N1))
8316+         return N1;
8317+     }
82728318    break;
82738319  }
82748320  case ISD::BITCAST:
@@ -12777,6 +12823,23 @@ SDValue llvm::peekThroughExtractSubvectors(SDValue V) {
1277712823  return V;
1277812824}
1277912825
12826+ SDValue llvm::peekThroughInsertVectorElt(SDValue V, const APInt &DemandedElts) {
12827+   while (V.getOpcode() == ISD::INSERT_VECTOR_ELT) {
12828+     SDValue InVec = V.getOperand(0);
12829+     SDValue EltNo = V.getOperand(2);
12830+     EVT VT = InVec.getValueType();
12831+     auto *IndexC = dyn_cast<ConstantSDNode>(EltNo);
12832+     if (IndexC && VT.isFixedLengthVector() &&
12833+         IndexC->getAPIntValue().ult(VT.getVectorNumElements()) &&
12834+         !DemandedElts[IndexC->getZExtValue()]) {
12835+       V = InVec;
12836+       continue;
12837+     }
12838+     break;
12839+   }
12840+   return V;
12841+ }
12842+ 
1278012843SDValue llvm::peekThroughTruncates(SDValue V) {
1278112844  while (V.getOpcode() == ISD::TRUNCATE)
1278212845    V = V.getOperand(0);
0 commit comments