[llvm-commits] Patch review for 9216 - Endless loop in Instcombine

Rotem, Nadav nadav.rotem at intel.com
Mon Feb 14 12:37:30 PST 2011


Hi,

This patch reproduces and fixes an endless loop in Instcombine.  The cause of the problem is described below.  Please review this patch.

Cheers,
Nadav

Index: llvm/test/Transforms/InstCombine/2011-02-14-InfLoop.ll
===================================================================
--- llvm/test/Transforms/InstCombine/2011-02-14-InfLoop.ll      (revision 0)
+++ llvm/test/Transforms/InstCombine/2011-02-14-InfLoop.ll   (revision 0)
@@ -0,0 +1,17 @@
+; This testcase causes an infinite loop in the instruction combiner,
+; because it changes a pattern and the original pattern is almost
+; identical to the newly-generated pattern.
+; RUN: opt < %s -instcombine -disable-output
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define <4 x float> @m_387(i8* noalias nocapture %A, i8* nocapture %B, <4 x i1> %C) nounwind {
+entry:
+  %movcsext20 = sext <4 x i1> %C to <4 x i32>
+  %tmp2389 = xor <4 x i32> %movcsext20, <i32 -1, i32 -1, i32 -1, i32 -1>
+  %movcand25 = and <4 x i32> %tmp2389, <i32 undef, i32 undef, i32 undef, i32 -1>
+  %movcor26 = or <4 x i32> %movcand25, zeroinitializer
+  %L2 = bitcast <4 x i32> %movcor26 to <4 x float>
+  %L3 = shufflevector <4 x float> zeroinitializer, <4 x float> %L2, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
+  ret <4 x float> %L3
+}

Property changes on: llvm/test/Transforms/InstCombine/2011-02-14-InfLoop.ll
___________________________________________________________________
Added: svn:eol-style
   + native

Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp             (revision 125511)
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp          (working copy)
@@ -1138,7 +1138,11 @@
         cast<BinaryOperator>(Op1)->swapOperands();
         std::swap(A, B);
       }
-      if (A == Op0)                                // A&(A^B) -> A & ~B
+      // Notice that the patten (A&(~B)) is actually (A&(-1^B)), so if
+      // A is originally -1 (or a vector of -1 and undefs), then we enter
+      // an endless loop. By checking that A is non-constant we ensure that
+      // we will never get to the loop.
+      if (A == Op0 && ! dyn_cast<Constant>(A) ) // A&(A^B) -> A & ~B
         return BinaryOperator::CreateAnd(A, Builder->CreateNot(B, "tmp"));
     }

---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110214/13b90f82/attachment.html>


More information about the llvm-commits mailing list