[llvm] [DAG] canCreateUndefOrPoison/isGuaranteedNotToBeUndefOrPoison - SCALAR_TO_VECTOR upper elements are poison (PR #217185)

Cyrus Ding via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 19:55:53 PDT 2026


================
@@ -3352,11 +3352,9 @@ bool TargetLowering::SimplifyDemandedVectorElts(
 
   switch (Opcode) {
   case ISD::SCALAR_TO_VECTOR: {
-    if (!DemandedElts[0]) {
-      KnownUndef.setAllBits();
-      return TLO.CombineTo(Op, TLO.DAG.getUNDEF(VT));
-    }
-    KnownUndef.setHighBits(NumElts - 1);
+    if (!DemandedElts[0])
+      return TLO.CombineTo(Op, TLO.DAG.getPOISON(VT));
+    // Upper elements are poison, not undef - don't mark them as KnownUndef.
----------------
dingcyrus wrote:

Thanks Björn — both fair points.

On the wording: you're right that ", not undef" reads as a lattice claim and is wrong under the poison-refines-undef reading; the intent was purely operational ("must not be *treated as* undef by undef-keyed folds"). I'll drop it in a small NFC comment fix.

On the reasoning: KnownUndef bits license folds that substitute a chosen concrete value for those bits — e.g. the ZERO_EXTEND / ZERO_EXTEND_VECTOR_INREG `zext(undef) -> 0` fold via `DemandedElts.isSubsetOf(KnownUndef)`, and the x86 shuffle `AND(0, undef) -> 0` combine Simon mentions. That substitution is valid for undef (each use may pick a value) but not for poison: consuming a poison lane yields poison, so the bits must stay unknown rather than KnownUndef. Marking them KnownUndef pre-#217185 was exactly what let `zext(stv(x))` fold to zero incorrectly.

NFC rewording patch coming shortly; happy to also extend the comment with the fold examples if that's useful.

https://github.com/llvm/llvm-project/pull/217185


More information about the llvm-commits mailing list