[llvm] r300480 - [CodeGenPrepare] Fix crash due to an invalid CFG

Brendon Cahoon via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 17 12:11:05 PDT 2017


Author: bcahoon
Date: Mon Apr 17 14:11:04 2017
New Revision: 300480

URL: http://llvm.org/viewvc/llvm-project?rev=300480&view=rev
Log:
[CodeGenPrepare] Fix crash due to an invalid CFG

The splitIndirectCriticalEdges function generates and invalid CFG when the
'Target' basic block is a loop to itself. When this occurs, the code that
updates the predecessor terminator needs to update the terminator in the split
basic block.

This occurs when there is an edge from block D back to D. Since D is split in
to D0 and D1, the code needs to update the terminator in D1. But D1 is not in
the OtherPreds vector, so it was not getting updated.

Differential Revision: https://reviews.llvm.org/D32126

Added:
    llvm/trunk/test/Transforms/CodeGenPrepare/split-indirect-loop.ll
Modified:
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp

Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=300480&r1=300479&r2=300480&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Mon Apr 17 14:11:04 2017
@@ -570,8 +570,14 @@ bool CodeGenPrepare::splitIndirectCritic
     ValueToValueMapTy VMap;
     BasicBlock *DirectSucc = CloneBasicBlock(Target, VMap, ".clone", &F);
 
-    for (BasicBlock *Pred : OtherPreds)
-      Pred->getTerminator()->replaceUsesOfWith(Target, DirectSucc);
+    for (BasicBlock *Pred : OtherPreds) {
+      // If the target is a loop to itself, then the terminator of the split
+      // block needs to be updated.
+      if (Pred == Target)
+        BodyBlock->getTerminator()->replaceUsesOfWith(Target, DirectSucc);
+      else
+        Pred->getTerminator()->replaceUsesOfWith(Target, DirectSucc);
+    }
 
     // Ok, now fix up the PHIs. We know the two blocks only have PHIs, and that
     // they are clones, so the number of PHIs are the same.

Added: llvm/trunk/test/Transforms/CodeGenPrepare/split-indirect-loop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/split-indirect-loop.ll?rev=300480&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/split-indirect-loop.ll (added)
+++ llvm/trunk/test/Transforms/CodeGenPrepare/split-indirect-loop.ll Mon Apr 17 14:11:04 2017
@@ -0,0 +1,37 @@
+; RUN: opt -codegenprepare -S < %s | FileCheck %s
+
+; Test that an invalid CFG is not created by splitIndirectCriticalEdges
+; transformation when the 'target' block is a loop to itself.
+
+; CHECK: .split:
+; CHECK: br label %while.body.clone
+; CHECK: if.else1:
+; CHECK: indirectbr
+; CHECK: while.body.clone:
+; CHECK: br label %.split
+
+define void @test() {
+entry:
+  br label %if.else
+
+if.else:
+  br i1 undef, label %while.body, label %preheader
+
+preheader:
+  br label %if.else1
+
+if.then:
+  unreachable
+
+while.body:
+  %dest.sroa = phi i32 [ %1, %while.body ], [ undef, %if.else1 ], [ undef, %if.else ]
+  %0 = inttoptr i32 %dest.sroa to i8*
+  %incdec.ptr = getelementptr inbounds i8, i8* %0, i32 -1
+  %1 = ptrtoint i8* %incdec.ptr to i32
+  store i8 undef, i8* %incdec.ptr, align 1
+  br label %while.body
+
+if.else1:
+  indirectbr i8* undef, [label %if.then, label %while.body, label %if.else, label %if.else1]
+}
+




More information about the llvm-commits mailing list