ychen added a comment. For coroutine `f0` in `test/CodeGenCoroutines/coro-alloc.cpp`
The allocation looks like this: ; Function Attrs: noinline nounwind optnone mustprogress define dso_local void @f0() #0 { entry: %0 = alloca %struct.global_new_delete_tag, align 1 %1 = alloca %struct.global_new_delete_tag, align 1 %__promise = alloca %"struct.std::experimental::coroutine_traits<void, global_new_delete_tag>::promise_type", align 1 %ref.tmp = alloca %struct.suspend_always, align 1 %undef.agg.tmp = alloca %struct.suspend_always, align 1 %agg.tmp = alloca %"struct.std::experimental::coroutine_handle", align 1 %agg.tmp2 = alloca %"struct.std::experimental::coroutine_handle.0", align 1 %undef.agg.tmp3 = alloca %"struct.std::experimental::coroutine_handle.0", align 1 %ref.tmp4 = alloca %struct.suspend_always, align 1 %undef.agg.tmp5 = alloca %struct.suspend_always, align 1 %agg.tmp7 = alloca %"struct.std::experimental::coroutine_handle", align 1 %agg.tmp8 = alloca %"struct.std::experimental::coroutine_handle.0", align 1 %undef.agg.tmp9 = alloca %"struct.std::experimental::coroutine_handle.0", align 1 %2 = bitcast %"struct.std::experimental::coroutine_traits<void, global_new_delete_tag>::promise_type"* %__promise to i8* %3 = call token @llvm.coro.id(i32 16, i8* %2, i8* null, i8* null) %4 = call i1 @llvm.coro.alloc(token %3) br i1 %4, label %coro.alloc, label %coro.init coro.alloc: ; preds = %entry %5 = call i64 @llvm.coro.size.i64() %6 = call i64 @llvm.coro.align.i64() %7 = sub nsw i64 %6, 16 %8 = icmp sgt i64 %7, 0 %9 = select i1 %8, i64 %7, i64 0 %10 = add i64 %5, %9 %call = call noalias nonnull i8* @_Znwm(i64 %10) #11 br label %coro.check.align coro.check.align: ; preds = %coro.alloc %11 = call i64 @llvm.coro.align.i64() %12 = icmp ugt i64 %11, 16 br i1 %12, label %coro.alloc.align, label %coro.init coro.alloc.align: ; preds = %coro.check.align %mask = sub i64 %11, 1 %intptr = ptrtoint i8* %call to i64 %over_boundary = add i64 %intptr, %mask %inverted_mask = xor i64 %mask, -1 %aligned_intptr = and i64 %over_boundary, %inverted_mask %diff = sub i64 %aligned_intptr, %intptr %aligned_result = getelementptr inbounds i8, i8* %call, i64 %diff call void @llvm.assume(i1 true) [ "align"(i8* %aligned_result, i64 %11) ] %13 = call i32 @llvm.coro.raw.frame.ptr.offset.i32() %14 = getelementptr inbounds i8, i8* %aligned_result, i32 %13 %15 = bitcast i8* %14 to i8** store i8* %call, i8** %15, align 8 br label %coro.init coro.init: ; preds = %coro.alloc.align, %coro.check.align, %entry %16 = phi i8* [ null, %entry ], [ %call, %coro.check.align ], [ %aligned_result, %coro.alloc.align ] %17 = call i8* @llvm.coro.begin(token %3, i8* %16) call void @_ZNSt12experimental16coroutine_traitsIJv21global_new_delete_tagEE12promise_type17get_return_objectEv(%"struct.std::experimental::coroutine_traits<void, global_new_delete_tag>::promise_type"* nonnull dereferenceable(1) %__promise) call void @_ZNSt12experimental16coroutine_traitsIJv21global_new_delete_tagEE12promise_type15initial_suspendEv(%"struct.std::experimental::coroutine_traits<void, global_new_delete_tag>::promise_type"* nonnull dereferenceable(1) %__promise) %call1 = call zeroext i1 @_ZN14suspend_always11await_readyEv(%struct.suspend_always* nonnull dereferenceable(1) %ref.tmp) #2 br i1 %call1, label %init.ready, label %init.suspend The deallocation looks like this: cleanup: ; preds = %final.ready, %final.cleanup, %init.cleanup %cleanup.dest.slot.0 = phi i32 [ 0, %final.ready ], [ 2, %final.cleanup ], [ 2, %init.cleanup ] %22 = call i8* @llvm.coro.free(token %3, i8* %17) %23 = icmp ne i8* %22, null br i1 %23, label %coro.free, label %after.coro.free coro.free: ; preds = %cleanup %24 = call i64 @llvm.coro.align.i64() %25 = icmp ugt i64 %24, 16 %26 = call i32 @llvm.coro.raw.frame.ptr.offset.i32() %27 = getelementptr inbounds i8, i8* %22, i32 %26 %28 = bitcast i8* %27 to i8** %29 = load i8*, i8** %28, align 8 %30 = select i1 %25, i8* %29, i8* %22 call void @_ZdlPv(i8* %30) #2 br label %after.coro.free after.coro.free: ; preds = %cleanup, %coro.free switch i32 %cleanup.dest.slot.0, label %unreachable [ i32 0, label %cleanup.cont i32 2, label %coro.ret ] cleanup.cont: ; preds = %after.coro.free br label %coro.ret coro.ret: ; preds = %cleanup.cont, %after.coro.free, %final.suspend, %init.suspend %31 = call i1 @llvm.coro.end(i8* null, i1 false) ret void unreachable: ; preds = %after.coro.free unreachable } Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D97915/new/ https://reviews.llvm.org/D97915 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits