[PATCH] D63629: [JumpThreading][PR42085] Do not fold conditional terminators of loop headers

Brian Rzycki via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 20 15:34:04 PDT 2019


brzycki created this revision.
brzycki added reviewers: craig.topper, sebpop, hfinkel.
Herald added subscribers: jfb, hiraditya.
Herald added a project: LLVM.

Folding conditional terminator instructions for basic blocks that are also loop headers can cause miscompiled code emitted from JumpThreading.

This only happens when calling JumpThreading via opt. The clang invocation scrubs the IR of such trivial optimizations before calling.

This fix pessimizes terminator folding only in the case when BB is a loop header.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63629

Files:
  llvm/lib/Transforms/Scalar/JumpThreading.cpp
  llvm/test/Transforms/JumpThreading/pr42085-thread-over-loopheader.ll


Index: llvm/test/Transforms/JumpThreading/pr42085-thread-over-loopheader.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/JumpThreading/pr42085-thread-over-loopheader.ll
@@ -0,0 +1,35 @@
+; RUN: opt -S < %s -jump-threading | FileCheck %s
+
+; PR42085: Do not thread over 'body' from 'pre_body' to 'latch'. In this
+;          case 'body' and 'head' are the correct loop headers and must
+;          not be threaded over. There are no JumpThread opportunities
+;          in this test case.
+
+define i32 @test(i1 %ARG) {
+; CHECK-NOT: {{.+}}.thread:
+entry:
+  br label %pre_body
+
+head:
+  %inc_head = phi i32 [ %inc_pre_body, %pre_body ], [ %inc, %latch ]
+  %cmp1 = icmp sgt i32 %inc_head, 1
+  br i1 %cmp1, label %body, label %pre_body
+
+pre_body:
+  %inc_pre_body = phi i32 [ 1, %entry ], [ %inc_head, %head ]
+  br i1 false, label %head, label %body
+
+body:
+  %res = phi i32 [ %inc_head, %head ], [ %inc_pre_body, %pre_body ]
+  %tmp = phi i32 [ %inc_head, %head ], [ %inc_pre_body, %pre_body ]
+  %inc = add i32 %tmp, 1
+  br i1 %ARG, label %exit, label %latch
+
+latch:
+  %cmp2 = icmp sgt i32 %inc, 2
+  br i1 %cmp2, label %exit, label %head
+
+exit:
+  %rc = phi i32 [ %res, %latch ], [ 0, %body ]
+  ret i32 %rc
+}
Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1097,14 +1097,21 @@
 
   // If the terminator of this block is branching on a constant, simplify the
   // terminator to an unconditional branch.  This can occur due to threading in
-  // other blocks.
-  if (getKnownConstant(Condition, Preference)) {
+  // other blocks.  We can only convert blocks that aren't LoopHeaders.  It's
+  // non-trivial to determine if BB remains a LoopHeader and if a recurisve
+  // successor of BB is also a new LoopHeader.
+  if (!LoopHeaders.count(BB) && getKnownConstant(Condition, Preference)) {
     LLVM_DEBUG(dbgs() << "  In block '" << BB->getName()
-                      << "' folding terminator: " << *BB->getTerminator()
+                      << "' trying to fold terminator: " << *BB->getTerminator()
                       << '\n');
-    ++NumFolds;
-    ConstantFoldTerminator(BB, true, nullptr, DTU);
-    return true;
+    if (ConstantFoldTerminator(BB, true, nullptr, DTU)) {
+      LLVM_DEBUG(dbgs() << "  Successfully folded block '" << BB->getName()
+                        << "' to new terminator: " << *BB->getTerminator()
+                        << '\n');
+      ++NumFolds;
+      return true;
+    }
+    return false;
   }
 
   Instruction *CondInst = dyn_cast<Instruction>(Condition);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63629.205914.patch
Type: text/x-patch
Size: 2761 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190620/ca7749bb/attachment.bin>


More information about the llvm-commits mailing list