[PATCH] D151660: [InstCombine] (icmp eq A, -1) & (icmp eq B, -1) --> (icmp eq (A&B), -1)

Shivam Gupta via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 29 13:09:59 PDT 2023


xgupta created this revision.
xgupta added reviewers: RKSimon, spatel.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
xgupta requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This patch add another icmp fold for -1 case.

This fixes https://github.com/llvm/llvm-project/issues/62311,
where we want instcombine to merge all compare intructions together so
later passes like simplifycfg and slpvectorize can better optimize this
chained comparison.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151660

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/test/Transforms/InstCombine/pr62311.ll


Index: llvm/test/Transforms/InstCombine/pr62311.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/pr62311.ll
@@ -0,0 +1,64 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; Function Attrs: mustprogress nounwind uwtable
+define dso_local noundef zeroext i1 @_Z7allonesDv8_x(<8 x i64> noundef %x) local_unnamed_addr #0 {
+; CHECK-LABEL: define dso_local noundef zeroext i1 @_Z7allonesDv8_x
+; CHECK-SAME: (<8 x i64> noundef [[X:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[VECEXT:%.*]] = extractelement <8 x i64> [[X]], i64 0
+; CHECK-NEXT:    [[VECEXT1:%.*]] = extractelement <8 x i64> [[X]], i64 1
+; CHECK-NEXT:    [[TMP0:%.*]] = and i64 [[VECEXT]], [[VECEXT1]]
+; CHECK-NEXT:    [[VECEXT4:%.*]] = extractelement <8 x i64> [[X]], i64 2
+; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], [[VECEXT4]]
+; CHECK-NEXT:    [[VECEXT7:%.*]] = extractelement <8 x i64> [[X]], i64 3
+; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP1]], [[VECEXT7]]
+; CHECK-NEXT:    [[VECEXT10:%.*]] = extractelement <8 x i64> [[X]], i64 4
+; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[TMP2]], [[VECEXT10]]
+; CHECK-NEXT:    [[VECEXT13:%.*]] = extractelement <8 x i64> [[X]], i64 5
+; CHECK-NEXT:    [[TMP4:%.*]] = and i64 [[TMP3]], [[VECEXT13]]
+; CHECK-NEXT:    [[VECEXT16:%.*]] = extractelement <8 x i64> [[X]], i64 6
+; CHECK-NEXT:    [[TMP5:%.*]] = and i64 [[TMP4]], [[VECEXT16]]
+; CHECK-NEXT:    [[OR_COND24:%.*]] = icmp eq i64 [[TMP5]], -1
+; CHECK-NEXT:    br i1 [[OR_COND24]], label [[LAND_RHS:%.*]], label [[LAND_END:%.*]]
+; CHECK:       land.rhs:
+; CHECK-NEXT:    [[VECEXT18:%.*]] = extractelement <8 x i64> [[X]], i64 7
+; CHECK-NEXT:    [[CMP19:%.*]] = icmp eq i64 [[VECEXT18]], -1
+; CHECK-NEXT:    br label [[LAND_END]]
+; CHECK:       land.end:
+; CHECK-NEXT:    [[TMP6:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP19]], [[LAND_RHS]] ]
+; CHECK-NEXT:    ret i1 [[TMP6]]
+;
+entry:
+  %vecext = extractelement <8 x i64> %x, i32 0
+  %cmp = icmp eq i64 %vecext, -1
+  %vecext1 = extractelement <8 x i64> %x, i32 1
+  %cmp2 = icmp eq i64 %vecext1, -1
+  %or.cond = select i1 %cmp, i1 %cmp2, i1 false
+  %vecext4 = extractelement <8 x i64> %x, i32 2
+  %cmp5 = icmp eq i64 %vecext4, -1
+  %or.cond20 = select i1 %or.cond, i1 %cmp5, i1 false
+  %vecext7 = extractelement <8 x i64> %x, i32 3
+  %cmp8 = icmp eq i64 %vecext7, -1
+  %or.cond21 = select i1 %or.cond20, i1 %cmp8, i1 false
+  %vecext10 = extractelement <8 x i64> %x, i32 4
+  %cmp11 = icmp eq i64 %vecext10, -1
+  %or.cond22 = select i1 %or.cond21, i1 %cmp11, i1 false
+  %vecext13 = extractelement <8 x i64> %x, i32 5
+  %cmp14 = icmp eq i64 %vecext13, -1
+  %or.cond23 = select i1 %or.cond22, i1 %cmp14, i1 false
+  %vecext16 = extractelement <8 x i64> %x, i32 6
+  %cmp17 = icmp eq i64 %vecext16, -1
+  %or.cond24 = select i1 %or.cond23, i1 %cmp17, i1 false
+  br i1 %or.cond24, label %land.rhs, label %land.end
+
+land.rhs:                                         ; preds = %entry
+  %vecext18 = extractelement <8 x i64> %x, i32 7
+
+  %cmp19 = icmp eq i64 %vecext18, -1
+  br label %land.end
+
+land.end:                                         ; preds = %land.rhs, %entry
+  %0 = phi i1 [ false, %entry ], [ %cmp19, %land.rhs ]
+  ret i1 %0
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2947,6 +2947,17 @@
                               Constant::getNullValue(NewOr->getType()));
   }
 
+  // (icmp ne A, -1) | (icmp ne B, -1) --> (icmp ne (A&B), -1)
+  // (icmp eq A, -1) & (icmp eq B, -1) --> (icmp eq (A&B), -1)
+  // TODO: Remove this when foldLogOpOfMaskedICmps can handle undefs.
+  if (!IsLogical && PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
+      PredL == PredR && match(LHS1, m_ConstantInt<-1>()) &&
+      match(RHS1, m_ConstantInt<-1>()) && LHS0->getType() == RHS0->getType()) {
+    Value *NewAnd = Builder.CreateAnd(LHS0, RHS0);
+    return Builder.CreateICmp(PredL, NewAnd,
+                              ConstantInt::get(LHS0->getType(), -1));
+  }
+
   // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2).
   if (!LHSC || !RHSC)
     return nullptr;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151660.526470.patch
Type: text/x-patch
Size: 4454 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230529/efe61b3d/attachment.bin>


More information about the llvm-commits mailing list