[PATCH] D32255: [InstCombine] prefer xor with -1 because 'not' is easier to understand

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 21 07:16:46 PDT 2017


This revision was automatically updated to reflect the committed changes.
Closed by commit rL300977: [InstCombine] prefer xor with -1 because 'not' is easier to understand (PR32706) (authored by spatel).

Changed prior to commit:
  https://reviews.llvm.org/D32255?vs=95846&id=96136#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D32255

Files:
  llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  llvm/trunk/test/Transforms/InstCombine/xor.ll
  llvm/trunk/test/Transforms/InstCombine/zext.ll


Index: llvm/trunk/test/Transforms/InstCombine/xor.ll
===================================================================
--- llvm/trunk/test/Transforms/InstCombine/xor.ll
+++ llvm/trunk/test/Transforms/InstCombine/xor.ll
@@ -536,3 +536,20 @@
   %xor = xor i32 %and, %B
   ret i32 %xor
 }
+
+; PR32706 - https://bugs.llvm.org/show_bug.cgi?id=32706
+; Pin an xor constant operand to -1 if possible because 'not' is better for SCEV and codegen.
+
+define i32 @not_is_canonical(i32 %x, i32 %y) {
+; CHECK-LABEL: @not_is_canonical(
+; CHECK-NEXT:    [[SUB:%.*]] = xor i32 %x, -1
+; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SUB]], %y
+; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[ADD]], 2
+; CHECK-NEXT:    ret i32 [[MUL]]
+;
+  %sub = xor i32 %x, 1073741823
+  %add = add i32 %sub, %y
+  %mul = shl i32 %add, 2
+  ret i32 %mul
+}
+
Index: llvm/trunk/test/Transforms/InstCombine/zext.ll
===================================================================
--- llvm/trunk/test/Transforms/InstCombine/zext.ll
+++ llvm/trunk/test/Transforms/InstCombine/zext.ll
@@ -35,7 +35,7 @@
 
 define <2 x i64> @test4(<2 x i64> %A) {
 ; CHECK-LABEL: @test4(
-; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i64> %A, <i64 63, i64 63>
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i64> %A, <i64 -1, i64 -1>
 ; CHECK-NEXT:    [[XOR:%.*]] = and <2 x i64> [[TMP1]], <i64 23, i64 42>
 ; CHECK-NEXT:    ret <2 x i64> [[XOR]]
 ;
Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -277,10 +277,20 @@
       return InsertNewInstWith(And, *I);
     }
 
-    // If the RHS is a constant, see if we can simplify it.
-    // FIXME: for XOR, we prefer to force bits to 1 if they will make a -1.
-    if (ShrinkDemandedConstant(I, 1, DemandedMask))
-      return I;
+    // If the RHS is a constant, see if we can change it. Don't alter a -1
+    // constant because that's a canonical 'not' op, and that is better for
+    // combining, SCEV, and codegen.
+    const APInt *C;
+    if (match(I->getOperand(1), m_APInt(C)) && !C->isAllOnesValue()) {
+      if ((*C | ~DemandedMask).isAllOnesValue()) {
+        // Force bits to 1 to create a 'not' op.
+        I->setOperand(1, ConstantInt::getAllOnesValue(VTy));
+        return I;
+      }
+      // If we can't turn this into a 'not', try to shrink the constant.
+      if (ShrinkDemandedConstant(I, 1, DemandedMask))
+        return I;
+    }
 
     // If our LHS is an 'and' and if it has one use, and if any of the bits we
     // are flipping are known to be set, then the xor is just resetting those


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32255.96136.patch
Type: text/x-patch
Size: 2748 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170421/9388f2f5/attachment-0001.bin>


More information about the llvm-commits mailing list