llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-coroutines @llvm/pr-subscribers-llvm-transforms Author: Weibo He (NewSigma) <details> <summary>Changes</summary> Consider the following code: ``` LLVM %hdl1 = call ptr @<!-- -->llvm.coro.begin(token %coro.outer, ptr %mem1) store ptr %hdl1, ptr %alloca, align 8 call i1 @<!-- -->llvm.coro.alloc(token %coro.inner) call ptr @<!-- -->llvm.coro.begin(token %coro.inner, ptr %mem2) %hdl1.ld = load ptr, ptr %alloca, align 8 %resumer = call ptr @<!-- -->llvm.coro.subfn.addr(ptr %hdl1.ld, i8 0) invoke void %resumer(ptr %hdl1.ld) ``` The pattern occurs inside nested coroutines. Adding `memory(none)` attributes allows GVN to replace the store-load with direct references to `coro.begin`, thus enabling further optimizations. We can simplify #<!-- -->57852 into single `ret 0` after this change. --- Full diff: https://github.com/llvm/llvm-project/pull/219870.diff 4 Files Affected: - (modified) clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp (+2-2) - (modified) llvm/include/llvm/IR/Intrinsics.td (+3-3) - (modified) llvm/test/Transforms/Coroutines/coro-byval-param.ll (+9-7) - (modified) llvm/test/Transforms/Coroutines/coro-split-alloc.ll (+1-2) ``````````diff diff --git a/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp b/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp index 97ef983b7523a..ace0bbca62dbb 100644 --- a/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp +++ b/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp @@ -55,12 +55,12 @@ coro_t f() { // CHECK-LPAD: invoke void @_Z9may_throwv() // CHECK-LPAD: to label %[[CONT:.+]] unwind label %[[CLEANUP:.+]] // CHECK-LPAD: [[CLEANUP]]: -// CHECK-LPAD: call void @_ZN7CleanupD1Ev(ptr {{[^,]*}} %x) #2 +// CHECK-LPAD: call void @_ZN7CleanupD1Ev(ptr {{[^,]*}} %x) #[[ATTR:[0-9]+]] // CHECK-LPAD: br label %[[CATCH:.+]] // CHECK-LPAD: [[CATCH]]: // CHECK-LPAD: call ptr @__cxa_begin_catch -// CHECK-LPAD: call void @_ZN6coro_t12promise_type19unhandled_exceptionEv(ptr {{[^,]*}} %__promise) #2 +// CHECK-LPAD: call void @_ZN6coro_t12promise_type19unhandled_exceptionEv(ptr {{[^,]*}} %__promise) #[[ATTR]] // CHECK-LPAD: invoke void @__cxa_end_catch() // CHECK-LPAD-NEXT: to label %[[CATCHRETDEST:.+]] unwind label // CHECK-LPAD: [[CATCHRETDEST]]: diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 1d960dc011a5a..0efe844900fd8 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1986,7 +1986,7 @@ def int_coro_id_retcon_once : Intrinsic<[llvm_token_ty], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty], []>; -def int_coro_alloc : Intrinsic<[llvm_i1_ty], [llvm_token_ty], []>; +def int_coro_alloc : Intrinsic<[llvm_i1_ty], [llvm_token_ty], [IntrNoMem]>; def int_coro_id_async : Intrinsic<[llvm_token_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; @@ -2007,10 +2007,10 @@ def int_coro_suspend_async def int_coro_prepare_async : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>; def int_coro_begin : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty], - [WriteOnly<ArgIndex<1>>]>; + [IntrArgMemOnly, WriteOnly<ArgIndex<1>>]>; def int_coro_begin_custom_abi : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty, llvm_i32_ty], - [WriteOnly<ArgIndex<1>>]>; + [IntrArgMemOnly, WriteOnly<ArgIndex<1>>]>; def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty], [IntrReadMem, IntrArgMemOnly, ReadOnly<ArgIndex<1>>, diff --git a/llvm/test/Transforms/Coroutines/coro-byval-param.ll b/llvm/test/Transforms/Coroutines/coro-byval-param.ll index 44204de99ea66..9e4f383653435 100644 --- a/llvm/test/Transforms/Coroutines/coro-byval-param.ll +++ b/llvm/test/Transforms/Coroutines/coro-byval-param.ll @@ -21,7 +21,7 @@ define ptr @foo(ptr nocapture readonly byval(%struct.A) align 8 %a1) #0 !prof !0 ; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.coro.alloc(token [[TMP0]]) ; CHECK-NEXT: br i1 [[TMP1]], label %[[CORO_ALLOC:.*]], label %[[CORO_INIT:.*]] ; CHECK: [[CORO_ALLOC]]: -; CHECK-NEXT: [[CALL:%.*]] = call noalias nonnull ptr @_Znwm(i64 48) #[[ATTR10:[0-9]+]] +; CHECK-NEXT: [[CALL:%.*]] = call noalias nonnull ptr @_Znwm(i64 48) #[[ATTR11:[0-9]+]] ; CHECK-NEXT: br label %[[CORO_INIT]] ; CHECK: [[CORO_INIT]]: ; CHECK-NEXT: [[TMP2:%.*]] = phi ptr [ [[CALL]], %[[CORO_ALLOC]] ], [ null, %[[ENTRY]] ] @@ -37,7 +37,7 @@ define ptr @foo(ptr nocapture readonly byval(%struct.A) align 8 %a1) #0 !prof !0 ; CHECK-NEXT: call void @initial_suspend(ptr nonnull dereferenceable(1) [[__PROMISE_RELOAD_ADDR]]) ; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 17 ; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR5]], align 1 -; CHECK-NEXT: call fastcc void @_ZNSt12experimental13coroutines_v116coroutine_handleIN4task12promise_typeEE12from_addressEPv(ptr [[TMP3]]) #[[ATTR2:[0-9]+]] +; CHECK-NEXT: call fastcc void @_ZNSt12experimental13coroutines_v116coroutine_handleIN4task12promise_typeEE12from_addressEPv(ptr [[TMP3]]) #[[ATTR8:[0-9]+]] ; CHECK-NEXT: ret ptr [[CALL2]] ; entry: @@ -159,16 +159,18 @@ attributes #10 = { noduplicate } ;. ; CHECK: attributes #[[ATTR0]] = { mustprogress noinline ssp uwtable "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" } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } -; CHECK: attributes #[[ATTR2]] = { nounwind } +; CHECK: attributes #[[ATTR2:[0-9]+]] = { nounwind memory(none) } ; CHECK: attributes #[[ATTR3:[0-9]+]] = { 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" } -; CHECK: attributes #[[ATTR4:[0-9]+]] = { nounwind memory(none) } +; CHECK: attributes #[[ATTR4:[0-9]+]] = { nounwind memory(argmem: readwrite) } ; CHECK: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } ; CHECK: attributes #[[ATTR6:[0-9]+]] = { mustprogress noinline nounwind ssp willreturn uwtable "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" } ; CHECK: attributes #[[ATTR7:[0-9]+]] = { nomerge nounwind } -; CHECK: attributes #[[ATTR8:[0-9]+]] = { nobuiltin nounwind "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" } -; CHECK: attributes #[[ATTR9:[0-9]+]] = { nounwind memory(argmem: read) } -; CHECK: attributes #[[ATTR10]] = { allocsize(0) } +; CHECK: attributes #[[ATTR8]] = { nounwind } +; CHECK: attributes #[[ATTR9:[0-9]+]] = { nobuiltin nounwind "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" } +; CHECK: attributes #[[ATTR10:[0-9]+]] = { nounwind memory(argmem: read) } +; CHECK: attributes #[[ATTR11]] = { allocsize(0) } ;. ; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000} ; CHECK: [[PROF1]] = !{!"unknown", !"coro-split"} +; CHECK: [[META2:![0-9]+]] = !{!"function_entry_count", i64 1333} ;. diff --git a/llvm/test/Transforms/Coroutines/coro-split-alloc.ll b/llvm/test/Transforms/Coroutines/coro-split-alloc.ll index db97cafeebbbb..3c3a2796d93ff 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-alloc.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-alloc.ll @@ -42,8 +42,7 @@ suspend: ; CHECK: %incremented = add i32 %argument, 1 ; CHECK-NEXT: store i32 %incremented, ptr %argument.addr ; CHECK-LABEL: dyn.alloc: -; CHECK: %allocator_argument = load i32, ptr %argument.addr -; CHECK: %alloc = call ptr @custom_alloctor(i32 24, i32 %allocator_argument) +; CHECK: %alloc = call ptr @custom_alloctor(i32 24, i32 %incremented) ; CHECK-LABEL: begin: ; CHECK: %print_argument = load i32, ptr %argument.addr ; CHECK: call void @print(i32 %print_argument) `````````` </details> https://github.com/llvm/llvm-project/pull/219870 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
