[PATCH] D100044: [InstCombine] avoid infinite loop from partial undef vectors

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 7 09:28:27 PDT 2021


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG1894c6c59e37: [InstCombine] avoid infinite loop from partial undef vectors (authored by spatel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D100044

Files:
  llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
  llvm/test/Transforms/InstCombine/select-extractelement.ll


Index: llvm/test/Transforms/InstCombine/select-extractelement.ll
===================================================================
--- llvm/test/Transforms/InstCombine/select-extractelement.ll
+++ llvm/test/Transforms/InstCombine/select-extractelement.ll
@@ -209,5 +209,28 @@
   ret <4 x i32> %r
 }
 
+; This would infinite loop because a select transform would create
+; a complete -1 vector constant and demanded elements would change
+; it back to  partial undef.
+
+define i32 @inf_loop_partial_undef(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @inf_loop_partial_undef(
+; CHECK-NEXT:    [[T5:%.*]] = add nsw <2 x i32> [[Y:%.*]], <i32 2147483647, i32 2147483647>
+; CHECK-NEXT:    [[T6:%.*]] = icmp sge <2 x i32> [[T5]], [[X:%.*]]
+; CHECK-NEXT:    [[AB:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[T7:%.*]] = select <2 x i1> [[AB]], <2 x i1> [[T6]], <2 x i1> <i1 true, i1 poison>
+; CHECK-NEXT:    [[P:%.*]] = select <2 x i1> [[T7]], <2 x i32> <i32 0, i32 poison>, <2 x i32> [[Y]]
+; CHECK-NEXT:    [[T11:%.*]] = extractelement <2 x i32> [[P]], i32 0
+; CHECK-NEXT:    ret i32 [[T11]]
+;
+  %t5 = add nsw <2 x i32> %y, <i32 2147483647, i32 2147483647>
+  %t6 = icmp slt <2 x i32> %t5, %x
+  %ab = and <2 x i1> %a, %b
+  %t7 = select <2 x i1> %ab, <2 x i1> %t6, <2 x i1> <i1 0, i1 poison>
+  %t10 = xor <2 x i1> %t7, <i1 true, i1 poison>
+  %p = select <2 x i1> %t10, <2 x i32> zeroinitializer, <2 x i32> %y
+  %t11 = extractelement <2 x i32> %p, i32 0
+  ret i32 %t11
+}
 
 attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2654,13 +2654,15 @@
     auto *One = ConstantInt::getTrue(SelType);
     auto *Zero = ConstantInt::getFalse(SelType);
 
+    // We match the "full" 0 or 1 constant here to avoid a potential infinite
+    // loop with vectors that may have undefined/poison elements.
     // select a, false, b -> select !a, b, false
-    if (match(TrueVal, m_Zero())) {
+    if (match(TrueVal, m_Specific(Zero))) {
       Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());
       return SelectInst::Create(NotCond, FalseVal, Zero);
     }
     // select a, b, true -> select !a, true, b
-    if (match(FalseVal, m_One())) {
+    if (match(FalseVal, m_Specific(One))) {
       Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());
       return SelectInst::Create(NotCond, One, TrueVal);
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D100044.335841.patch
Type: text/x-patch
Size: 2823 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210407/ce35cb45/attachment.bin>


More information about the llvm-commits mailing list