[PATCH] D32126: [CodeGenPrepare] Fix crash due to an invalid CFG

Brendon Cahoon via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 17 10:16:29 PDT 2017


bcahoon created this revision.

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

This occurs when there is an edge from 'D' to 'D'. Since D is split into D0 and https://reviews.llvm.org/D1, the code needs to update the terminator in https://reviews.llvm.org/D1, but https://reviews.llvm.org/D1 isn't in the OtherPreds vector so it doesn't get updated.


https://reviews.llvm.org/D32126

Files:
  lib/CodeGen/CodeGenPrepare.cpp
  test/Transforms/CodeGenPrepare/split-indirect-loop.ll


Index: test/Transforms/CodeGenPrepare/split-indirect-loop.ll
===================================================================
--- /dev/null
+++ test/Transforms/CodeGenPrepare/split-indirect-loop.ll
@@ -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]
+}
+
Index: lib/CodeGen/CodeGenPrepare.cpp
===================================================================
--- lib/CodeGen/CodeGenPrepare.cpp
+++ lib/CodeGen/CodeGenPrepare.cpp
@@ -570,8 +570,14 @@
     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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32126.95447.patch
Type: text/x-patch
Size: 2069 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170417/75d1e725/attachment.bin>


More information about the llvm-commits mailing list