[PATCH] D81698: [InstCombine] allow undef elements when comparing vector constants for min/max bailout

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 14 06:24:58 PDT 2020


This revision was automatically updated to reflect the committed changes.
Closed by commit rGaeb50448019c: [InstCombine] allow undef elements when comparing vector constants for min/max… (authored by spatel).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81698/new/

https://reviews.llvm.org/D81698

Files:
  llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
  llvm/test/Transforms/InstCombine/minmax-fold.ll


Index: llvm/test/Transforms/InstCombine/minmax-fold.ll
===================================================================
--- llvm/test/Transforms/InstCombine/minmax-fold.ll
+++ llvm/test/Transforms/InstCombine/minmax-fold.ll
@@ -1448,3 +1448,18 @@
   %r = trunc i32 %u7 to i8
   ret i8 %r
 }
+
+define i8 @PR46271(<2 x i8> %x) {
+; CHECK-LABEL: @PR46271(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
+; CHECK-NEXT:    [[B:%.*]] = select <2 x i1> [[A]], <2 x i8> [[X]], <2 x i8> <i8 undef, i8 -1>
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i8> [[B]], i32 1
+; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], -1
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %a = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
+  %b = select <2 x i1> %a, <2 x i8> %x, <2 x i8> <i8 undef, i8 -1>
+  %not = xor <2 x i8> %b, <i8 undef, i8 -1>
+  %r = extractelement <2 x i8> %not, i32 1
+  ret i8 %r
+}
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -922,7 +922,31 @@
   if (auto *CI = dyn_cast<CmpInst>(SI->getCondition())) {
     if (CI->hasOneUse()) {
       Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1);
-      if ((TV == Op0 && FV == Op1) || (FV == Op0 && TV == Op1))
+
+      // FIXME: This is a hack to avoid infinite looping with min/max patterns.
+      //        We have to ensure that vector constants that only differ with
+      //        undef elements are treated as equivalent.
+      auto areLooselyEqual = [](Value *A, Value *B) {
+        if (A == B)
+          return true;
+
+        // Test for vector constants.
+        Constant *ConstA, *ConstB;
+        if (!match(A, m_Constant(ConstA)) || !match(B, m_Constant(ConstB)))
+          return false;
+
+        // TODO: Deal with FP constants?
+        if (!A->getType()->isIntOrIntVectorTy() || A->getType() != B->getType())
+          return false;
+
+        // Compare for equality including undefs as equal.
+        auto *Cmp = ConstantExpr::getCompare(ICmpInst::ICMP_EQ, ConstA, ConstB);
+        const APInt *C;
+        return match(Cmp, m_APIntAllowUndef(C)) && C->isOneValue();
+      };
+
+      if ((areLooselyEqual(TV, Op0) && areLooselyEqual(FV, Op1)) ||
+          (areLooselyEqual(FV, Op0) && areLooselyEqual(TV, Op1)))
         return nullptr;
     }
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81698.270615.patch
Type: text/x-patch
Size: 2465 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200614/481bdafb/attachment.bin>


More information about the llvm-commits mailing list