[PATCH] D51964: [InstCombine] Fold (xor (min/max X, Y), -1) -> (max/min ~X, ~Y) when X and Y are freely invertible.

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 11 23:30:20 PDT 2018


craig.topper created this revision.
craig.topper added a reviewer: spatel.

This allows the xor to be removed completely.

This might help with recomitting r341674, but seems good regardless.


Repository:
  rL LLVM

https://reviews.llvm.org/D51964

Files:
  lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  test/Transforms/InstCombine/xor.ll


Index: test/Transforms/InstCombine/xor.ll
===================================================================
--- test/Transforms/InstCombine/xor.ll
+++ test/Transforms/InstCombine/xor.ll
@@ -802,3 +802,31 @@
   %res = mul i32 %umin, %add
   ret i32 %res
 }
+
+define i32 @test48(i32 %x) {
+; CHECK-LABEL: @test48(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], -1
+; CHECK-NEXT:    [[D:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 -1
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %a = sub i32 -2, %x
+  %b = icmp sgt i32 %a, -1
+  %c = select i1 %b, i32 %a, i32 0
+  %d = xor i32 %c, -1
+  ret i32 %d
+}
+
+define i32 @test49(i32 %x) {
+; CHECK-LABEL: @test49(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], 0
+; CHECK-NEXT:    [[D:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 0
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %a = sub i32 -2, %x
+  %b = icmp slt i32 %a, 0
+  %c = select i1 %b, i32 %a, i32 -1
+  %d = xor i32 %c, -1
+  ret i32 %d
+}
Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2898,6 +2898,17 @@
         return SelectInst::Create(
             Builder.CreateICmp(getInverseMinMaxPred(SPF), NotX, Y), NotX, Y);
       }
+
+      // If both sides are freely invertible, then we can get rid of the xor
+      // completelely
+      if (IsFreeToInvert(LHS, !LHS->hasNUsesOrMore(3)) &&
+          IsFreeToInvert(RHS, !RHS->hasNUsesOrMore(3))) {
+        Value *NotLHS = Builder.CreateNot(LHS);
+        Value *NotRHS = Builder.CreateNot(RHS);
+        return SelectInst::Create(
+            Builder.CreateICmp(getInverseMinMaxPred(SPF), NotLHS, NotRHS),
+            NotLHS, NotRHS);
+      }
     }
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51964.165011.patch
Type: text/x-patch
Size: 1929 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180912/99358877/attachment.bin>


More information about the llvm-commits mailing list