LoopVectorize: Handle single edge PHIs
authorArnold Schwaighofer <aschwaighofer@apple.com>
Sat, 18 May 2013 18:38:34 +0000 (18:38 +0000)
committerArnold Schwaighofer <aschwaighofer@apple.com>
Sat, 18 May 2013 18:38:34 +0000 (18:38 +0000)
We might encouter single edge PHIs - handle them with an identity select.

Fixes PR15990.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182199 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Vectorize/LoopVectorize.cpp
test/Transforms/LoopVectorize/if-conv-crash.ll

index fce2cf211cd9b485bc6701fb2b12684ec015328e..d5c6ff8cad2fbb8f1b383ff3c7a683c1b79f0635 100644 (file)
@@ -2105,7 +2105,6 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,
         // optimizations will clean it up.
 
         unsigned NumIncoming = P->getNumIncomingValues();
-        assert(NumIncoming > 1 && "Invalid PHI");
 
         // Generate a sequence of selects of the form:
         // SELECT(Mask3, In3,
@@ -2117,10 +2116,11 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal,
           VectorParts &In0 = getVectorValue(P->getIncomingValue(In));
 
           for (unsigned part = 0; part < UF; ++part) {
-            // We don't need to 'select' the first PHI operand because it is
-            // the default value if all of the other masks don't match.
+            // We might have single edge PHIs (blocks) - use an identity
+            // 'select' for the first PHI operand.
             if (In == 0)
-              Entry[part] = In0[part];
+              Entry[part] = Builder.CreateSelect(Cond[part], In0[part],
+                                                 In0[part]);
             else
               // Select between the current value and the previous incoming edge
               // based on the incoming mask.
index 3283456aa3c3af5d2e3bae3b69046a13c2117994..f8f2cf1fff4bb21112ab040263b23f4bb88ab915 100644 (file)
@@ -37,3 +37,25 @@ if.end21:                                         ; preds = %lor.lhs.false
 if.end25:                                         ; preds = %entry
   ret void
 }
+
+; PR15990
+; We can have basic blocks with single entry PHI nodes.
+define void @single_entry_phi(i32* %a, i32 *%b) {
+entry:
+  br label %for.cond1.preheader
+
+for.cond1.preheader:
+  %inc10 = phi i32 [ 0, %entry ], [ %inc, %for.end ]
+  br label %for.end
+
+for.end:
+  %malicious.phi = phi i32 [ 0, %for.cond1.preheader ]
+  %inc = add nsw i32 %inc10, 1
+  %tobool = icmp eq i32 %inc, 0
+  br i1 %tobool, label %for.cond.for.end5, label %for.cond1.preheader
+
+for.cond.for.end5:
+  %and.lcssa = phi i32 [ %malicious.phi, %for.end ]
+  store i32 %and.lcssa, i32* %a, align 4
+  ret void
+}