[llvm] [X86] combineOr - undemand and freeze elements if the other operand's element is allones (PR #215538)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 06:10:46 PDT 2026


================
@@ -53857,27 +53857,25 @@ static SDValue combineOr(SDNode *N, SelectionDAG &DAG,
     if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
       return Res;
 
-    // If either operand is a constant mask, then only the elements that aren't
-    // allones are actually demanded by the other operand.
-    auto SimplifyUndemandedElts = [&](SDValue Op, SDValue OtherOp) {
-      APInt UndefElts;
-      SmallVector<APInt> EltBits;
-      int NumElts = VT.getVectorNumElements();
-      int EltSizeInBits = VT.getScalarSizeInBits();
-      if (!getTargetConstantBitsFromNode(Op, EltSizeInBits, UndefElts, EltBits))
-        return false;
-
+    // If second operand is a constant mask, then only the elements that aren't
+    // allones are actually demanded by the first operand.
+    APInt UndefElts;
+    SmallVector<APInt> EltBits;
+    int NumElts = VT.getVectorNumElements();
+    int EltSizeInBits = VT.getScalarSizeInBits();
+    if (getTargetConstantBitsFromNode(N1, EltSizeInBits, UndefElts, EltBits)) {
       APInt DemandedElts = APInt::getZero(NumElts);
       for (int I = 0; I != NumElts; ++I)
         if (!EltBits[I].isAllOnes())
           DemandedElts.setBit(I);
 
-      return TLI.SimplifyDemandedVectorElts(OtherOp, DemandedElts, DCI);
-    };
-    if (SimplifyUndemandedElts(N0, N1) || SimplifyUndemandedElts(N1, N0)) {
-      if (N->getOpcode() != ISD::DELETED_NODE)
-        DCI.AddToWorklist(N);
-      return SDValue(N, 0);
+      // We must freeze the result to prevent OR(poison,-1) -> poison.
+      if (!DemandedElts.isAllOnes() && N0.getOpcode() != ISD::FREEZE &&
+          TLI.SimplifyDemandedVectorElts(N0, DemandedElts, DCI)) {
----------------
RKSimon wrote:

I don't trust this - we can still have cases where a FREEZE is further up the chain, SimplifyDemandedVectorElts then removes it and we just add it back again.... I'll take another look.

We have similar code for ISD::AND and X86ISD::ANDNP nodes and they suffer some the same issue :/ More aggressive creation of ISD::POISON in DAG is exposing a lot of issues.

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


More information about the llvm-commits mailing list