[llvm] ec78f0d - [X86] combineAndNotOrIntoAndNotAnd - don't attempt with constant operands

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 15 08:55:28 PDT 2024


Author: Simon Pilgrim
Date: 2024-10-15T16:54:08+01:00
New Revision: ec78f0da0e9b1b8e2b2323e434ea742e272dd913

URL: https://github.com/llvm/llvm-project/commit/ec78f0da0e9b1b8e2b2323e434ea742e272dd913
DIFF: https://github.com/llvm/llvm-project/commit/ec78f0da0e9b1b8e2b2323e434ea742e272dd913.diff

LOG: [X86] combineAndNotOrIntoAndNotAnd - don't attempt with constant operands

Don't fold AND(X,OR(NOT(Z),C)) -> AND(X,NOT(AND(Z,C'))) as DAGCombiner will invert it back again.

Fixes #112347

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/pr108731.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a24c65bcf1383f..5b4b27c888952c 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -50049,12 +50049,15 @@ static SDValue combineAndNotOrIntoAndNotAnd(SDNode *N, SelectionDAG &DAG) {
     return SDValue();
 
   SDValue X, Y, Z;
-  if (sd_match(
-          N, m_And(m_Value(X), m_OneUse(m_Or(m_Value(Y), m_Not(m_Value(Z)))))))
-    return DAG.getNode(
-        ISD::AND, DL, VT, X,
-        DAG.getNOT(DL, DAG.getNode(ISD::AND, DL, VT, DAG.getNOT(DL, Y, VT), Z),
-                   VT));
+  if (sd_match(N, m_And(m_Value(X),
+                        m_OneUse(m_Or(m_Value(Y), m_Not(m_Value(Z))))))) {
+    // Don't fold if Y is a constant to prevent infinite loops.
+    if (!isa<ConstantSDNode>(Y))
+      return DAG.getNode(
+          ISD::AND, DL, VT, X,
+          DAG.getNOT(
+              DL, DAG.getNode(ISD::AND, DL, VT, DAG.getNOT(DL, Y, VT), Z), VT));
+  }
 
   return SDValue();
 }

diff  --git a/llvm/test/CodeGen/X86/pr108731.ll b/llvm/test/CodeGen/X86/pr108731.ll
index 1c6d2deb701afa..87dce0314d08e2 100644
--- a/llvm/test/CodeGen/X86/pr108731.ll
+++ b/llvm/test/CodeGen/X86/pr108731.ll
@@ -57,5 +57,23 @@ Entry:
   %and3 = and <16 x i8> %and2, %or1
   ret <16 x i8> %and3
 }
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK: {{.*}}
+
+; PR112347 - don't fold if we'd be inverting a constant, as demorgan normalisation will invert it back again.
+define void @PR112347(ptr %p0, ptr %p1, ptr %p2) {
+; CHECK-LABEL: PR112347:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl (%rdi), %eax
+; CHECK-NEXT:    notl %eax
+; CHECK-NEXT:    orl $-16777204, %eax # imm = 0xFF00000C
+; CHECK-NEXT:    andl (%rsi), %eax
+; CHECK-NEXT:    movl %eax, (%rdx)
+; CHECK-NEXT:    retq
+  %load0 = load i32, ptr %p0, align 1
+  %load1 = load i32, ptr %p1, align 4
+  %not = xor i32 %load0, -1
+  %top = or i32 %not, -16777204
+  %mask = and i32 %load1, %top
+  store i32 %mask, ptr %p2, align 4
+  ret void
+}
+


        


More information about the llvm-commits mailing list