diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1476,6 +1476,7 @@ // FIXME: Can we define a safety predicate for CallBr? if (isa(I1) || !I1->isIdenticalToWhenDefined(I2) || (isa(I1) && !isSafeToHoistInvoke(BB1, BB2, I1, I2)) || + I1->getType()->isTokenTy() || I2->getType()->isTokenTy() || isa(I1)) return false; diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-skip-token.ll b/llvm/test/Transforms/SimplifyCFG/hoist-skip-token.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/hoist-skip-token.ll @@ -0,0 +1,36 @@ +; RUN: opt < %s -passes='simplifycfg' -S | FileCheck %s + +; CHECK: call token @llvm.coro.save(ptr null) +; CHECK: call token @llvm.coro.save(ptr null) + +declare token @llvm.coro.save(ptr) +declare i8 @llvm.coro.suspend(token, i1) + +define void @f(i32 %x) { +entry: + br label %while.cond + +while.cond: + %cmp = icmp slt i32 %x, 0 + br i1 %cmp, label %await.suspend, label %final.suspend + +await.suspend: + %0 = call token @llvm.coro.save(ptr null) + %1 = call i8 @llvm.coro.suspend(token %0, i1 false) + switch i8 %1, label %coro.ret [ + i8 0, label %while.cond + i8 1, label %cleanup + ] + +final.suspend: + %2 = call token @llvm.coro.save(ptr null) + %3 = call i8 @llvm.coro.suspend(token %2, i1 true) + %switch = icmp ult i8 %3, 2 + br i1 %switch, label %cleanup, label %coro.ret + +cleanup: + br label %coro.ret + +coro.ret: + ret void +}