[PATCH] D100211: [InstCombine] Fold cmpeq/ne(and(~X,Y),0) --> cmpeq/ne(or(freeze(X),Y),X)

Simon Pilgrim via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 9 08:58:10 PDT 2021


RKSimon created this revision.
RKSimon added reviewers: lebedev.ri, nikic, spatel.
Herald added a subscriber: hiraditya.
RKSimon requested review of this revision.
Herald added a project: LLVM.

Reverse of the backend fold from D100177 <https://reviews.llvm.org/D100177> (PR44136), this is only valid if we freeze the not source value.

If we require the freeze we're not actually reducing the instruction count - should we limit this to cases where 'X' isGuaranteedNotToBeUndefOrPoison?

https://alive2.llvm.org/ce/z/PgAUx5
https://alive2.llvm.org/ce/z/8uRSz6


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100211

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
  llvm/test/Transforms/InstCombine/2010-11-23-Distributed.ll
  llvm/test/Transforms/InstCombine/icmp.ll
  llvm/test/Transforms/InstCombine/rem.ll


Index: llvm/test/Transforms/InstCombine/rem.ll
===================================================================
--- llvm/test/Transforms/InstCombine/rem.ll
+++ llvm/test/Transforms/InstCombine/rem.ll
@@ -703,9 +703,9 @@
 define i1 @test26(i32 %A, i32 %B) {
 ; CHECK-LABEL: @test26(
 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[B:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[NOTMASK]], -1
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
-; CHECK-NEXT:    [[E:%.*]] = icmp ne i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = freeze i32 [[NOTMASK]]
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
+; CHECK-NEXT:    [[E:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
 ; CHECK-NEXT:    ret i1 [[E]]
 ;
   %C = shl i32 1, %B ; not a constant
Index: llvm/test/Transforms/InstCombine/icmp.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp.ll
+++ llvm/test/Transforms/InstCombine/icmp.ll
@@ -1803,8 +1803,9 @@
 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = freeze i32 [[A:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[SHL]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %neg = xor i32 %A, -1
@@ -1817,8 +1818,9 @@
 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = freeze i32 [[A:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[SHL]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %neg = xor i32 %A, -1
Index: llvm/test/Transforms/InstCombine/2010-11-23-Distributed.ll
===================================================================
--- llvm/test/Transforms/InstCombine/2010-11-23-Distributed.ll
+++ llvm/test/Transforms/InstCombine/2010-11-23-Distributed.ll
@@ -15,9 +15,9 @@
 
 define i1 @bar(i64 %x, i64 %y) {
 ; CHECK-LABEL: @bar(
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i64 [[X:%.*]], -1
-; CHECK-NEXT:    [[B:%.*]] = and i64 [[TMP1]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[B]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = freeze i64 [[X:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[TMP2]], [[TMP1]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %a = and i64 %y, %x
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1358,6 +1358,18 @@
   if (!match(Cmp.getOperand(1), m_Zero()))
     return nullptr;
 
+  // (icmp eq and(~A, B) 0) -> (icmp eq or(freeze(A), B) A)
+  // (icmp ne and(~A, B) 0) -> (icmp ne or(freeze(A), B) A)
+  if (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) {
+    Value *A, *B;
+    if (match(Cmp.getOperand(0),
+              m_OneUse(m_c_And(m_Not(m_Value(A)), m_Value(B))))) {
+      Value *NewA = Builder.CreateFreeze(A);
+      Value *NewOr = Builder.CreateOr(NewA, B);
+      return new ICmpInst(Pred, NewOr, NewA);
+    }
+  }
+
   // (icmp sgt smin(PosA, B) 0) -> (icmp sgt B 0)
   if (Pred == ICmpInst::ICMP_SGT) {
     Value *A, *B;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D100211.336484.patch
Type: text/x-patch
Size: 3657 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210409/1dc8defb/attachment.bin>


More information about the llvm-commits mailing list