Skip to content

Commit

Permalink
[Coroutines] Add the newly generated SCCs back to the CGSCC work queu…
Browse files Browse the repository at this point in the history
…e after CoroSplit actually happened

Relevant discussion can be found at: https://lists.llvm.org/pipermail/llvm-dev/2021-January/148197.html
In the existing design, An SCC that contains a coroutine will go through the folloing passes:
Inliner -> CoroSplitPass (fake) -> FunctionSimplificationPipeline -> Inliner -> CoroSplitPass (real) -> FunctionSimplificationPipeline

The first CoroSplitPass doesn't do anything other than putting the SCC back to the queue so that the entire pipeline can repeat.
As you can see, we run Inliner twice on the SCC consecutively without doing any real split, which is unnecessary and likely unintended.
What we really wanted is this:
Inliner -> FunctionSimplificationPipeline -> CoroSplitPass -> FunctionSimplificationPipeline
(note that we don't really need to run Inliner again on the ramp function after split).

Hence the way we do it here is to move CoroSplitPass to the end of the CGSCC pipeline, make it once for real, insert the newly generated SCCs (the clones) back to the pipeline so that they can be optimized, and also add a function simplification pipeline after CoroSplit to optimize the post-split ramp function.

This approach also conforms to how the new pass manager works instead of relying on an adhoc post split cleanup, making it ready for full switch to new pass manager eventually.

By looking at some of the changes to the tests, we can already observe that this changes allows for more optimizations applied to coroutines.

Reviewed By: aeubanks, ChuanqiXu

Differential Revision: https://reviews.llvm.org/D95807
  • Loading branch information
lxfind committed Jun 30, 2021
1 parent 2c4f569 commit 822b92a
Show file tree
Hide file tree
Showing 68 changed files with 322 additions and 315 deletions.
8 changes: 1 addition & 7 deletions clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@
//
// CHECK-ALL: Running pass:{{.*}}CoroEarlyPass
//
// The first coro-split pass enqueues a second run of the entire CGSCC pipeline.
// CHECK-ALL: Running pass: CoroSplitPass on (_Z3foov)
// CHECK-OPT: Running pass:{{.*}}CoroElidePass{{.*}} on {{.*}}_Z3foov{{.*}}
//
// The second coro-split pass splits coroutine 'foo' into funclets
// 'foo.resume', 'foo.destroy', and 'foo.cleanup'.
// CHECK-ALL: Running pass: CoroSplitPass on (_Z3foov)
// CHECK-OPT: Running pass:{{.*}}CoroElidePass{{.*}} on {{.*}}_Z3foov{{.*}}
//
Expand All @@ -27,7 +21,7 @@ namespace experimental {
struct handle {};

struct awaitable {
bool await_ready() noexcept { return true; }
bool await_ready() noexcept { return false; }
void await_suspend(handle) noexcept {}
bool await_resume() noexcept { return true; }
};
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,9 +1002,6 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level,
if (AttributorRun & AttributorRunOption::CGSCC)
MainCGPipeline.addPass(AttributorCGSCCPass());

if (PTO.Coroutines)
MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0));

// Now deduce any function attributes based in the current code.
MainCGPipeline.addPass(PostOrderFunctionAttrsPass());

Expand All @@ -1026,6 +1023,9 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level,
MainCGPipeline.addPass(createCGSCCToFunctionPassAdaptor(
buildFunctionSimplificationPipeline(Level, Phase)));

if (PTO.Coroutines)
MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0));

return MIWP;
}

Expand Down
34 changes: 8 additions & 26 deletions llvm/lib/Transforms/Coroutines/CoroSplit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1134,17 +1134,6 @@ static void postSplitCleanup(Function &F) {
// pass to FPM below because it will also verify all the global data.
if (verifyFunction(F, &errs()))
report_fatal_error("Broken function");

legacy::FunctionPassManager FPM(F.getParent());

FPM.add(createSCCPPass());
FPM.add(createCFGSimplificationPass());
FPM.add(createEarlyCSEPass());
FPM.add(createCFGSimplificationPass());

FPM.doInitialization();
FPM.run(F);
FPM.doFinalization();
}

// Assuming we arrived at the block NewBlock from Prev instruction, store
Expand Down Expand Up @@ -2119,28 +2108,21 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
// Split all the coroutines.
for (LazyCallGraph::Node *N : Coroutines) {
Function &F = N->getFunction();
Attribute Attr = F.getFnAttribute(CORO_PRESPLIT_ATTR);
StringRef Value = Attr.getValueAsString();
LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F.getName()
<< "' state: " << Value << "\n");
if (Value == UNPREPARED_FOR_SPLIT) {
// Enqueue a second iteration of the CGSCC pipeline on this SCC.
UR.CWorklist.insert(&C);
F.addFnAttr(CORO_PRESPLIT_ATTR, PREPARED_FOR_SPLIT);
continue;
}
<< "' state: "
<< F.getFnAttribute(CORO_PRESPLIT_ATTR).getValueAsString()
<< "\n");
F.removeFnAttr(CORO_PRESPLIT_ATTR);

SmallVector<Function *, 4> Clones;
const coro::Shape Shape = splitCoroutine(F, Clones, ReuseFrameSlot);
updateCallGraphAfterCoroutineSplit(*N, Shape, Clones, C, CG, AM, UR, FAM);

if ((Shape.ABI == coro::ABI::Async || Shape.ABI == coro::ABI::Retcon ||
Shape.ABI == coro::ABI::RetconOnce) &&
!Shape.CoroSuspends.empty()) {
// Run the CGSCC pipeline on the newly split functions.
// All clones will be in the same RefSCC, so choose a random clone.
UR.RCWorklist.insert(CG.lookupRefSCC(CG.get(*Clones[0])));
if (!Shape.CoroSuspends.empty()) {
// Run the CGSCC pipeline on the original and newly split functions.
UR.CWorklist.insert(&C);
for (Function *Clone : Clones)
UR.CWorklist.insert(CG.lookupSCC(CG.get(*Clone)));
}
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/ArgAddr.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Need to move users of allocas that were moved into the coroutine frame after
; coro.begin.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define nonnull i8* @f(i32 %n) "coroutine.presplit"="1" {
; CHECK-LABEL: @f(
Expand Down
8 changes: 5 additions & 3 deletions llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Check that we can handle the case when both alloc function and
; the user body consume the same argument.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

; using copy of this (as it would happen under -O0)
define i8* @f_copy(i64 %this_arg) "coroutine.presplit"="1" {
Expand Down Expand Up @@ -33,15 +33,17 @@ suspend:

; See that %this is spilled into the frame
; CHECK-LABEL: define i8* @f_copy(i64 %this_arg)
; CHECK: %this.addr = alloca i64, align 8
; CHECK: store i64 %this_arg, i64* %this.addr, align 4
; CHECK: %this.spill.addr = getelementptr inbounds %f_copy.Frame, %f_copy.Frame* %FramePtr, i32 0, i32 2
; CHECK: store i64 %this_arg, i64* %this.spill.addr
; CHECK: ret i8* %hdl
; CHECK: ret i8* %hdl

; See that %this was loaded from the frame
; CHECK-LABEL: @f_copy.resume(
; CHECK: %this.reload = load i64, i64* %this.reload.addr
; CHECK: call void @print2(i64 %this.reload)
; CHECK: ret void
; CHECK: ret void

declare i8* @llvm.coro.free(token, i8*)
declare i32 @llvm.coro.size.i32()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Check that we can handle the case when both alloc function and
; the user body consume the same argument.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

; using this directly (as it would happen under -O2)
define i8* @f_direct(i64 %this) "coroutine.presplit"="1" {
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-alloca-01.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that CoroSplit can succesfully determine allocas should live on the frame
; if their aliases are used across suspension points through PHINode.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f(i1 %n) "coroutine.presplit"="1" {
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-alloca-02.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that if an alloca is escaped through storing the address,
; the alloac will be put on the frame.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f() "coroutine.presplit"="1" {
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-alloca-03.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Tests that allocas escaped through function calls will live on the frame.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f() "coroutine.presplit"="1" {
entry:
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/Coroutines/coro-alloca-04.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that CoroSplit can succesfully determine allocas should live on the frame
; if their aliases are used across suspension points through PHINode.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f(i1 %n) "coroutine.presplit"="1" {
entry:
Expand Down Expand Up @@ -45,7 +45,7 @@ suspend:
; CHECK-NEXT: %0 = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0, i32 2
; CHECK-NEXT: %1 = bitcast i64* %0 to i8*
; CHECK-NEXT: %2 = bitcast i8* %1 to i32*
; CHECK-NEXT: %alias_phi.spill.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0, i32 3
; CHECK: %alias_phi.spill.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0, i32 3
; CHECK-NEXT: store i32* %2, i32** %alias_phi.spill.addr

declare i8* @llvm.coro.free(token, i8*)
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/Transforms/Coroutines/coro-alloca-05.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that allocas after coro.begin are properly that do not need to
; live on the frame are properly moved to the .resume function.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f() "coroutine.presplit"="1" {
entry:
Expand Down Expand Up @@ -31,10 +31,10 @@ suspend:
; CHECK-NEXT: entry.resume:
; CHECK-NEXT: [[VFRAME:%.*]] = bitcast %f.Frame* [[FRAMEPTR:%.*]] to i8*
; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[X_VALUE:%.*]] = load i32, i32* [[X]], align 4
; CHECK: [[X_VALUE:%.*]] = load i32, i32* [[X]], align 4
; CHECK-NEXT: call void @print(i32 [[X_VALUE]])
; CHECK-NEXT: call void @free(i8* [[VFRAME]])
; CHECK-NEXT: ret void
; CHECK: call void @free(i8* [[VFRAME]])
; CHECK: ret void

declare i8* @llvm.coro.free(token, i8*)
declare i32 @llvm.coro.size.i32()
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-alloca-06.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Test that in some simple cases allocas will not live on the frame even
; though their pointers are stored.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

%handle = type { i8* }

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-alloca-07.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that CoroSplit can succesfully determine allocas should live on the frame
; if their aliases are used across suspension points through PHINode.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f(i1 %n) "coroutine.presplit"="1" {
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-alloca-08.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

%"struct.std::coroutine_handle" = type { i8* }
%"struct.std::coroutine_handle.0" = type { %"struct.std::coroutine_handle" }
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-async.ll
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ define void @my_async_function_pa(i8* %ctxt, %async.task* %task, %async.actor* %

; CHECK-LABEL: define swiftcc void @my_async_function(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor)
; CHECK-SAME: !dbg ![[SP1:[0-9]+]] {
; CHECK: entry:
; CHECK: coro.return:
; CHECK: [[FRAMEPTR:%.*]] = getelementptr inbounds i8, i8* %async.ctxt, i64 128
; CHECK: [[ACTOR_SPILL_ADDR:%.*]] = getelementptr inbounds i8, i8* %async.ctxt, i64 152
; CHECK: [[CAST1:%.*]] = bitcast i8* [[ACTOR_SPILL_ADDR]] to %async.actor**
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-byval-param.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s
%promise_type = type { i8 }
%struct.A = type <{ i64, i64, i32, [4 x i8] }>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests the PHI nodes in cleanuppads for catchswitch instructions are correctly
; split up.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

declare i32 @__CxxFrameHandler3(...)
define i8* @f2(i1 %val) "coroutine.presplit"="1" personality i32 (...)* @__CxxFrameHandler3 {
Expand Down Expand Up @@ -106,11 +106,10 @@ declare void @llvm.coro.destroy(i8*)
declare token @llvm.coro.id(i32, i8*, i8*, i8*)
declare i1 @llvm.coro.alloc(token)
declare i8* @llvm.coro.begin(token, i8*)
declare i1 @llvm.coro.end(i8*, i1)
declare i1 @llvm.coro.end(i8*, i1)

declare noalias i8* @malloc(i32)
declare void @print(i32)
declare void @free(i8*)

declare i32 @f()

2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-catchswitch.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Verifies that we can insert the spill for a PHI preceding the catchswitch
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-debug.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Tests that debug information is sane after coro-split
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

source_filename = "simple-repro.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that we can handle edge splits leading into a landingpad
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that we can handle edge splits leading into a landingpad
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that we can handle edge splits leading into a landingpad
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that we can handle spills of array allocas
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

declare void @consume.double.ptr(double*)
declare void @consume.i32.ptr(i32*)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that we can handle spills of array allocas
; RUN: opt < %s -passes=coro-split -reuse-storage-in-coroutine-frame -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -reuse-storage-in-coroutine-frame -S | FileCheck %s

%struct.big_structure = type { [500 x i8] }
declare void @consume(%struct.big_structure*)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that variables in a Corotuine whose lifetime range is not overlapping each other
; re-use the same slot in Coroutine frame.
; RUN: opt < %s -passes=coro-split -reuse-storage-in-coroutine-frame -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -reuse-storage-in-coroutine-frame -S | FileCheck %s
%"struct.task::promise_type" = type { i8 }
%struct.awaitable = type { i8 }
%struct.big_structure = type { [500 x i8] }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that variables of different type in a Corotuine whose lifetime range is not overlapping each other
; re-use the same slot in Coroutine frame.
; RUN: opt < %s -passes=coro-split -reuse-storage-in-coroutine-frame -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -reuse-storage-in-coroutine-frame -S | FileCheck %s
%"struct.task::promise_type" = type { i8 }
%struct.awaitable = type { i8 }
%struct.big_structure = type { [500 x i8] }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that we should not reuse alloca sotrage in O0.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

%struct.big_structure = type { [500 x i8] }
declare void @consume(%struct.big_structure*)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that variables of different type with incompatible alignment in a Corotuine whose lifetime
; range is not overlapping each other should not re-use the same slot in Coroutine frame.
; RUN: opt < %s -passes=coro-split -reuse-storage-in-coroutine-frame -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -reuse-storage-in-coroutine-frame -S | FileCheck %s
%"struct.task::promise_type" = type { i8 }
%struct.awaitable = type { i8 }
%struct.big_structure = type { [500 x i8] }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Tests that variables of different type with incompatible alignment in a Corotuine whose
; lifetime range is not overlapping each other re-use the same slot in CorotuineFrame.
; RUN: opt < %s -passes=coro-split -reuse-storage-in-coroutine-frame -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -reuse-storage-in-coroutine-frame -S | FileCheck %s
%"struct.task::promise_type" = type { i8 }
%struct.awaitable = type { i8 }
%struct.big_structure = type { [500 x i8] }
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that coro-split doesn't choke on intrinsics in unreachable blocks
; RUN: opt < %s -passes=coro-split -S
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S

define i8* @f(i1 %arg) "coroutine.presplit"="1" personality i32 0 {
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-frame.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that we can handle spills of the result of the invoke instruction
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f(i64 %this) "coroutine.presplit"="1" personality i32 0 {
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-materialize.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Verifies that we materialize instruction across suspend points
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f(i32 %n) "coroutine.presplit"="1" {
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-padding.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Check that we will insert the correct padding if natural alignment of the
; spilled data does not match the alignment specified in alloca instruction.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

%PackedStruct = type <{ i64 }>

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Coroutines/coro-param-copy.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; Check that we create copy the data from the alloca into the coroutine
; frame slot if it was written to.
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(coro-split),simplify-cfg,early-cse' -S | FileCheck %s

define i8* @f() "coroutine.presplit"="1" {
entry:
Expand Down
Loading

0 comments on commit 822b92a

Please sign in to comment.