ChuanqiXu created this revision.
ChuanqiXu added reviewers: nikic, rjmccall, ezhulenev.
Herald added subscribers: Peiming, bzcheeseman, sdasgup3, wenzhicui, wrengr, 
Chia-hungDuan, dcaballe, cota, teijeong, rdzhabarov, tatianashp, jdoerfert, 
msifontes, jurahul, Kayjukh, grosul1, Joonsoo, liufengdb, aartbik, mgester, 
arpith-jacob, antiagainst, shauheen, rriddle, mehdi_amini, hiraditya, qcolombet.
Herald added a project: All.
ChuanqiXu requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, stephenneuendorffer, 
nicolasvasilache.
Herald added projects: clang, MLIR, LLVM.

This is required by @nikic in https://reviews.llvm.org/D127383 and this fixes a 
FIXME too.

@rjmccall I'm not sure if swift have emitted "coroutine.presplit" in the 
frontend. If it haven't do so, it should be fine.

@ezhulenev I'm not sure if the changes in mlir part calls the right API. 
Although it passes the tests, I haven't run mlir actually.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D127471

Files:
  clang/lib/CodeGen/CGCoroutine.cpp
  clang/test/CodeGenCoroutines/coro-attributes.cpp
  llvm/docs/Coroutines.rst
  llvm/include/llvm/Bitcode/LLVMBitCodes.h
  llvm/include/llvm/IR/Attributes.td
  llvm/include/llvm/IR/Function.h
  llvm/lib/Bitcode/Reader/BitcodeReader.cpp
  llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
  llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
  llvm/lib/Transforms/Coroutines/CoroEarly.cpp
  llvm/lib/Transforms/Coroutines/CoroInternal.h
  llvm/lib/Transforms/Coroutines/CoroSplit.cpp
  llvm/test/Transforms/Coroutines/ArgAddr.ll
  llvm/test/Transforms/Coroutines/coro-align16.ll
  llvm/test/Transforms/Coroutines/coro-align32.ll
  llvm/test/Transforms/Coroutines/coro-align64-02.ll
  llvm/test/Transforms/Coroutines/coro-align64.ll
  llvm/test/Transforms/Coroutines/coro-align8-02.ll
  llvm/test/Transforms/Coroutines/coro-align8.ll
  llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll
  llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll
  llvm/test/Transforms/Coroutines/coro-alloca-01.ll
  llvm/test/Transforms/Coroutines/coro-alloca-02.ll
  llvm/test/Transforms/Coroutines/coro-alloca-03.ll
  llvm/test/Transforms/Coroutines/coro-alloca-04.ll
  llvm/test/Transforms/Coroutines/coro-alloca-05.ll
  llvm/test/Transforms/Coroutines/coro-alloca-06.ll
  llvm/test/Transforms/Coroutines/coro-alloca-07.ll
  llvm/test/Transforms/Coroutines/coro-alloca-08.ll
  llvm/test/Transforms/Coroutines/coro-alloca-09.ll
  llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll
  llvm/test/Transforms/Coroutines/coro-async.ll
  llvm/test/Transforms/Coroutines/coro-byval-param.ll
  llvm/test/Transforms/Coroutines/coro-catchswitch-cleanuppad.ll
  llvm/test/Transforms/Coroutines/coro-catchswitch.ll
  llvm/test/Transforms/Coroutines/coro-debug-O2.ll
  llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll
  llvm/test/Transforms/Coroutines/coro-debug-dbg.addr.ll
  llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll
  llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll
  llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll
  llvm/test/Transforms/Coroutines/coro-debug.ll
  llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll
  llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
  llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
  llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
  llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-00.ll
  llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
  llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
  llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-03.ll
  llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
  llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
  llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll
  llvm/test/Transforms/Coroutines/coro-frame.ll
  llvm/test/Transforms/Coroutines/coro-inline.ll
  llvm/test/Transforms/Coroutines/coro-materialize.ll
  llvm/test/Transforms/Coroutines/coro-noalias-param.ll
  llvm/test/Transforms/Coroutines/coro-padding.ll
  llvm/test/Transforms/Coroutines/coro-param-copy.ll
  llvm/test/Transforms/Coroutines/coro-retcon-frame.ll
  llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll
  llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll
  llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll
  llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll
  llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
  llvm/test/Transforms/Coroutines/coro-spill-promise.ll
  llvm/test/Transforms/Coroutines/coro-split-00.ll
  llvm/test/Transforms/Coroutines/coro-split-01.ll
  llvm/test/Transforms/Coroutines/coro-split-02.ll
  llvm/test/Transforms/Coroutines/coro-split-alloc.ll
  llvm/test/Transforms/Coroutines/coro-split-dbg.ll
  llvm/test/Transforms/Coroutines/coro-split-eh-00.ll
  llvm/test/Transforms/Coroutines/coro-split-eh-01.ll
  llvm/test/Transforms/Coroutines/coro-split-hidden.ll
  llvm/test/Transforms/Coroutines/coro-split-musttail.ll
  llvm/test/Transforms/Coroutines/coro-split-musttail1.ll
  llvm/test/Transforms/Coroutines/coro-split-musttail2.ll
  llvm/test/Transforms/Coroutines/coro-split-musttail3.ll
  llvm/test/Transforms/Coroutines/coro-split-musttail4.ll
  llvm/test/Transforms/Coroutines/coro-split-musttail5.ll
  llvm/test/Transforms/Coroutines/coro-split-musttail6.ll
  llvm/test/Transforms/Coroutines/coro-split-musttail7.ll
  llvm/test/Transforms/Coroutines/coro-split-recursive.ll
  llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
  llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
  llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll
  llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll
  llvm/test/Transforms/Coroutines/coro-zero-alloca.ll
  llvm/test/Transforms/Coroutines/ex0.ll
  llvm/test/Transforms/Coroutines/ex1.ll
  llvm/test/Transforms/Coroutines/ex2.ll
  llvm/test/Transforms/Coroutines/ex3.ll
  llvm/test/Transforms/Coroutines/ex4.ll
  llvm/test/Transforms/Coroutines/ex5.ll
  llvm/test/Transforms/Coroutines/no-suspend.ll
  llvm/test/Transforms/Coroutines/phi-coro-end.ll
  llvm/test/Transforms/FunctionAttrs/noreturn.ll
  llvm/test/Transforms/Inline/ML/state-tracking-coro.ll
  mlir/lib/Dialect/Async/Transforms/AsyncToAsyncRuntime.cpp
  mlir/test/mlir-opt/async.mlir

Index: mlir/test/mlir-opt/async.mlir
===================================================================
--- mlir/test/mlir-opt/async.mlir
+++ mlir/test/mlir-opt/async.mlir
@@ -3,9 +3,9 @@
 // RUN:   mlir-opt %s -pass-pipeline="async-to-async-runtime,func.func(async-runtime-ref-counting,async-runtime-ref-counting-opt),convert-async-to-llvm,func.func(convert-linalg-to-loops,convert-scf-to-cf),convert-linalg-to-llvm,convert-memref-to-llvm,func.func(convert-arith-to-llvm),convert-func-to-llvm,reconcile-unrealized-casts" \
 // RUN: | FileCheck %s
 
-// CHECK: llvm.func @async_execute_fn{{.*}}attributes{{.*}}"coroutine.presplit", "0"
-// CHECK: llvm.func @async_execute_fn_0{{.*}}attributes{{.*}}"coroutine.presplit", "0"
-// CHECK: llvm.func @async_execute_fn_1{{.*}}attributes{{.*}}"coroutine.presplit", "0"
+// CHECK: llvm.func @async_execute_fn{{.*}}attributes{{.*}}presplitcoroutine
+// CHECK: llvm.func @async_execute_fn_0{{.*}}attributes{{.*}}presplitcoroutine
+// CHECK: llvm.func @async_execute_fn_1{{.*}}attributes{{.*}}presplitcoroutine
 
 func.func @main() {
   %i0 = arith.constant 0 : index
Index: mlir/lib/Dialect/Async/Transforms/AsyncToAsyncRuntime.cpp
===================================================================
--- mlir/lib/Dialect/Async/Transforms/AsyncToAsyncRuntime.cpp
+++ mlir/lib/Dialect/Async/Transforms/AsyncToAsyncRuntime.cpp
@@ -192,11 +192,9 @@
   }
 
   // The switch-resumed API based coroutine should be marked with
-  // "coroutine.presplit" attribute with value "0" to mark the function as a
-  // coroutine.
-  func->setAttr("passthrough", builder.getArrayAttr(builder.getArrayAttr(
-                                   {builder.getStringAttr("coroutine.presplit"),
-                                    builder.getStringAttr("0")})));
+  // coroutine.presplit attribute to mark the function as a coroutine.
+  func->setAttr("passthrough", builder.getArrayAttr(
+                                   StringAttr::get(ctx, "presplitcoroutine")));
 
   CoroMachinery machinery;
   machinery.func = func;
Index: llvm/test/Transforms/Inline/ML/state-tracking-coro.ll
===================================================================
--- llvm/test/Transforms/Inline/ML/state-tracking-coro.ll
+++ llvm/test/Transforms/Inline/ML/state-tracking-coro.ll
@@ -13,7 +13,7 @@
 declare i8* @malloc(i64)
 declare void @print(i32)
 
-define void @a() "coroutine.presplit"="0" {
+define void @a() presplitcoroutine {
 entry:
   %ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
   %testval = alloca i32
Index: llvm/test/Transforms/FunctionAttrs/noreturn.ll
===================================================================
--- llvm/test/Transforms/FunctionAttrs/noreturn.ll
+++ llvm/test/Transforms/FunctionAttrs/noreturn.ll
@@ -79,7 +79,7 @@
 
 ; CHECK-NOT: Function Attrs: {{.*}}noreturn
 ; CHECK: @coro
-define void @coro() "coroutine.presplit"="1" {
+define void @coro() presplitcoroutine {
   call token @llvm.coro.id.retcon.once(i32 0, i32 0, i8* null, i8* bitcast(void() *@coro to i8*), i8* null, i8* null)
   call i1 @llvm.coro.end(i8* null, i1 false)
   unreachable
Index: llvm/test/Transforms/Coroutines/phi-coro-end.ll
===================================================================
--- llvm/test/Transforms/Coroutines/phi-coro-end.ll
+++ llvm/test/Transforms/Coroutines/phi-coro-end.ll
@@ -1,7 +1,7 @@
 ; Verify that we correctly handle suspend when the coro.end block contains phi
 ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -S | FileCheck %s
 
-define i8* @f(i32 %n) "coroutine.presplit"="0" {
+define i8* @f(i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/no-suspend.ll
===================================================================
--- llvm/test/Transforms/Coroutines/no-suspend.ll
+++ llvm/test/Transforms/Coroutines/no-suspend.ll
@@ -10,7 +10,7 @@
 ; CHECK-NEXT:    call void @print(i32 %n)
 ; CHECK-NEXT:    ret void
 ;
-define void @no_suspends(i32 %n) "coroutine.presplit"="1" {
+define void @no_suspends(i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
@@ -50,7 +50,7 @@
 ; CHECK-NEXT:    call void @print(i32 0)
 ; CHECK-NEXT:    ret void
 ;
-define void @simplify_resume(i8* %src, i8* %dst) "coroutine.presplit"="1" {
+define void @simplify_resume(i8* %src, i8* %dst) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
@@ -101,7 +101,7 @@
 ; CHECK-NEXT:    call void @print(i32 1)
 ; CHECK-NEXT:    ret void
 ;
-define void @simplify_destroy() "coroutine.presplit"="1" personality i32 0 {
+define void @simplify_destroy() presplitcoroutine personality i32 0 {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
@@ -159,7 +159,7 @@
 ; CHECK:         call void @print(i32 0)
 ; CHECK-NEXT:    ret void
 ;
-define void @simplify_resume_with_inlined_if(i8* %src, i8* %dst, i1 %cond) "coroutine.presplit"="1" {
+define void @simplify_resume_with_inlined_if(i8* %src, i8* %dst, i1 %cond) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
@@ -215,7 +215,7 @@
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:     llvm.coro.id
 
-define void @cannot_simplify_other_calls() "coroutine.presplit"="1" {
+define void @cannot_simplify_other_calls() presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
@@ -268,7 +268,7 @@
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:     llvm.coro.id
 
-define void @cannot_simplify_calls_in_terminator() "coroutine.presplit"="1" personality i32 0 {
+define void @cannot_simplify_calls_in_terminator() presplitcoroutine personality i32 0 {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
@@ -321,7 +321,7 @@
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:     llvm.coro.id
 
-define void @cannot_simplify_not_last_instr(i8* %dst, i8* %src) "coroutine.presplit"="1" {
+define void @cannot_simplify_not_last_instr(i8* %dst, i8* %src) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
@@ -367,7 +367,7 @@
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:     llvm.coro.id
 ;
-define void @cannot_simplify_final_suspend() "coroutine.presplit"="1" personality i32 0 {
+define void @cannot_simplify_final_suspend() presplitcoroutine personality i32 0 {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
Index: llvm/test/Transforms/Coroutines/ex5.ll
===================================================================
--- llvm/test/Transforms/Coroutines/ex5.ll
+++ llvm/test/Transforms/Coroutines/ex5.ll
@@ -1,7 +1,7 @@
 ; Fifth example from Doc/Coroutines.rst (final suspend)
 ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s
 
-define i8* @f(i32 %n) "coroutine.presplit"="0" {
+define i8* @f(i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/ex4.ll
===================================================================
--- llvm/test/Transforms/Coroutines/ex4.ll
+++ llvm/test/Transforms/Coroutines/ex4.ll
@@ -1,7 +1,7 @@
 ; Fourth example from Doc/Coroutines.rst (coroutine promise)
 ; RUN: opt < %s -passes='default<O2>' -S | FileCheck %s
 
-define i8* @f(i32 %n) "coroutine.presplit"="0" {
+define i8* @f(i32 %n) presplitcoroutine {
 entry:
   %promise = alloca i32
   %pv = bitcast i32* %promise to i8*
Index: llvm/test/Transforms/Coroutines/ex3.ll
===================================================================
--- llvm/test/Transforms/Coroutines/ex3.ll
+++ llvm/test/Transforms/Coroutines/ex3.ll
@@ -1,7 +1,7 @@
 ; Third example from Doc/Coroutines.rst (two suspend points)
 ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -S | FileCheck %s
 
-define i8* @f(i32 %n) "coroutine.presplit"="0" {
+define i8* @f(i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/ex2.ll
===================================================================
--- llvm/test/Transforms/Coroutines/ex2.ll
+++ llvm/test/Transforms/Coroutines/ex2.ll
@@ -1,7 +1,7 @@
 ; Second example from Doc/Coroutines.rst (custom alloc and free functions)
 ; RUN: opt < %s -passes='default<O2>' -S | FileCheck %s
 
-define i8* @f(i32 %n) "coroutine.presplit"="0" {
+define i8* @f(i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
Index: llvm/test/Transforms/Coroutines/ex1.ll
===================================================================
--- llvm/test/Transforms/Coroutines/ex1.ll
+++ llvm/test/Transforms/Coroutines/ex1.ll
@@ -1,7 +1,7 @@
 ; First example from Doc/Coroutines.rst (one block loop)
 ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s
 
-define i8* @f(i32 %n) "coroutine.presplit"="0" {
+define i8* @f(i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/ex0.ll
===================================================================
--- llvm/test/Transforms/Coroutines/ex0.ll
+++ llvm/test/Transforms/Coroutines/ex0.ll
@@ -1,7 +1,7 @@
 ; First example from Doc/Coroutines.rst (two block loop)
 ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s
 
-define i8* @f(i32 %n) "coroutine.presplit"="0" {
+define i8* @f(i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/coro-zero-alloca.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-zero-alloca.ll
+++ llvm/test/Transforms/Coroutines/coro-zero-alloca.ll
@@ -13,7 +13,7 @@
 declare i8* @llvm.coro.free(token, i8* nocapture readonly)
 declare token @llvm.coro.save(i8*)
 
-define void @foo() "coroutine.presplit"="1" {
+define void @foo() presplitcoroutine {
 entry:
   %a0 = alloca [0 x i8]
   %a1 = alloca i32
Index: llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll
+++ llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll
@@ -10,7 +10,7 @@
 declare void @print(i32)
 declare void @consume.i8(i8)
 
-define void @a() "coroutine.presplit"="1" {
+define void @a() presplitcoroutine {
 entry:
   %ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
   %testval = alloca i8
Index: llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll
+++ llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll
@@ -12,7 +12,7 @@
 %i8.array = type { [100 x i8] }
 declare void @consume.i8.array(%i8.array*)
 
-define void @a.gep() "coroutine.presplit"="1" {
+define void @a.gep() presplitcoroutine {
 entry:
   %ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
   %testval = alloca %i8.array
Index: llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
+++ llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
@@ -10,7 +10,7 @@
 declare i8* @malloc(i64)
 declare void @print(i32)
 
-define void @a() "coroutine.presplit"="1" {
+define void @a() presplitcoroutine {
 entry:
   %ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
   %testval = alloca i32
Index: llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
+++ llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
@@ -9,7 +9,7 @@
 declare i8* @malloc(i64)
 declare void @print(i32)
 
-define void @a() "coroutine.presplit"="1" {
+define void @a() presplitcoroutine {
 entry:
   %ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
   %testval = alloca i32
Index: llvm/test/Transforms/Coroutines/coro-split-recursive.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-recursive.ll
+++ llvm/test/Transforms/Coroutines/coro-split-recursive.ll
@@ -14,7 +14,7 @@
 ; CHECK: call void @foo()
 ; CHECK-LABEL: define {{.*}}void @foo.destroy(
 
-define void @foo() "coroutine.presplit"="0" {
+define void @foo() presplitcoroutine {
 entry:
   %__promise = alloca i32, align 8
   %0 = bitcast i32* %__promise to i8*
Index: llvm/test/Transforms/Coroutines/coro-split-musttail7.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-musttail7.ll
+++ llvm/test/Transforms/Coroutines/coro-split-musttail7.ll
@@ -113,7 +113,7 @@
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
 
-attributes #0 = { "coroutine.presplit"="1" }
+attributes #0 = { presplitcoroutine }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind readnone }
Index: llvm/test/Transforms/Coroutines/coro-split-musttail6.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-musttail6.ll
+++ llvm/test/Transforms/Coroutines/coro-split-musttail6.ll
@@ -111,7 +111,7 @@
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
 
-attributes #0 = { "coroutine.presplit"="1" }
+attributes #0 = { presplitcoroutine }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind readnone }
Index: llvm/test/Transforms/Coroutines/coro-split-musttail5.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-musttail5.ll
+++ llvm/test/Transforms/Coroutines/coro-split-musttail5.ll
@@ -56,7 +56,7 @@
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
 
-attributes #0 = { "coroutine.presplit"="1" }
+attributes #0 = { presplitcoroutine }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind readnone }
Index: llvm/test/Transforms/Coroutines/coro-split-musttail4.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-musttail4.ll
+++ llvm/test/Transforms/Coroutines/coro-split-musttail4.ll
@@ -59,7 +59,7 @@
 declare i8* @malloc(i64)
 declare void @delete(i8* nonnull) #2
 
-attributes #0 = { "coroutine.presplit"="1" }
+attributes #0 = { presplitcoroutine }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind readnone }
Index: llvm/test/Transforms/Coroutines/coro-split-musttail3.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-musttail3.ll
+++ llvm/test/Transforms/Coroutines/coro-split-musttail3.ll
@@ -94,7 +94,7 @@
 declare i8* @g()
 declare i8* @h()
 
-attributes #0 = { "coroutine.presplit"="1" }
+attributes #0 = { presplitcoroutine }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind readnone }
Index: llvm/test/Transforms/Coroutines/coro-split-musttail2.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-musttail2.ll
+++ llvm/test/Transforms/Coroutines/coro-split-musttail2.ll
@@ -61,7 +61,7 @@
 declare i8* @llvm.coro.subfn.addr(i8* nocapture readonly, i8) #1
 declare i8* @malloc(i64)
 
-attributes #0 = { "coroutine.presplit"="1" }
+attributes #0 = { presplitcoroutine }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind readnone }
Index: llvm/test/Transforms/Coroutines/coro-split-musttail1.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-musttail1.ll
+++ llvm/test/Transforms/Coroutines/coro-split-musttail1.ll
@@ -98,7 +98,7 @@
 declare i8* @g()
 declare i8* @h()
 
-attributes #0 = { "coroutine.presplit"="1" }
+attributes #0 = { presplitcoroutine }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind readnone }
Index: llvm/test/Transforms/Coroutines/coro-split-musttail.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-musttail.ll
+++ llvm/test/Transforms/Coroutines/coro-split-musttail.ll
@@ -59,7 +59,7 @@
 declare i8* @llvm.coro.subfn.addr(i8* nocapture readonly, i8) #1
 declare i8* @malloc(i64)
 
-attributes #0 = { "coroutine.presplit"="1" }
+attributes #0 = { presplitcoroutine }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind readnone }
Index: llvm/test/Transforms/Coroutines/coro-split-hidden.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-hidden.ll
+++ llvm/test/Transforms/Coroutines/coro-split-hidden.ll
@@ -3,7 +3,7 @@
 ; '-fvisibility-inlines-hidden'.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define hidden i8* @f() "coroutine.presplit"="1" {
+define hidden i8* @f() presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.alloc = call i1 @llvm.coro.alloc(token %id)
Index: llvm/test/Transforms/Coroutines/coro-split-eh-01.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-eh-01.ll
+++ llvm/test/Transforms/Coroutines/coro-split-eh-01.ll
@@ -2,7 +2,7 @@
 ; and retains it in the start function.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f2(i1 %val) "coroutine.presplit"="1" personality i32 4 {
+define i8* @f2(i1 %val) presplitcoroutine personality i32 4 {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
Index: llvm/test/Transforms/Coroutines/coro-split-eh-00.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-eh-00.ll
+++ llvm/test/Transforms/Coroutines/coro-split-eh-00.ll
@@ -2,7 +2,7 @@
 ; and retains it in the start function.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f(i1 %val) "coroutine.presplit"="1" personality i32 3 {
+define i8* @f(i1 %val) presplitcoroutine personality i32 3 {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
Index: llvm/test/Transforms/Coroutines/coro-split-dbg.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-dbg.ll
+++ llvm/test/Transforms/Coroutines/coro-split-dbg.ll
@@ -65,7 +65,7 @@
 attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
 attributes #1 = { nounwind readnone }
 attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #3 = { nounwind uwtable "coroutine.presplit"="1" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #3 = { nounwind uwtable presplitcoroutine "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
 attributes #4 = { argmemonly nounwind }
 attributes #5 = { argmemonly nounwind readonly }
 attributes #6 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
Index: llvm/test/Transforms/Coroutines/coro-split-alloc.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-alloc.ll
+++ llvm/test/Transforms/Coroutines/coro-split-alloc.ll
@@ -1,7 +1,7 @@
 ; Tests that coro-split passes initialized values to coroutine frame allocator.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f(i32 %argument) "coroutine.presplit"="1" {
+define i8* @f(i32 %argument) presplitcoroutine {
 entry:
   %argument.addr = alloca i32, align 4
   %incremented = add i32 %argument, 1
Index: llvm/test/Transforms/Coroutines/coro-split-02.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-02.ll
+++ llvm/test/Transforms/Coroutines/coro-split-02.ll
@@ -10,7 +10,7 @@
 declare i8* @malloc(i64)
 declare void @print(i32)
 
-define void @a() "coroutine.presplit"="1" {
+define void @a() presplitcoroutine {
 entry:
   %ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
   %testval = alloca i32
Index: llvm/test/Transforms/Coroutines/coro-split-01.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-01.ll
+++ llvm/test/Transforms/Coroutines/coro-split-01.ll
@@ -1,7 +1,7 @@
 ; Tests that a coroutine is split, inlined into the caller and devirtualized.
 ; RUN: opt < %s -S -passes='default<O2>' | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="0" {
+define i8* @f() presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
Index: llvm/test/Transforms/Coroutines/coro-split-00.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-split-00.ll
+++ llvm/test/Transforms/Coroutines/coro-split-00.ll
@@ -1,7 +1,7 @@
 ; Tests that coro-split pass splits the coroutine into f, f.resume and f.destroy
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %need.alloc = call i1 @llvm.coro.alloc(token %id)
Index: llvm/test/Transforms/Coroutines/coro-spill-promise.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-spill-promise.ll
+++ llvm/test/Transforms/Coroutines/coro-spill-promise.ll
@@ -6,7 +6,7 @@
 declare void @consume(i32*)
 declare void @consume2(%"class.task::promise_type"*)
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %data = alloca i32, align 4
   %__promise = alloca %"class.task::promise_type", align 64
Index: llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
+++ llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
@@ -1,7 +1,7 @@
 ; Verifies that phi and invoke definitions before CoroBegin are spilled properly.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg' -S | FileCheck %s
 
-define i8* @f(i1 %n) "coroutine.presplit"="1" personality i32 0 {
+define i8* @f(i1 %n) presplitcoroutine personality i32 0 {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll
+++ llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll
@@ -9,7 +9,7 @@
 
 declare i8* @g()
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll
+++ llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll
@@ -5,7 +5,7 @@
 ; Verifies that the both phis are stored correctly in the coroutine frame
 ; CHECK: %f.Frame = type { void (%f.Frame*)*, void (%f.Frame*)*, i32, i32, i1 }
 
-define i8* @f(i1 %n) "coroutine.presplit"="1" {
+define i8* @f(i1 %n) presplitcoroutine {
 ; CHECK-LABEL: @f(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ID:%.*]] = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* bitcast ([3 x void (%f.Frame*)*]* @f.resumers to i8*))
Index: llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll
+++ llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg,coro-cleanup' -S | FileCheck %s
 
-define i8* @f(i8* %buffer, i32 %n) "coroutine.presplit"="1" {
+define i8* @f(i8* %buffer, i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast (i8* (i8*, i32)* @prototype to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*))
   %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
Index: llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll
+++ llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll
@@ -3,7 +3,7 @@
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.12.0"
 
-define {i8*, i32*} @f(i8* %buffer, i32* %ptr) "coroutine.presplit"="1" {
+define {i8*, i32*} @f(i8* %buffer, i32* %ptr) presplitcoroutine {
 entry:
   %temp = alloca i32, align 4
   %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, i8* %buffer, i8* bitcast (void (i8*, i1)* @prototype to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*))
Index: llvm/test/Transforms/Coroutines/coro-retcon-frame.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-retcon-frame.ll
+++ llvm/test/Transforms/Coroutines/coro-retcon-frame.ll
@@ -10,7 +10,7 @@
 declare void @use(i8* %ptr)
 declare void @use_addr_val(i64 %val, {i64, i64}*%addr)
 
-define { i8*, {i64, i64}* } @f(i8* %buffer) "coroutine.presplit"="1" {
+define { i8*, {i64, i64}* } @f(i8* %buffer) presplitcoroutine {
 entry:
   %tmp = alloca { i64, i64 }, align 8
   %proj.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 0
Index: llvm/test/Transforms/Coroutines/coro-param-copy.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-param-copy.ll
+++ llvm/test/Transforms/Coroutines/coro-param-copy.ll
@@ -2,7 +2,7 @@
 ; frame slot if it was written to.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %a.addr = alloca i64 ; read-only before coro.begin
   %a = load i64, i64* %a.addr ; cannot modify the value, don't need to copy
Index: llvm/test/Transforms/Coroutines/coro-padding.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-padding.ll
+++ llvm/test/Transforms/Coroutines/coro-padding.ll
@@ -6,7 +6,7 @@
 
 declare void @consume(%PackedStruct*)
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %data = alloca %PackedStruct, align 32
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
Index: llvm/test/Transforms/Coroutines/coro-noalias-param.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-noalias-param.ll
+++ llvm/test/Transforms/Coroutines/coro-noalias-param.ll
@@ -1,7 +1,7 @@
 ; RUN: opt < %s -S -passes=coro-early | FileCheck %s
 %struct.A = type <{ i64, i64, i32, [4 x i8] }>
 
-define void @f(%struct.A* nocapture readonly noalias align 8 %a) "coroutine.presplit"="0" {
+define void @f(%struct.A* nocapture readonly noalias align 8 %a) presplitcoroutine {
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
   %alloc = call i8* @malloc(i32 %size)
Index: llvm/test/Transforms/Coroutines/coro-materialize.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-materialize.ll
+++ llvm/test/Transforms/Coroutines/coro-materialize.ll
@@ -1,7 +1,7 @@
 ; Verifies that we materialize instruction across suspend points
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f(i32 %n) "coroutine.presplit"="1" {
+define i8* @f(i32 %n) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/coro-inline.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-inline.ll
+++ llvm/test/Transforms/Coroutines/coro-inline.ll
@@ -24,7 +24,7 @@
 declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*)
 declare i8* @llvm.coro.begin(token, i8* writeonly)
 
-attributes #0 = { alwaysinline ssp uwtable "coroutine.presplit"="1" "use-sample-profile" }
+attributes #0 = { alwaysinline ssp uwtable presplitcoroutine "use-sample-profile" }
 
 !llvm.dbg.cu = !{}
 !llvm.module.flags = !{!1, !2, !3, !4}
Index: llvm/test/Transforms/Coroutines/coro-frame.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame.ll
+++ llvm/test/Transforms/Coroutines/coro-frame.ll
@@ -1,7 +1,7 @@
 ; Check that we can handle spills of the result of the invoke instruction
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f(i64 %this) "coroutine.presplit"="1" personality i32 0 {
+define i8* @f(i64 %this) presplitcoroutine personality i32 0 {
 entry:
   %this.addr = alloca i64
   store i64 %this, i64* %this.addr
Index: llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll
+++ llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll
@@ -1,7 +1,7 @@
 ; Check that coro-split doesn't choke on intrinsics in unreachable blocks
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S
 
-define i8* @f(i1 %arg) "coroutine.presplit"="1" personality i32 0 {
+define i8* @f(i1 %arg) presplitcoroutine personality i32 0 {
 entry:
   %arg.addr = alloca i1
   store i1 %arg, i1* %arg.addr
Index: llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
+++ llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
@@ -8,7 +8,7 @@
 declare i8* @malloc(i64)
 declare void @consume(%struct.big_structure*)
 declare void @consume.2(%struct.big_structure.2*)
-define void @a(i1 zeroext %cond) "coroutine.presplit"="1" {
+define void @a(i1 zeroext %cond) presplitcoroutine {
 entry:
   %__promise = alloca %"struct.task::promise_type", align 1
   %a = alloca %struct.big_structure, align 32
Index: llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
+++ llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
@@ -8,7 +8,7 @@
 declare i8* @malloc(i64)
 declare void @consume(%struct.big_structure*)
 declare void @consume.2(%struct.big_structure.2*)
-define void @a(i1 zeroext %cond) "coroutine.presplit"="1" {
+define void @a(i1 zeroext %cond) presplitcoroutine {
 entry:
   %__promise = alloca %"struct.task::promise_type", align 1
   %a = alloca %struct.big_structure, align 1
Index: llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-03.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-03.ll
+++ llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-03.ll
@@ -5,7 +5,7 @@
 declare void @consume(%struct.big_structure*)
 
 ; Function Attrs: noinline optnone uwtable
-define i8* @f(i1 %cond) "coroutine.presplit"="1" {
+define i8* @f(i1 %cond) presplitcoroutine {
 entry:
   %data = alloca %struct.big_structure, align 1
   %data2 = alloca %struct.big_structure, align 1
Index: llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
+++ llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
@@ -8,7 +8,7 @@
 declare i8* @malloc(i64)
 declare void @consume(%struct.big_structure*)
 declare void @consume.2(%struct.big_structure.2*)
-define void @a(i1 zeroext %cond) "coroutine.presplit"="1" {
+define void @a(i1 zeroext %cond) presplitcoroutine {
 entry:
   %__promise = alloca %"struct.task::promise_type", align 1
   %a = alloca %struct.big_structure, align 1
Index: llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
+++ llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
@@ -6,7 +6,7 @@
 %struct.big_structure = type { [500 x i8] }
 declare i8* @malloc(i64)
 declare void @consume(%struct.big_structure*)
-define void @a(i1 zeroext %cond) "coroutine.presplit"="1" {
+define void @a(i1 zeroext %cond) presplitcoroutine {
 entry:
   %__promise = alloca %"struct.task::promise_type", align 1
   %a = alloca %struct.big_structure, align 1
Index: llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-00.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-00.ll
+++ llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-00.ll
@@ -5,7 +5,7 @@
 declare void @consume(%struct.big_structure*)
 
 ; Function Attrs: noinline optnone uwtable
-define i8* @f(i1 %cond) "coroutine.presplit"="1" {
+define i8* @f(i1 %cond) presplitcoroutine {
 entry:
   %data = alloca %struct.big_structure, align 1
   %data2 = alloca %struct.big_structure, align 1
Index: llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
+++ llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
@@ -4,7 +4,7 @@
 declare void @consume.double.ptr(double*)
 declare void @consume.i32.ptr(i32*)
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %prefix = alloca double
   %data = alloca i32, i32 4
Index: llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
+++ llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
@@ -5,7 +5,7 @@
 target triple = "x86_64-unknown-linux-gnu"
 
 ; CHECK-LABEL: define internal fastcc void @h.resume(
-define void @h(i1 %cond, i32 %x, i32 %y) "coroutine.presplit"="1" personality i32 0 {
+define void @h(i1 %cond, i32 %x, i32 %y) presplitcoroutine personality i32 0 {
 entry:
   %id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null)
   %size = tail call i64 @llvm.coro.size.i64()
Index: llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
+++ llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
@@ -5,7 +5,7 @@
 target triple = "x86_64-unknown-linux-gnu"
 
 ; CHECK-LABEL: define internal fastcc void @g.resume(
-define void @g(i1 %cond, i32 %x, i32 %y) "coroutine.presplit"="1" personality i32 0 {
+define void @g(i1 %cond, i32 %x, i32 %y) presplitcoroutine personality i32 0 {
 entry:
   %id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null)
   %size = tail call i64 @llvm.coro.size.i64()
Index: llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll
+++ llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll
@@ -5,7 +5,7 @@
 target triple = "x86_64-unknown-linux-gnu"
 
 ; CHECK-LABEL: define internal fastcc void @f.resume(
-define void @f(i1 %cond) "coroutine.presplit"="1" personality i32 0 {
+define void @f(i1 %cond) presplitcoroutine personality i32 0 {
 entry:
   %id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null)
   %size = tail call i64 @llvm.coro.size.i64()
Index: llvm/test/Transforms/Coroutines/coro-debug.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-debug.ll
+++ llvm/test/Transforms/Coroutines/coro-debug.ll
@@ -123,7 +123,7 @@
 ; Function Attrs: argmemonly nounwind readonly
 declare i8* @llvm.coro.subfn.addr(i8* nocapture readonly, i8) #2
 
-attributes #0 = { noinline nounwind "coroutine.presplit"="1" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #0 = { noinline nounwind presplitcoroutine "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
 attributes #1 = { nounwind readnone speculatable }
 attributes #2 = { argmemonly nounwind readonly }
 attributes #3 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
Index: llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll
+++ llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll
@@ -60,7 +60,7 @@
 ; CHECK-DAG: ![[IVAR_RESUME]] = !DILocalVariable(name: "i"
 ; CHECK-DAG: ![[JVAR_RESUME]] = !DILocalVariable(name: "j"
 ; CHECK-DAG: ![[JDBGLOC_RESUME]] = !DILocation(line: 32, column: 7, scope: ![[RESUME_SCOPE]])
-define void @f() "coroutine.presplit"="0" {
+define void @f() presplitcoroutine {
 entry:
   %__promise = alloca i8, align 8
   %i = alloca i32, align 4
Index: llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll
+++ llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll
@@ -19,7 +19,7 @@
 source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll"
 declare void @consume(i32)
 
-define void @f(i32 %i, i32 %j) "coroutine.presplit"="0" !dbg !8 {
+define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 {
 entry:
   %__promise = alloca i8, align 8
   %x = alloca [10 x i32], align 16
Index: llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll
+++ llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll
@@ -13,7 +13,7 @@
 
 source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll"
 
-define void @f(i32 %i, i32 %j) "coroutine.presplit"="0" !dbg !8 {
+define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 {
 entry:
   %__promise = alloca i8, align 8
   %x = alloca [10 x i32], align 16
Index: llvm/test/Transforms/Coroutines/coro-debug-dbg.addr.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-debug-dbg.addr.ll
+++ llvm/test/Transforms/Coroutines/coro-debug-dbg.addr.ll
@@ -43,7 +43,7 @@
 source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll"
 declare void @consume(i32)
 
-define void @f(i32 %i, i32 %j, i8* %ptr) "coroutine.presplit"="0" !dbg !8 {
+define void @f(i32 %i, i32 %j, i8* %ptr) presplitcoroutine !dbg !8 {
 entry:
   %__promise = alloca i8, align 8
   %x = alloca [10 x i32], align 16
Index: llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll
+++ llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll
@@ -57,7 +57,7 @@
 declare void @pi64(i64*)
 declare void @pdouble(double*)
 
-define void @f(i32 %a, i32 %b, i64 %c, double %d) "coroutine.presplit"="0" !dbg !8 {
+define void @f(i32 %a, i32 %b, i64 %c, double %d) presplitcoroutine !dbg !8 {
 entry:
     %__promise = alloca %promise_type, align 8
     %0 = bitcast %promise_type* %__promise to i8*
@@ -183,7 +183,7 @@
 
 }
 
-define void @bar(i32 %a, i64 %c, double %d) "coroutine.presplit"="0" !dbg !19 {
+define void @bar(i32 %a, i64 %c, double %d) presplitcoroutine !dbg !19 {
 entry:
     %__promise = alloca %promise_type, align 8
     %0 = bitcast %promise_type* %__promise to i8*
Index: llvm/test/Transforms/Coroutines/coro-debug-O2.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-debug-O2.ll
+++ llvm/test/Transforms/Coroutines/coro-debug-O2.ll
@@ -9,7 +9,7 @@
 ; CHECK: ![[PROMISEVAR_RESUME]] = !DILocalVariable(name: "__promise"
 %promise_type = type { i32, i32, double }
 
-define void @f() "coroutine.presplit"="0" !dbg !8  {
+define void @f() presplitcoroutine !dbg !8  {
 entry:
     %__promise = alloca %promise_type, align 8
     %0 = bitcast %promise_type* %__promise to i8*
Index: llvm/test/Transforms/Coroutines/coro-catchswitch.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-catchswitch.ll
+++ llvm/test/Transforms/Coroutines/coro-catchswitch.ll
@@ -5,7 +5,7 @@
 target triple = "i686-pc-windows-msvc"
 
 ; CHECK-LABEL: define void @f(
-define void @f(i1 %cond) "coroutine.presplit"="1" personality i32 0 {
+define void @f(i1 %cond) presplitcoroutine personality i32 0 {
 entry:
   %id = call token @llvm.coro.id(i32 8, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/coro-catchswitch-cleanuppad.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-catchswitch-cleanuppad.ll
+++ llvm/test/Transforms/Coroutines/coro-catchswitch-cleanuppad.ll
@@ -3,7 +3,7 @@
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg<switch-range-to-icmp>,early-cse' -S | FileCheck %s
 
 declare i32 @__CxxFrameHandler3(...)
-define i8* @f2(i1 %val) "coroutine.presplit"="1" personality i32 (...)* @__CxxFrameHandler3 {
+define i8* @f2(i1 %val) presplitcoroutine personality i32 (...)* @__CxxFrameHandler3 {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %valueA = call i32 @f();
Index: llvm/test/Transforms/Coroutines/coro-byval-param.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-byval-param.ll
+++ llvm/test/Transforms/Coroutines/coro-byval-param.ll
@@ -113,7 +113,7 @@
 ; Function Attrs: argmemonly nounwind readonly
 declare i8* @llvm.coro.free(token, i8* nocapture readonly) #1
 
-attributes #0 = { noinline ssp uwtable mustprogress "coroutine.presplit"="1" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
+attributes #0 = { noinline ssp uwtable mustprogress presplitcoroutine "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
 attributes #1 = { argmemonly nounwind readonly }
 attributes #2 = { nounwind }
 attributes #3 = { nobuiltin nofree allocsize(0) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
Index: llvm/test/Transforms/Coroutines/coro-async.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-async.ll
+++ llvm/test/Transforms/Coroutines/coro-async.ll
@@ -61,7 +61,7 @@
 }
 
 
-define swiftcc void @my_async_function(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor) "coroutine.presplit"="1" !dbg !1 {
+define swiftcc void @my_async_function(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor) presplitcoroutine !dbg !1 {
 entry:
   %tmp = alloca { i64, i64 }, align 8
   %vector = alloca <4 x double>, align 16
@@ -203,7 +203,7 @@
      i32 128    ; Initial async context size without space for frame
   }>
 
-define swiftcc void @my_async_function2(%async.task* %task, %async.actor* %actor, i8* %async.ctxt) "coroutine.presplit"="1" "frame-pointer"="all" !dbg !6 {
+define swiftcc void @my_async_function2(%async.task* %task, %async.actor* %actor, i8* %async.ctxt) presplitcoroutine "frame-pointer"="all" !dbg !6 {
 entry:
 
   %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 2, i8* bitcast (<{i32, i32}>* @my_async_function2_fp to i8*))
@@ -325,7 +325,7 @@
   ret void
 }
 
-define swiftcc void @dont_crash_on_cf(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) "coroutine.presplit"="1"  {
+define swiftcc void @dont_crash_on_cf(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) presplitcoroutine  {
 entry:
   %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
           i8* bitcast (<{i32, i32}>* @dont_crash_on_cf_fp to i8*))
@@ -371,7 +371,7 @@
   ret void
 }
 
-define swiftcc void @multiple_coro_end_async(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) "coroutine.presplit"="1" {
+define swiftcc void @multiple_coro_end_async(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
           i8* bitcast (<{i32, i32}>* @dont_crash_on_cf_fp to i8*))
@@ -427,7 +427,7 @@
      i32 64    ; Initial async context size without space for frame
 }>
 
-define swiftcc void @polymorphic_suspend_return(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor) "coroutine.presplit"="1" {
+define swiftcc void @polymorphic_suspend_return(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor) presplitcoroutine {
 entry:
   %tmp = alloca { i64, i64 }, align 8
   %proj.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 0
@@ -496,7 +496,7 @@
      i32 128    ; Initial async context size without space for frame
 }>
 
-define swiftcc void @no_coro_suspend(i8* %async.ctx) "coroutine.presplit"="1" {
+define swiftcc void @no_coro_suspend(i8* %async.ctx) presplitcoroutine {
 entry:
   %some_alloca = alloca i64
   %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
@@ -523,7 +523,7 @@
 
 declare void @do_with_swifterror(i64** swifterror)
 
-define swiftcc void @no_coro_suspend_swifterror(i8* %async.ctx) "coroutine.presplit"="1" {
+define swiftcc void @no_coro_suspend_swifterror(i8* %async.ctx) presplitcoroutine {
 entry:
   %some_alloca = alloca swifterror i64*
   %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
@@ -553,7 +553,7 @@
 declare void @crash()
 declare void @use(i8*)
 
-define swiftcc void @undefined_coro_async_resume(i8 *%async.ctx) "coroutine.presplit"="1" {
+define swiftcc void @undefined_coro_async_resume(i8 *%async.ctx) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id.async(i32 24, i32 16, i32 0, i8* bitcast (<{i32, i32}>* @undefined_coro_async_resume_fp to i8*))
   %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
Index: llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll
+++ llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll
@@ -62,7 +62,7 @@
 ; CHECK:  store i64 2, i64* [[T4]]
 ; CHECK:  store i64 3, i64* [[T9]]
 
-define swiftcc void @my_async_function(i8* swiftasync %async.ctxt) "coroutine.presplit"="1" {
+define swiftcc void @my_async_function(i8* swiftasync %async.ctxt) presplitcoroutine {
 entry:
   %tmp = alloca i64, align 8
   %tmp2 = alloca i64, align 16
Index: llvm/test/Transforms/Coroutines/coro-alloca-09.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-09.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-09.ll
@@ -14,7 +14,7 @@
 ; wouldn't live across suspend point.
 ; This test whether or not %testval would be put on the frame by ignoring the
 ; partial lifetime markers.
-define void @foo(%i8.array** %to_store) "coroutine.presplit"="1" {
+define void @foo(%i8.array** %to_store) presplitcoroutine {
 entry:
   %testval = alloca %i8.array
   %subrange = getelementptr inbounds %i8.array, %i8.array* %testval, i64 0, i32 0, i64 50
Index: llvm/test/Transforms/Coroutines/coro-alloca-08.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-08.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-08.ll
@@ -11,7 +11,7 @@
 
 ; The lifetime of testval starts and ends before coro.suspend. Even though consume.i8.array
 ; might capture it, we can safely say it won't live across suspension.
-define void @foo() "coroutine.presplit"="1" {
+define void @foo() presplitcoroutine {
 entry:
   %testval = alloca %i8.array
   %cast = getelementptr inbounds %i8.array, %i8.array* %testval, i64 0, i32 0, i64 0
@@ -39,7 +39,7 @@
 
 ; The lifetime of testval starts after coro.suspend. So it will never live across suspension
 ; points.
-define void @bar() "coroutine.presplit"="1" {
+define void @bar() presplitcoroutine {
 entry:
   %testval = alloca %i8.array
   %cast = getelementptr inbounds %i8.array, %i8.array* %testval, i64 0, i32 0, i64 0
Index: llvm/test/Transforms/Coroutines/coro-alloca-07.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-07.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-07.ll
@@ -2,7 +2,7 @@
 ; if their aliases are used across suspension points through PHINode.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f(i1 %n) "coroutine.presplit"="1" {
+define i8* @f(i1 %n) presplitcoroutine {
 entry:
   %x = alloca i64
   %y = alloca i64
Index: llvm/test/Transforms/Coroutines/coro-alloca-06.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-06.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-06.ll
@@ -4,7 +4,7 @@
 
 %handle = type { i8* }
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %0 = alloca %"handle", align 8
   %1 = alloca %"handle"*, align 8
Index: llvm/test/Transforms/Coroutines/coro-alloca-05.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-05.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-05.ll
@@ -2,7 +2,7 @@
 ; live on the frame are properly moved to the .resume function.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/coro-alloca-04.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-04.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-04.ll
@@ -2,7 +2,7 @@
 ; if their aliases are used across suspension points through PHINode.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f(i1 %n) "coroutine.presplit"="1" {
+define i8* @f(i1 %n) presplitcoroutine {
 entry:
   %x = alloca i64
   br i1 %n, label %flag_true, label %flag_false
Index: llvm/test/Transforms/Coroutines/coro-alloca-03.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-03.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-03.ll
@@ -1,7 +1,7 @@
 ; Tests that allocas escaped through function calls will live on the frame.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %x = alloca i64
   %y = alloca i64
Index: llvm/test/Transforms/Coroutines/coro-alloca-02.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-02.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-02.ll
@@ -2,7 +2,7 @@
 ; the alloac will be put on the frame.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %x = alloca i64
   %y = alloca i32*
Index: llvm/test/Transforms/Coroutines/coro-alloca-01.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloca-01.ll
+++ llvm/test/Transforms/Coroutines/coro-alloca-01.ll
@@ -2,7 +2,7 @@
 ; if their aliases are used across suspension points through PHINode.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f(i1 %n) "coroutine.presplit"="1" {
+define i8* @f(i1 %n) presplitcoroutine {
 entry:
   %x = alloca i64
   %y = alloca i64
Index: llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll
+++ llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll
@@ -3,7 +3,7 @@
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
 ; using this directly (as it would happen under -O2)
-define i8* @f_direct(i64 %this) "coroutine.presplit"="1" {
+define i8* @f_direct(i64 %this) presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll
+++ llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll
@@ -3,7 +3,7 @@
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,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" {
+define i8* @f_copy(i64 %this_arg) presplitcoroutine {
 entry:
   %this.addr = alloca i64
   store i64 %this_arg, i64* %this.addr
Index: llvm/test/Transforms/Coroutines/coro-align8.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-align8.ll
+++ llvm/test/Transforms/Coroutines/coro-align8.ll
@@ -1,7 +1,7 @@
 ; Tests that the coro.align intrinsic could be lowered to correct alignment
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %x = alloca i64
   %y = alloca i64
Index: llvm/test/Transforms/Coroutines/coro-align8-02.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-align8-02.ll
+++ llvm/test/Transforms/Coroutines/coro-align8-02.ll
@@ -1,7 +1,7 @@
 ; Tests that the coro.align intrinsic could be lowered to correct alignment
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
   %size = call i32 @llvm.coro.size.i32()
Index: llvm/test/Transforms/Coroutines/coro-align64.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-align64.ll
+++ llvm/test/Transforms/Coroutines/coro-align64.ll
@@ -1,7 +1,7 @@
 ; Tests that the coro.align intrinsic could be lowered to correct alignment
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %x = alloca i1, align 64
   %y = alloca i64
Index: llvm/test/Transforms/Coroutines/coro-align64-02.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-align64-02.ll
+++ llvm/test/Transforms/Coroutines/coro-align64-02.ll
@@ -1,7 +1,7 @@
 ; Tests that the coro.align intrinsic could be lowered to correct alignment
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %x = alloca i1, align 64
   %y = alloca i64, align 32
Index: llvm/test/Transforms/Coroutines/coro-align32.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-align32.ll
+++ llvm/test/Transforms/Coroutines/coro-align32.ll
@@ -1,7 +1,7 @@
 ; Tests that the coro.align intrinsic could be lowered to correct alignment
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %x = alloca i64, align 16
   %y = alloca i32, align 32
Index: llvm/test/Transforms/Coroutines/coro-align16.ll
===================================================================
--- llvm/test/Transforms/Coroutines/coro-align16.ll
+++ llvm/test/Transforms/Coroutines/coro-align16.ll
@@ -1,7 +1,7 @@
 ; Tests that the coro.align intrinsic could be lowered to correct alignment
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define i8* @f() "coroutine.presplit"="1" {
+define i8* @f() presplitcoroutine {
 entry:
   %x = alloca i64, align 16
   %y = alloca i64
Index: llvm/test/Transforms/Coroutines/ArgAddr.ll
===================================================================
--- llvm/test/Transforms/Coroutines/ArgAddr.ll
+++ llvm/test/Transforms/Coroutines/ArgAddr.ll
@@ -2,7 +2,7 @@
 ; coro.begin.
 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
 
-define nonnull i8* @f(i32 %n) "coroutine.presplit"="1" {
+define nonnull i8* @f(i32 %n) presplitcoroutine {
 ; CHECK-LABEL: @f(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ID:%.*]] = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* bitcast ([3 x void (%f.Frame*)*]* @f.resumers to i8*))
Index: llvm/lib/Transforms/Coroutines/CoroSplit.cpp
===================================================================
--- llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -2064,7 +2064,7 @@
   // Find coroutines for processing.
   SmallVector<LazyCallGraph::Node *> Coroutines;
   for (LazyCallGraph::Node &N : C)
-    if (N.getFunction().hasFnAttribute(CORO_PRESPLIT_ATTR))
+    if (N.getFunction().isPresplitCoroutine())
       Coroutines.push_back(&N);
 
   if (Coroutines.empty() && PrepareFns.empty())
@@ -2081,7 +2081,7 @@
     Function &F = N->getFunction();
     LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F.getName()
                       << "\n");
-    F.removeFnAttr(CORO_PRESPLIT_ATTR);
+    F.setSplittedCoroutine();
 
     SmallVector<Function *, 4> Clones;
     const coro::Shape Shape = splitCoroutine(F, Clones, OptimizeFrame);
Index: llvm/lib/Transforms/Coroutines/CoroInternal.h
===================================================================
--- llvm/lib/Transforms/Coroutines/CoroInternal.h
+++ llvm/lib/Transforms/Coroutines/CoroInternal.h
@@ -20,15 +20,6 @@
 class CallGraphSCC;
 class PassRegistry;
 
-// CoroEarly pass marks every function that has coro.begin with a string
-// attribute "coroutine.presplit". CoroSplit pass would processes the 
-// function marked as "coroutine.presplit" only.
-//
-// FIXME: Refactor these attributes as LLVM attributes instead of string
-// attributes since these attributes are already used outside LLVM's
-// coroutine module.
-#define CORO_PRESPLIT_ATTR "coroutine.presplit"
-
 namespace coro {
 
 bool declaresAnyIntrinsic(const Module &M);
Index: llvm/lib/Transforms/Coroutines/CoroEarly.cpp
===================================================================
--- llvm/lib/Transforms/Coroutines/CoroEarly.cpp
+++ llvm/lib/Transforms/Coroutines/CoroEarly.cpp
@@ -180,7 +180,7 @@
       case Intrinsic::coro_id:
         if (auto *CII = cast<CoroIdInst>(&I)) {
           if (CII->getInfo().isPreSplit()) {
-            assert(F.hasFnAttribute(CORO_PRESPLIT_ATTR) &&
+            assert(F.isPresplitCoroutine() &&
                    "The frontend uses Swtich-Resumed ABI should emit "
                    "\"coroutine.presplit\" attribute for the coroutine.");
             setCannotDuplicate(CII);
@@ -192,9 +192,7 @@
       case Intrinsic::coro_id_retcon:
       case Intrinsic::coro_id_retcon_once:
       case Intrinsic::coro_id_async:
-        // TODO: Remove the line once we support it in the corresponding
-        // frontend.
-        F.addFnAttr(CORO_PRESPLIT_ATTR);
+        F.setPresplitCoroutine();
         break;
       case Intrinsic::coro_resume:
         lowerResumeOrDestroy(*CB, CoroSubFnInst::ResumeIndex);
Index: llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
===================================================================
--- llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
+++ llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
@@ -45,8 +45,7 @@
 }
 
 bool Lowerer::lower(Function &F) {
-  bool IsPrivateAndUnprocessed =
-      F.hasFnAttribute(CORO_PRESPLIT_ATTR) && F.hasLocalLinkage();
+  bool IsPrivateAndUnprocessed = F.isPresplitCoroutine() && F.hasLocalLinkage();
   bool Changed = false;
 
   for (Instruction &I : llvm::make_early_inc_range(instructions(F))) {
Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -774,6 +774,8 @@
     return bitc::ATTR_KIND_BYREF;
   case Attribute::MustProgress:
     return bitc::ATTR_KIND_MUSTPROGRESS;
+  case Attribute::PresplitCoroutine:
+    return bitc::ATTR_KIND_PRESPLIT_COROUTINE;
   case Attribute::EndAttrKinds:
     llvm_unreachable("Can not encode end-attribute kinds marker.");
   case Attribute::None:
Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1634,6 +1634,8 @@
     return Attribute::MustProgress;
   case bitc::ATTR_KIND_HOT:
     return Attribute::Hot;
+  case bitc::ATTR_KIND_PRESPLIT_COROUTINE:
+    return Attribute::PresplitCoroutine;
   }
 }
 
Index: llvm/include/llvm/IR/Function.h
===================================================================
--- llvm/include/llvm/IR/Function.h
+++ llvm/include/llvm/IR/Function.h
@@ -484,11 +484,12 @@
     return AttributeSets.getParamDereferenceableOrNullBytes(ArgNo);
   }
 
-  /// A function will have the "coroutine.presplit" attribute if it's
-  /// a coroutine and has not gone through full CoroSplit pass.
+  /// Determine if the function is presplit coroutine.
   bool isPresplitCoroutine() const {
-    return hasFnAttribute("coroutine.presplit");
+    return hasFnAttribute(Attribute::PresplitCoroutine);
   }
+  void setPresplitCoroutine() { addFnAttr(Attribute::PresplitCoroutine); }
+  void setSplittedCoroutine() { removeFnAttr(Attribute::PresplitCoroutine); }
 
   /// Determine if the function does not access memory.
   bool doesNotAccessMemory() const {
Index: llvm/include/llvm/IR/Attributes.td
===================================================================
--- llvm/include/llvm/IR/Attributes.td
+++ llvm/include/llvm/IR/Attributes.td
@@ -303,6 +303,9 @@
 /// Function is required to make Forward Progress.
 def MustProgress : EnumAttr<"mustprogress", [FnAttr]>;
 
+/// Function is a presplit coroutine.
+def PresplitCoroutine : EnumAttr<"presplitcoroutine", [FnAttr]>;
+
 /// Target-independent string attributes.
 def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
 def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
Index: llvm/include/llvm/Bitcode/LLVMBitCodes.h
===================================================================
--- llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -685,6 +685,7 @@
   ATTR_KIND_ALLOC_ALIGN = 80,
   ATTR_KIND_ALLOCATED_POINTER = 81,
   ATTR_KIND_ALLOC_KIND = 82,
+  ATTR_KIND_PRESPLIT_COROUTINE = 83,
 };
 
 enum ComdatSelectionKindCodes {
Index: llvm/docs/Coroutines.rst
===================================================================
--- llvm/docs/Coroutines.rst
+++ llvm/docs/Coroutines.rst
@@ -1201,7 +1201,7 @@
 
 A frontend should emit exactly one `coro.id` intrinsic per coroutine.
 
-A frontend should emit function attribute `"coroutine.presplit"` for the coroutine.
+A frontend should emit function attribute `presplitcoroutine` for the coroutine.
 
 .. _coro.id.async:
 
@@ -1242,7 +1242,7 @@
 
 A frontend should emit exactly one `coro.id.async` intrinsic per coroutine.
 
-A frontend should emit function attribute `"coroutine.presplit"` for the coroutine.
+A frontend should emit function attribute `presplitcoroutine` for the coroutine.
 
 .. _coro.id.retcon:
 
@@ -1299,7 +1299,7 @@
 Semantics:
 """"""""""
 
-A frontend should emit function attribute `"coroutine.presplit"` for the coroutine.
+A frontend should emit function attribute `presplitcoroutine` for the coroutine.
 
 'llvm.coro.id.retcon.once' Intrinsic
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1325,7 +1325,7 @@
 Semantics:
 """"""""""
 
-A frontend should emit function attribute `"coroutine.presplit"` for the coroutine.
+A frontend should emit function attribute `presplitcoroutine` for the coroutine.
 
 .. _coro.end:
 
Index: clang/test/CodeGenCoroutines/coro-attributes.cpp
===================================================================
--- clang/test/CodeGenCoroutines/coro-attributes.cpp
+++ clang/test/CodeGenCoroutines/coro-attributes.cpp
@@ -14,7 +14,7 @@
 };
 
 // CHECK: void @_Z3foov() #[[FOO_ATTR_NUM:[0-9]+]]
-// CHECK: attributes #[[FOO_ATTR_NUM]] = { {{.*}} "coroutine.presplit"="0"
+// CHECK: attributes #[[FOO_ATTR_NUM]] = { {{.*}} presplitcoroutine
 coro foo() {
   co_await suspend_always{};
 }
Index: clang/lib/CodeGen/CGCoroutine.cpp
===================================================================
--- clang/lib/CodeGen/CGCoroutine.cpp
+++ clang/lib/CodeGen/CGCoroutine.cpp
@@ -654,9 +654,8 @@
     EmitStmt(Ret);
   }
 
-  // LLVM require the frontend to add the function attribute. See
-  // Coroutines.rst.
-  CurFn->addFnAttr("coroutine.presplit", "0");
+  // LLVM require the frontend to mark the coroutine.
+  CurFn->setPresplitCoroutine();
 }
 
 // Emit coroutine intrinsic and patch up arguments of the token type.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to