[llvm] r321603 - [SimplifyCFG] Stop hoisting musttail calls incorrectly.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 31 08:47:17 PST 2017


Author: davide
Date: Sun Dec 31 08:47:16 2017
New Revision: 321603

URL: http://llvm.org/viewvc/llvm-project?rev=321603&view=rev
Log:
[SimplifyCFG] Stop hoisting musttail calls incorrectly.

PR35774.

Added:
    llvm/trunk/test/Transforms/SimplifyCFG/pr35774.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=321603&r1=321602&r2=321603&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Sun Dec 31 08:47:16 2017
@@ -1276,6 +1276,17 @@ static bool HoistThenElseCodeToIf(Branch
     if (isa<TerminatorInst>(I1))
       goto HoistTerminator;
 
+    // If we're going to hoist a call, make sure that the two instructions we're
+    // commoning/hoisting are both marked with musttail, or neither of them is
+    // marked as such. Otherwise, we might end up in a situation where we hoist
+    // from a block where the terminator is a `ret` to a block where the terminator
+    // is a `br`, and `musttail` calls expect to be followed by a return.
+    auto *C1 = dyn_cast<CallInst>(I1);
+    auto *C2 = dyn_cast<CallInst>(I2);
+    if (C1 && C2)
+      if (C1->isMustTailCall() != C2->isMustTailCall())
+        return false;
+
     if (!TTI.isProfitableToHoist(I1) || !TTI.isProfitableToHoist(I2))
       return Changed;
 

Added: llvm/trunk/test/Transforms/SimplifyCFG/pr35774.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/pr35774.ll?rev=321603&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/pr35774.ll (added)
+++ llvm/trunk/test/Transforms/SimplifyCFG/pr35774.ll Sun Dec 31 08:47:16 2017
@@ -0,0 +1,35 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -simplifycfg -S %s | FileCheck %s
+
+%foo = type { i32 (%foo)*, i32 }
+
+declare i32 @putchar(i32)
+
+define i32 @intercept(%foo %f) {
+; CHECK-LABEL: @intercept(
+; CHECK-NEXT:    [[FN:%.*]] = extractvalue [[FOO:%.*]] %f, 0
+; CHECK-NEXT:    [[X:%.*]] = extractvalue [[FOO]] %f, 1
+; CHECK-NEXT:    [[X0:%.*]] = icmp eq i32 [[X]], 0
+; CHECK-NEXT:    br i1 [[X0]], label [[ZERO:%.*]], label [[NONZERO:%.*]]
+; CHECK:       Zero:
+; CHECK-NEXT:    [[R0:%.*]] = musttail call i32 [[FN]](%foo [[F:%.*]])
+; CHECK-NEXT:    ret i32 [[R0]]
+; CHECK:       Nonzero:
+; CHECK-NEXT:    [[R1:%.*]] = tail call i32 [[FN]](%foo [[F]])
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @putchar(i32 [[R1]])
+; CHECK-NEXT:    ret i32 [[R1]]
+;
+  %fn = extractvalue %foo %f, 0
+  %x = extractvalue %foo %f, 1
+  %x0 = icmp eq i32 %x, 0
+  br i1 %x0, label %Zero, label %Nonzero
+
+Zero:
+  %r0 = musttail call i32 %fn(%foo %f)
+  ret i32 %r0
+
+Nonzero:
+  %r1 = tail call i32 %fn(%foo %f)
+  %1 = tail call i32 @putchar(i32 %r1)
+  ret i32 %r1
+}




More information about the llvm-commits mailing list