From b170d856a3a303ab826f6896812bfd0ce05ec706 Mon Sep 17 00:00:00 2001 From: Yuanfang Chen Date: Tue, 5 Jul 2022 10:56:19 -0700 Subject: [PATCH] [SimplifyCFG] Skip hoisting common instructions that return token type By LangRef, hoisting token-returning instructions obsures the origin so it should be skipped. Found this issue while investigating a CoroSplit pass crash. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D129025 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 4 +++ .../Transforms/SimplifyCFG/hoist-skip-token.ll | 39 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 llvm/test/Transforms/SimplifyCFG/hoist-skip-token.ll diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 6b0f1e3..653ebd9 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1505,6 +1505,10 @@ bool SimplifyCFGOpt::HoistThenElseCodeToIf(BranchInst *BI, if (I1->isTerminator()) goto HoistTerminator; + // Hoisting token-returning instructions would obscure the origin. + if (I1->getType()->isTokenTy()) + return Changed; + // 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 diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-skip-token.ll b/llvm/test/Transforms/SimplifyCFG/hoist-skip-token.ll new file mode 100644 index 0000000..1e9dc25 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/hoist-skip-token.ll @@ -0,0 +1,39 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes='simplifycfg' -S | FileCheck %s + +declare token @llvm.coro.save(ptr) +declare i8 @llvm.coro.suspend(token, i1) + +define void @f(i32 %x) { +; CHECK-LABEL: @f( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[AWAIT_SUSPEND:%.*]], label [[FINAL_SUSPEND:%.*]] +; CHECK: await.suspend: +; CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.coro.save(ptr null) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.coro.suspend(token [[TMP0]], i1 false) +; CHECK-NEXT: br label [[CORO_RET:%.*]] +; CHECK: final.suspend: +; CHECK-NEXT: [[TMP2:%.*]] = call token @llvm.coro.save(ptr null) +; CHECK-NEXT: [[TMP3:%.*]] = call i8 @llvm.coro.suspend(token [[TMP2]], i1 true) +; CHECK-NEXT: br label [[CORO_RET]] +; CHECK: coro.ret: +; CHECK-NEXT: ret void +; +entry: + %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) + br label %coro.ret + +final.suspend: + %2 = call token @llvm.coro.save(ptr null) + %3 = call i8 @llvm.coro.suspend(token %2, i1 true) + br label %coro.ret + +coro.ret: + ret void +} -- 2.7.4