[PATCH] D46494: [DAGCombiner] Masked merge: enhance handling of 'andn' with immediates

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat May 5 04:29:34 PDT 2018


lebedev.ri created this revision.
lebedev.ri added reviewers: spatel, craig.topper.
lebedev.ri added a dependency: D46493: [DagCombiner] Not all 'andn''s work with immediates..

Split off from https://reviews.llvm.org/D46031.

The previous patch, https://reviews.llvm.org/D46493, completely disabled unfolding in case of immediates.
But we can do better:
F6108843: previous-patch-vs-patch.txt <https://reviews.llvm.org/F6108843> F6108842: trunk-vs-patch.txt <https://reviews.llvm.org/F6108842>


Repository:
  rL LLVM

https://reviews.llvm.org/D46494

Files:
  lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll


Index: test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll
===================================================================
--- test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll
+++ test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll
@@ -655,10 +655,10 @@
 ;
 ; CHECK-BMI-LABEL: in_constant_varx_42:
 ; CHECK-BMI:       # %bb.0:
-; CHECK-BMI-NEXT:    xorl $42, %edi
-; CHECK-BMI-NEXT:    andl %edx, %edi
-; CHECK-BMI-NEXT:    xorl $42, %edi
 ; CHECK-BMI-NEXT:    movl %edi, %eax
+; CHECK-BMI-NEXT:    xorl $42, %eax
+; CHECK-BMI-NEXT:    andnl %eax, %edx, %eax
+; CHECK-BMI-NEXT:    orl %edi, %eax
 ; CHECK-BMI-NEXT:    retq
   %n0 = xor i32 %x, 42 ; %x
   %n1 = and i32 %n0, %mask
@@ -700,9 +700,10 @@
 ;
 ; CHECK-BMI-LABEL: in_constant_varx_42_invmask:
 ; CHECK-BMI:       # %bb.0:
-; CHECK-BMI-NEXT:    xorl $42, %edi
-; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
+; CHECK-BMI-NEXT:    movl %edi, %eax
 ; CHECK-BMI-NEXT:    xorl $42, %eax
+; CHECK-BMI-NEXT:    andl %edx, %eax
+; CHECK-BMI-NEXT:    orl %edi, %eax
 ; CHECK-BMI-NEXT:    retq
   %notmask = xor i32 %mask, -1
   %n0 = xor i32 %x, 42 ; %x
Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -5387,8 +5387,9 @@
 
   // There are 3 commutable operators in the pattern,
   // so we have to deal with 8 possible variants of the basic pattern.
-  SDValue X, Y, M;
-  auto matchAndXor = [&X, &Y, &M](SDValue And, unsigned XorIdx, SDValue Other) {
+  SDValue A, D, X, Y, M;
+  auto matchAndXor = [&A, &D, &X, &Y, &M](SDValue And, unsigned XorIdx,
+                                          SDValue Other) {
     if (And.getOpcode() != ISD::AND || !And.hasOneUse())
       return false;
     SDValue Xor = And.getOperand(XorIdx);
@@ -5403,16 +5404,18 @@
       std::swap(Xor0, Xor1);
     if (Other != Xor1)
       return false;
+    A = And;
+    D = Xor;
     X = Xor0;
     Y = Xor1;
     M = And.getOperand(XorIdx ? 0 : 1);
     return true;
   };
 
-  SDValue A = N->getOperand(0);
-  SDValue B = N->getOperand(1);
-  if (!matchAndXor(A, 0, B) && !matchAndXor(A, 1, B) && !matchAndXor(B, 0, A) &&
-      !matchAndXor(B, 1, A))
+  SDValue A_ = N->getOperand(0);
+  SDValue B_ = N->getOperand(1);
+  if (!matchAndXor(A_, 0, B_) && !matchAndXor(A_, 1, B_) &&
+      !matchAndXor(B_, 0, A_) && !matchAndXor(B_, 1, A_))
     return SDValue();
 
   // Don't do anything if the mask is constant. This should not be reachable.
@@ -5425,16 +5428,19 @@
   if (!TLI.hasAndNot(M))
     return SDValue();
 
-  // If Y is a constant, check that 'andn' works with immediates.
-  if (!TLI.hasAndNot(Y))
-    return SDValue();
-
   SDLoc DL(N);
+  SDValue NotM = DAG.getNOT(DL, M, VT);
+
+  // If Y is a constant, check that 'andn' works with immediates.
+  if (!TLI.hasAndNot(Y)) {
+    assert(TLI.hasAndNot(X) && "Only mask is a variable? Unreachable.");
+    // If not, de-canonicalze (Invert) the mask, swap the value in B part.
+    SDValue NewA = DAG.getNode(ISD::AND, DL, VT, D, NotM);
+    return DAG.getNode(ISD::OR, DL, VT, NewA, X);
+  }
 
   SDValue LHS = DAG.getNode(ISD::AND, DL, VT, X, M);
-  SDValue NotM = DAG.getNOT(DL, M, VT);
   SDValue RHS = DAG.getNode(ISD::AND, DL, VT, Y, NotM);
-
   return DAG.getNode(ISD::OR, DL, VT, LHS, RHS);
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46494.145365.patch
Type: text/x-patch
Size: 3391 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180505/6589183f/attachment.bin>


More information about the llvm-commits mailing list