From f3a7783bf37a751f359a6a9b4795a87922327c13 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 5 Apr 2023 15:53:15 +0200 Subject: [PATCH] [Coroutines] Convert some tests to opaque pointers (NFC) --- .../Transforms/Coroutines/coro-elide-musttail.ll | 48 +++---- .../Transforms/Coroutines/coro-retcon-alloca.ll | 150 ++++++++++----------- .../Coroutines/coro-retcon-once-value.ll | 75 +++++------ .../Coroutines/coro-retcon-resume-values.ll | 81 +++++------ .../Coroutines/coro-retcon-resume-values2.ll | 92 ++++++------- llvm/test/Transforms/Coroutines/coro-retcon.ll | 149 +++++++++----------- .../Transforms/Coroutines/coro-spill-after-phi.ll | 64 +++++---- .../Transforms/Coroutines/coro-split-recursive.ll | 15 +-- llvm/test/Transforms/Coroutines/coro-swifterror.ll | 95 +++++++------ 9 files changed, 354 insertions(+), 415 deletions(-) diff --git a/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll b/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll index ece3524..6c6e5a6 100644 --- a/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll +++ b/llvm/test/Transforms/Coroutines/coro-elide-musttail.ll @@ -2,65 +2,65 @@ ; Only run with new pass manager since old pass manager's alias analysis isn't ; powerful enough to tell that the tailcall's arguments don't alias the frame. ; -; RUN: opt -opaque-pointers=0 < %s -passes='coro-elide' -S | FileCheck %s -; RUN: opt -opaque-pointers=0 < %s -aa-pipeline= -passes='coro-elide' -S | FileCheck %s -check-prefix=NOAA +; RUN: opt < %s -passes='coro-elide' -S | FileCheck %s +; RUN: opt < %s -aa-pipeline= -passes='coro-elide' -S | FileCheck %s -check-prefix=NOAA -%"bar.Frame" = type { void (%"bar.Frame"*)*, void (%"bar.Frame"*)*, %"struct.coroutine::promise_type", i1 } +%"bar.Frame" = type { ptr, ptr, %"struct.coroutine::promise_type", i1 } %"struct.coroutine::promise_type" = type { i32 } -%"foo.Frame" = type { void (%"foo.Frame"*)*, void (%"foo.Frame"*)*, %"struct.coroutine::promise_type", i1, %"struct.coroutine::promise_type::final_awaitable" } +%"foo.Frame" = type { ptr, ptr, %"struct.coroutine::promise_type", i1, %"struct.coroutine::promise_type::final_awaitable" } %"struct.coroutine::promise_type" = type { i32 } %"struct.coroutine::promise_type::final_awaitable" = type { i8 } -@"bar.resumers" = private constant [3 x void (%"bar.Frame"*)*] [void (%"bar.Frame"*)* @"bar.resume", void (%"bar.Frame"*)* undef, void (%"bar.Frame"*)* undef] +@"bar.resumers" = private constant [3 x ptr] [ptr @"bar.resume", ptr undef, ptr undef] declare dso_local void @"bar"() align 2 -declare dso_local fastcc void @"bar.resume"(%"bar.Frame"* align 8 dereferenceable(24)) align 2 +declare dso_local fastcc void @"bar.resume"(ptr align 8 dereferenceable(24)) align 2 ; There is a musttail call. ; With alias analysis, we can tell that the frame does not interfere with CALL34, and hence we can keep the tailcalls. ; Without alias analysis, we have to keep the tailcalls. -define internal fastcc void @foo.resume_musttail(%"foo.Frame"* %FramePtr) { +define internal fastcc void @foo.resume_musttail(ptr %FramePtr) { ; CHECK-LABEL: @foo.resume_musttail( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = alloca [24 x i8], align 8 -; CHECK-NEXT: [[VFRAME:%.*]] = bitcast [24 x i8]* [[TMP0]] to i8* -; CHECK-NEXT: [[TMP1:%.*]] = tail call token @llvm.coro.id(i32 16, i8* null, i8* bitcast (void ()* @bar to i8*), i8* bitcast ([3 x void (%bar.Frame*)*]* @bar.resumers to i8*)) -; CHECK-NEXT: [[CALL34:%.*]] = call i8* undef() -; CHECK-NEXT: musttail call fastcc void undef(i8* [[CALL34]]) +; CHECK-NEXT: [[VFRAME:%.*]] = bitcast ptr [[TMP0]] to ptr +; CHECK-NEXT: [[TMP1:%.*]] = tail call token @llvm.coro.id(i32 16, ptr null, ptr @bar, ptr @bar.resumers) +; CHECK-NEXT: [[CALL34:%.*]] = call ptr undef() +; CHECK-NEXT: musttail call fastcc void undef(ptr [[CALL34]]) ; CHECK-NEXT: ret void ; ; NOAA-LABEL: @foo.resume_musttail( ; NOAA-NEXT: entry: ; NOAA-NEXT: [[TMP0:%.*]] = alloca [24 x i8], align 8 -; NOAA-NEXT: [[VFRAME:%.*]] = bitcast [24 x i8]* [[TMP0]] to i8* -; NOAA-NEXT: [[TMP1:%.*]] = call token @llvm.coro.id(i32 16, i8* null, i8* bitcast (void ()* @bar to i8*), i8* bitcast ([3 x void (%bar.Frame*)*]* @bar.resumers to i8*)) -; NOAA-NEXT: [[CALL34:%.*]] = call i8* undef() -; NOAA-NEXT: musttail call fastcc void undef(i8* [[CALL34]]) +; NOAA-NEXT: [[VFRAME:%.*]] = bitcast ptr [[TMP0]] to ptr +; NOAA-NEXT: [[TMP1:%.*]] = call token @llvm.coro.id(i32 16, ptr null, ptr @bar, ptr @bar.resumers) +; NOAA-NEXT: [[CALL34:%.*]] = call ptr undef() +; NOAA-NEXT: musttail call fastcc void undef(ptr [[CALL34]]) ; NOAA-NEXT: ret void ; entry: - %0 = tail call token @llvm.coro.id(i32 16, i8* null, i8* bitcast (void ()* @"bar" to i8*), i8* bitcast ([3 x void (%"bar.Frame"*)*]* @"bar.resumers" to i8*)) + %0 = tail call token @llvm.coro.id(i32 16, ptr null, ptr @"bar", ptr @"bar.resumers") %1 = tail call i1 @llvm.coro.alloc(token %0) - %2 = tail call i8* @llvm.coro.begin(token %0, i8* null) - call i8* @llvm.coro.subfn.addr(i8* %2, i8 1) - %call34 = call i8* undef() - musttail call fastcc void undef(i8* %call34) + %2 = tail call ptr @llvm.coro.begin(token %0, ptr null) + call ptr @llvm.coro.subfn.addr(ptr %2, i8 1) + %call34 = call ptr undef() + musttail call fastcc void undef(ptr %call34) ret void } ; Function Attrs: argmemonly nofree nosync nounwind willreturn -declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #0 +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #0 ; Function Attrs: argmemonly nounwind readonly -declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #1 +declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 ; Function Attrs: nounwind declare i1 @llvm.coro.alloc(token) #2 ; Function Attrs: nounwind -declare i8* @llvm.coro.begin(token, i8* writeonly) #2 +declare ptr @llvm.coro.begin(token, ptr writeonly) #2 ; Function Attrs: argmemonly nounwind readonly -declare i8* @llvm.coro.subfn.addr(i8* nocapture readonly, i8) #1 +declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 attributes #0 = { argmemonly nofree nosync nounwind willreturn } attributes #1 = { argmemonly nounwind readonly } diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll index 307615d..a4b6945 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll @@ -1,32 +1,30 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -opaque-pointers=0 < %s -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s target datalayout = "p:64:64:64" -declare {i8*, i8*, i32} @prototype_f(i8*, i1) -define {i8*, i8*, i32} @f(i8* %buffer, i32 %n) { +declare {ptr, ptr, i32} @prototype_f(ptr, i1) +define {ptr, ptr, i32} @f(ptr %buffer, i32 %n) { ; CHECK-LABEL: @f( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds i8, i8* [[BUFFER:%.*]], i64 8 -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[N_VAL_SPILL_ADDR]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[TMP0]], align 4 -; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @allocate(i32 [[N]]) -; CHECK-NEXT: [[DOTSPILL_ADDR:%.*]] = bitcast i8* [[BUFFER]] to i8** -; CHECK-NEXT: store i8* [[TMP1]], i8** [[DOTSPILL_ADDR]], align 8 -; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i8*, i8*, i32 } { i8* bitcast ({ i8*, i8*, i32 } (i8*, i1)* @f.resume.0 to i8*), i8* undef, i32 undef }, i8* [[TMP1]], 1 -; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i8*, i8*, i32 } [[TMP2]], i32 [[N]], 2 -; CHECK-NEXT: ret { i8*, i8*, i32 } [[TMP3]] +; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[BUFFER:%.*]], i64 0, i32 1 +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[N_VAL_SPILL_ADDR]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @allocate(i32 [[N]]) +; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER]], align 8 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, ptr, i32 } { ptr @f.resume.0, ptr undef, i32 undef }, ptr [[TMP0]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr, ptr, i32 } [[TMP1]], i32 [[N]], 2 +; CHECK-NEXT: ret { ptr, ptr, i32 } [[TMP2]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, i8* %buffer, i8* bitcast ({i8*, i8*, i32} (i8*, i1)* @prototype_f 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) + %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_f, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ] %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %n.val, i32 8) - %ptr = call i8* @llvm.coro.alloca.get(token %alloca) - %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(i8* %ptr, i32 %n.val) + %ptr = call ptr @llvm.coro.alloca.get(token %alloca) + %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %ptr, i32 %n.val) call void @llvm.coro.alloca.free(token %alloca) br i1 %unwind, label %cleanup, label %resume @@ -35,34 +33,33 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -declare {i8*, i32} @prototype_g(i8*, i1) -define {i8*, i32} @g(i8* %buffer, i32 %n) { +declare {ptr, i32} @prototype_g(ptr, i1) +define {ptr, i32} @g(ptr %buffer, i32 %n) { ; CHECK-LABEL: @g( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = bitcast i8* [[BUFFER:%.*]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_VAL_SPILL_ADDR]], align 4 +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4 ; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[TMP0]], align 8 -; CHECK-NEXT: tail call void @use(i8* nonnull [[TMP1]]) -; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i8*, i32 } { i8* bitcast ({ i8*, i32 } (i8*, i1)* @g.resume.0 to i8*), i32 undef }, i32 [[N]], 1 -; CHECK-NEXT: ret { i8*, i32 } [[TMP2]] +; CHECK-NEXT: tail call void @use(ptr nonnull [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr, i32 } { ptr @g.resume.0, i32 undef }, i32 [[N]], 1 +; CHECK-NEXT: ret { ptr, i32 } [[TMP2]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, i8* %buffer, i8* bitcast ({i8*, i32} (i8*, i1)* @prototype_g 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) + %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ] %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %n.val, i32 8) - %ptr = call i8* @llvm.coro.alloca.get(token %alloca) - call void @use(i8* %ptr) + %ptr = call ptr @llvm.coro.alloca.get(token %alloca) + call void @use(ptr %ptr) call void @llvm.coro.alloca.free(token %alloca) %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 %n.val) br i1 %unwind, label %cleanup, label %resume @@ -72,24 +69,23 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -declare {i8*, i32} @prototype_h(i8*, i1) -define {i8*, i32} @h(i8* %buffer, i32 %n) { +declare {ptr, i32} @prototype_h(ptr, i1) +define {ptr, i32} @h(ptr %buffer, i32 %n) { ; CHECK-LABEL: @h( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[N_SPILL_ADDR:%.*]] = bitcast i8* [[BUFFER:%.*]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_SPILL_ADDR]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i8*, i32 } { i8* bitcast ({ i8*, i32 } (i8*, i1)* @h.resume.0 to i8*), i32 undef }, i32 [[N]], 1 -; CHECK-NEXT: ret { i8*, i32 } [[TMP0]] +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } { ptr @h.resume.0, i32 undef }, i32 [[N]], 1 +; CHECK-NEXT: ret { ptr, i32 } [[TMP0]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, i8* %buffer, i8* bitcast ({i8*, i32} (i8*, i1)* @prototype_h 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) + %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_h, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: @@ -100,30 +96,29 @@ loop: resume: %inc = add i32 %n.val, 1 %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %inc, i32 8) - %ptr = call i8* @llvm.coro.alloca.get(token %alloca) - call void @use(i8* %ptr) + %ptr = call ptr @llvm.coro.alloca.get(token %alloca) + call void @use(ptr %ptr) call void @llvm.coro.alloca.free(token %alloca) br label %loop cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -declare {i8*, i32} @prototype_i(i8*) -define {i8*, i32} @i(i8* %buffer, i32 %n) { +declare {ptr, i32} @prototype_i(ptr) +define {ptr, i32} @i(ptr %buffer, i32 %n) { ; CHECK-LABEL: @i( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = bitcast i8* [[BUFFER:%.*]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_VAL_SPILL_ADDR]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i8*, i32 } { i8* bitcast ({ i8*, i32 } (i8*)* @i.resume.0 to i8*), i32 undef }, i32 [[N]], 1 -; CHECK-NEXT: ret { i8*, i32 } [[TMP0]] +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } { ptr @i.resume.0, i32 undef }, i32 [[N]], 1 +; CHECK-NEXT: ret { ptr, i32 } [[TMP0]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, i8* %buffer, i8* bitcast ({i8*, i32} (i8*)* @prototype_i 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) + %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_i, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: @@ -135,8 +130,8 @@ loop: loop2: %k = phi i32 [ %inc, %loop ], [ %k2, %loop2 ] %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %k, i32 8) - %ptr = call i8* @llvm.coro.alloca.get(token %alloca) - call void @use(i8* %ptr) + %ptr = call ptr @llvm.coro.alloca.get(token %alloca) + call void @use(ptr %ptr) call void @llvm.coro.alloca.free(token %alloca) %k2 = lshr i32 %k, 1 %cmp = icmp ugt i32 %k, 128 @@ -145,24 +140,23 @@ loop2: -declare {i8*, i32} @prototype_j(i8*) -define {i8*, i32} @j(i8* %buffer, i32 %n) { +declare {ptr, i32} @prototype_j(ptr) +define {ptr, i32} @j(ptr %buffer, i32 %n) { ; CHECK-LABEL: @j( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = bitcast i8* [[BUFFER:%.*]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_VAL_SPILL_ADDR]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i8*, i32 } { i8* bitcast ({ i8*, i32 } (i8*)* @j.resume.0 to i8*), i32 undef }, i32 [[N]], 1 -; CHECK-NEXT: ret { i8*, i32 } [[TMP0]] +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } { ptr @j.resume.0, i32 undef }, i32 [[N]], 1 +; CHECK-NEXT: ret { ptr, i32 } [[TMP0]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, i8* %buffer, i8* bitcast ({i8*, i32} (i8*)* @prototype_j 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) + %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_j, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %forward back: ; We should encounter this 'get' before we encounter the 'alloc'. - %ptr = call i8* @llvm.coro.alloca.get(token %alloca) - call void @use(i8* %ptr) + %ptr = call ptr @llvm.coro.alloca.get(token %alloca) + call void @use(ptr %ptr) call void @llvm.coro.alloca.free(token %alloca) %k = add i32 %n.val, 1 %cmp = icmp ugt i32 %k, 128 @@ -176,28 +170,28 @@ forward: br label %back end: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } declare i32 @getSize() -define {i8*, i32} @k(i8* %buffer, i32 %n, i1 %cond) { +define {ptr, i32} @k(ptr %buffer, i32 %n, i1 %cond) { ; CHECK-LABEL: @k( ; CHECK-NEXT: PostSpill: ; CHECK-NEXT: [[SIZE:%.*]] = tail call i32 @getSize() ; CHECK-NEXT: br i1 [[COND:%.*]], label [[ALLOCA_BLOCK:%.*]], label [[CORO_RETURN:%.*]] ; CHECK: coro.return: -; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i8*, i32 } { i8* bitcast ({ i8*, i32 } (i8*, i1)* @k.resume.0 to i8*), i32 undef }, i32 [[N:%.*]], 1 -; CHECK-NEXT: ret { i8*, i32 } [[TMP0]] +; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } { ptr @k.resume.0, i32 undef }, i32 [[N:%.*]], 1 +; CHECK-NEXT: ret { ptr, i32 } [[TMP0]] ; CHECK: alloca_block: ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[SIZE]] to i64 ; CHECK-NEXT: [[TMP2:%.*]] = alloca i8, i64 [[TMP1]], align 8 -; CHECK-NEXT: tail call void @use(i8* nonnull [[TMP2]]) +; CHECK-NEXT: tail call void @use(ptr nonnull [[TMP2]]) ; CHECK-NEXT: br label [[CORO_RETURN]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, i8* %buffer, i8* bitcast ({i8*, i32} (i8*, i1)* @prototype_g 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) + %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br i1 %cond, label %alloca_block, label %non_alloca_block suspend: @@ -213,8 +207,8 @@ alloca_block: ; Make sure code that runs after that lowering does not hoist the dynamic ; alloca into the entry block of the resume function. %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %size, i32 8) - %ptr = call i8* @llvm.coro.alloca.get(token %alloca) - call void @use(i8* %ptr) + %ptr = call ptr @llvm.coro.alloca.get(token %alloca) + call void @use(ptr %ptr) call void @llvm.coro.alloca.free(token %alloca) br label %suspend @@ -223,22 +217,22 @@ non_alloca_block: br label %suspend cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*) -declare i8* @llvm.coro.begin(token, i8*) +declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) declare void @llvm.coro.suspend.retcon.isVoid(...) -declare i1 @llvm.coro.end(i8*, i1) -declare i8* @llvm.coro.prepare.retcon(i8*) +declare i1 @llvm.coro.end(ptr, i1) +declare ptr @llvm.coro.prepare.retcon(ptr) declare token @llvm.coro.alloca.alloc.i32(i32, i32) -declare i8* @llvm.coro.alloca.get(token) +declare ptr @llvm.coro.alloca.get(token) declare void @llvm.coro.alloca.free(token) -declare noalias i8* @allocate(i32 %size) -declare void @deallocate(i8* %ptr) +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) declare void @print(i32) -declare void @use(i8*) +declare void @use(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll index ed22a75..eb4626d 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll @@ -1,26 +1,25 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -opaque-pointers=0 < %s -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s 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* %array) { +define {ptr, i32} @f(ptr %buffer, ptr %array) { ; CHECK-LABEL: @f( ; CHECK-NEXT: PostSpill: -; CHECK-NEXT: [[ARRAY_SPILL_ADDR:%.*]] = bitcast i8* [[BUFFER:%.*]] to i32** -; CHECK-NEXT: store i32* [[ARRAY:%.*]], i32** [[ARRAY_SPILL_ADDR]], align 8 -; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[ARRAY]], align 4 +; CHECK-NEXT: store ptr [[ARRAY:%.*]], ptr [[BUFFER:%.*]], align 8 +; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[ARRAY]], align 4 ; CHECK-NEXT: [[LOAD_POS:%.*]] = icmp sgt i32 [[LOAD]], 0 -; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD]], i32 0) -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[LOAD_POS]], i8* bitcast (void (i8*, i1)* @f.resume.0 to i8*), i8* bitcast (void (i8*, i1)* @f.resume.1 to i8*) -; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i8*, i32 } undef, i8* [[TMP1]], 0 -; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i8*, i32 } [[TMP2]], i32 [[TMP0]], 1 -; CHECK-NEXT: ret { i8*, i32 } [[TMP3]] +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[LOAD_POS]], ptr @f.resume.0, ptr @f.resume.1 +; CHECK-NEXT: [[SPEC_SELECT4:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD]], i32 0) +; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } undef, ptr [[SPEC_SELECT]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, i32 } [[TMP0]], i32 [[SPEC_SELECT4]], 1 +; CHECK-NEXT: ret { ptr, i32 } [[TMP1]] ; entry: - %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*)) - %hdl = call i8* @llvm.coro.begin(token %id, i8* null) - %load = load i32, i32* %array + %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) + %load = load i32, ptr %array %load.pos = icmp sgt i32 %load, 0 br i1 %load.pos, label %pos, label %neg @@ -29,7 +28,7 @@ pos: br i1 %unwind0, label %cleanup, label %pos.cont pos.cont: - store i32 0, i32* %array, align 4 + store i32 0, ptr %array, align 4 br label %cleanup neg: @@ -37,55 +36,51 @@ neg: br i1 %unwind1, label %cleanup, label %neg.cont neg.cont: - store i32 10, i32* %array, align 4 + store i32 10, ptr %array, align 4 br label %cleanup cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -define void @test(i32* %array) { +define void @test(ptr %array) { ; CHECK-LABEL: @test( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: [[DOTSUB:%.*]] = bitcast i32** [[TMP0]] to i8* -; CHECK-NEXT: store i32* [[ARRAY:%.*]], i32** [[TMP0]], align 8 -; CHECK-NEXT: [[LOAD_I:%.*]] = load i32, i32* [[ARRAY]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = alloca [8 x i8], align 8 +; CHECK-NEXT: store ptr [[ARRAY:%.*]], ptr [[TMP0]], align 8 +; CHECK-NEXT: [[LOAD_I:%.*]] = load i32, ptr [[ARRAY]], align 4 ; CHECK-NEXT: [[LOAD_POS_I:%.*]] = icmp sgt i32 [[LOAD_I]], 0 -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD_I]], i32 0) -; CHECK-NEXT: tail call void @print(i32 [[TMP1]]) -; CHECK-NEXT: [[CONT_CAST:%.*]] = select i1 [[LOAD_POS_I]], void (i8*, i1)* @f.resume.0, void (i8*, i1)* @f.resume.1 -; CHECK-NEXT: call void [[CONT_CAST]](i8* nonnull [[DOTSUB]], i1 zeroext false) +; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = select i1 [[LOAD_POS_I]], ptr @f.resume.0, ptr @f.resume.1 +; CHECK-NEXT: [[SPEC_SELECT4_I:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD_I]], i32 0) +; CHECK-NEXT: tail call void @print(i32 [[SPEC_SELECT4_I]]) +; CHECK-NEXT: call void [[SPEC_SELECT_I]](ptr nonnull [[TMP0]], i1 zeroext false) ; CHECK-NEXT: ret void ; entry: %0 = alloca [8 x i8], align 8 - %buffer = bitcast [8 x i8]* %0 to i8* - %prepare = call i8* @llvm.coro.prepare.retcon(i8* bitcast ({i8*, i32} (i8*, i32*)* @f to i8*)) - %f = bitcast i8* %prepare to {i8*, i32} (i8*, i32*)* - %result = call {i8*, i32} %f(i8* %buffer, i32* %array) - %value = extractvalue {i8*, i32} %result, 1 + %prepare = call ptr @llvm.coro.prepare.retcon(ptr @f) + %result = call {ptr, i32} %prepare(ptr %0, ptr %array) + %value = extractvalue {ptr, i32} %result, 1 call void @print(i32 %value) - %cont = extractvalue {i8*, i32} %result, 0 - %cont.cast = bitcast i8* %cont to void (i8*, i1)* - call void %cont.cast(i8* %buffer, i1 zeroext 0) + %cont = extractvalue {ptr, i32} %result, 0 + call void %cont(ptr %0, i1 zeroext 0) ret void } ; Unfortunately, we don't seem to fully optimize this right now due ; to some sort of phase-ordering thing. -declare token @llvm.coro.id.retcon.once(i32, i32, i8*, i8*, i8*, i8*) -declare i8* @llvm.coro.begin(token, i8*) +declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) +declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(i8*, i1) -declare i8* @llvm.coro.prepare.retcon(i8*) +declare i1 @llvm.coro.end(ptr, i1) +declare ptr @llvm.coro.prepare.retcon(ptr) -declare void @prototype(i8*, i1 zeroext) +declare void @prototype(ptr, i1 zeroext) -declare noalias i8* @allocate(i32 %size) -declare void @deallocate(i8* %ptr) +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll index c186ce3..09a17f8 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll @@ -1,19 +1,17 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -opaque-pointers=0 < %s -passes="default" -aa-pipeline=default -S | FileCheck %s +; RUN: opt < %s -passes="default" -aa-pipeline=default -S | FileCheck %s -define i8* @f(i8* %buffer, i32 %n) { +define ptr @f(ptr %buffer, i32 %n) { ; CHECK-LABEL: @f( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @allocate(i32 12) -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[BUFFER:%.*]] to i8** -; CHECK-NEXT: store i8* [[TMP0]], i8** [[TMP1]], align 8 -; CHECK-NEXT: [[N_SPILL_ADDR:%.*]] = bitcast i8* [[TMP0]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_SPILL_ADDR]], align 4 -; CHECK-NEXT: ret i8* bitcast (i8* (i8*, i32, i1)* @f.resume.0 to i8*) +; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @allocate(i32 12) +; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8 +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[TMP0]], align 4 +; CHECK-NEXT: ret ptr @f.resume.0 ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast (i8* (i8*, i32, i1)* @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) + %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: @@ -29,7 +27,7 @@ resume: cleanup: call void @print(i32 %n.val) - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } @@ -38,56 +36,43 @@ cleanup: define i32 @main() { ; CHECK-LABEL: @main( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @allocate(i32 12) -; CHECK-NEXT: [[N_SPILL_ADDR_I:%.*]] = bitcast i8* [[TMP0]] to i32* -; CHECK-NEXT: store i32 1, i32* [[N_SPILL_ADDR_I]], align 4 -; CHECK-NEXT: [[N_VAL3_SPILL_ADDR_I:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4 -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[N_VAL3_SPILL_ADDR_I]] to i32* -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 4, !noalias !0 -; CHECK-NEXT: [[INPUT_SPILL_ADDR_I:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 8 -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[INPUT_SPILL_ADDR_I]] to i32* -; CHECK-NEXT: store i32 2, i32* [[TMP2]], align 4, !noalias !0 -; CHECK-NEXT: [[INPUT_RELOAD_ADDR13_I:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 8 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast i8* [[INPUT_RELOAD_ADDR13_I]] to i32* -; CHECK-NEXT: [[N_VAL3_RELOAD_ADDR11_I:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4 -; CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[N_VAL3_RELOAD_ADDR11_I]] to i32* -; CHECK-NEXT: [[N_VAL3_RELOAD12_I:%.*]] = load i32, i32* [[TMP4]], align 4, !noalias !3 -; CHECK-NEXT: [[SUM7_I:%.*]] = add i32 [[N_VAL3_RELOAD12_I]], 2 -; CHECK-NEXT: store i32 [[SUM7_I]], i32* [[TMP4]], align 4, !noalias !3 -; CHECK-NEXT: store i32 4, i32* [[TMP3]], align 4, !noalias !3 -; CHECK-NEXT: [[SUM7_I7:%.*]] = add i32 [[N_VAL3_RELOAD12_I]], 6 -; CHECK-NEXT: tail call void @print(i32 [[SUM7_I7]]), !noalias !6 -; CHECK-NEXT: tail call void @deallocate(i8* [[TMP0]]), !noalias !6 +; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @allocate(i32 12) +; CHECK-NEXT: store i32 1, ptr [[TMP0]], align 4 +; CHECK-NEXT: [[N_VAL3_SPILL_ADDR_I:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP0]], i64 0, i32 1 +; CHECK-NEXT: store i32 1, ptr [[N_VAL3_SPILL_ADDR_I]], align 4, !noalias !0 +; CHECK-NEXT: [[INPUT_SPILL_ADDR_I:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP0]], i64 0, i32 2 +; CHECK-NEXT: store i32 2, ptr [[INPUT_SPILL_ADDR_I]], align 4, !noalias !0 +; CHECK-NEXT: [[INPUT_RELOAD_ADDR13_I:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP0]], i64 0, i32 2 +; CHECK-NEXT: [[N_VAL3_RELOAD_ADDR11_I:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP0]], i64 0, i32 1 +; CHECK-NEXT: store i32 3, ptr [[N_VAL3_RELOAD_ADDR11_I]], align 4, !noalias !3 +; CHECK-NEXT: store i32 4, ptr [[INPUT_RELOAD_ADDR13_I]], align 4, !noalias !3 +; CHECK-NEXT: tail call void @print(i32 7), !noalias !6 +; CHECK-NEXT: tail call void @deallocate(ptr nonnull [[TMP0]]), !noalias !6 ; CHECK-NEXT: ret i32 0 ; entry: %0 = alloca [8 x i8], align 4 - %buffer = bitcast [8 x i8]* %0 to i8* - %prepare = call i8* @llvm.coro.prepare.retcon(i8* bitcast (i8* (i8*, i32)* @f to i8*)) - %f = bitcast i8* %prepare to i8* (i8*, i32)* - %cont0 = call i8* %f(i8* %buffer, i32 1) - %cont0.cast = bitcast i8* %cont0 to i8* (i8*, i32, i1)* - %cont1 = call i8* %cont0.cast(i8* %buffer, i32 2, i1 zeroext false) - %cont1.cast = bitcast i8* %cont1 to i8* (i8*, i32, i1)* - %cont2 = call i8* %cont1.cast(i8* %buffer, i32 4, i1 zeroext false) - %cont2.cast = bitcast i8* %cont2 to i8* (i8*, i32, i1)* - call i8* %cont2.cast(i8* %buffer, i32 100, i1 zeroext true) + %prepare = call ptr @llvm.coro.prepare.retcon(ptr @f) + %cont0 = call ptr %prepare(ptr %0, i32 1) + %cont1 = call ptr %cont0(ptr %0, i32 2, i1 zeroext false) + %cont2 = call ptr %cont1(ptr %0, i32 4, i1 zeroext false) + call ptr %cont2(ptr %0, i32 100, i1 zeroext true) ret i32 0 } ; Unfortunately, we don't seem to fully optimize this right now due ; to some sort of phase-ordering thing. -declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*) -declare i8* @llvm.coro.begin(token, i8*) +declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +declare ptr @llvm.coro.begin(token, ptr) declare { i32, i1 } @llvm.coro.suspend.retcon.sl_i32i1s(...) -declare i1 @llvm.coro.end(i8*, i1) -declare i8* @llvm.coro.prepare.retcon(i8*) +declare i1 @llvm.coro.end(ptr, i1) +declare ptr @llvm.coro.prepare.retcon(ptr) -declare i8* @prototype(i8*, i32, i1 zeroext) +declare ptr @prototype(ptr, i32, i1 zeroext) -declare noalias i8* @allocate(i32 %size) -declare void @deallocate(i8* %ptr) +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll index 9585e19..7c00464 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll @@ -1,10 +1,10 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs -; RUN: opt -opaque-pointers=0 < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg,coro-cleanup' -S | FileCheck %s +; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg,coro-cleanup' -S | FileCheck %s -define i8* @f(i8* %buffer, i32 %n) presplitcoroutine { +define ptr @f(ptr %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) + %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) %value0 = call i32 (...) @llvm.coro.suspend.retcon.i32() %sum0 = call i32 @add(i32 %n, i32 %value0) %value1 = call i32 (...) @llvm.coro.suspend.retcon.i32() @@ -15,81 +15,73 @@ entry: %sum4 = call i32 @add(i32 %sum3, i32 %value1) %sum5 = call i32 @add(i32 %sum4, i32 %value2) call void @print(i32 %sum5) - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*) -declare i8* @llvm.coro.begin(token, i8*) +declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +declare ptr @llvm.coro.begin(token, ptr) declare i32 @llvm.coro.suspend.retcon.i32(...) -declare i1 @llvm.coro.end(i8*, i1) -declare i8* @llvm.coro.prepare.retcon(i8*) +declare i1 @llvm.coro.end(ptr, i1) +declare ptr @llvm.coro.prepare.retcon(ptr) -declare i8* @prototype(i8*, i32) +declare ptr @prototype(ptr, i32) -declare noalias i8* @allocate(i32 %size) -declare void @deallocate(i8* %ptr) +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) declare i32 @add(i32, i32) declare void @print(i32) ; CHECK-LABEL: @f( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = call i8* @allocate(i32 20) -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[BUFFER:%.*]] to i8** -; CHECK-NEXT: store i8* [[TMP0]], i8** [[TMP1]], align 8 -; CHECK-NEXT: [[FRAMEPTR:%.*]] = bitcast i8* [[TMP0]] to %f.Frame* -; CHECK-NEXT: [[N_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], %f.Frame* [[FRAMEPTR]], i32 0, i32 0 -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_SPILL_ADDR]], align 4 -; CHECK-NEXT: ret i8* bitcast (i8* (i8*, i32)* @f.resume.0 to i8*) +; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 20) +; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8 +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[TMP0]], align 4 +; CHECK-NEXT: ret ptr @f.resume.0 ; ; ; CHECK-LABEL: @f.resume.0( ; CHECK-NEXT: entryresume.0: -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP0:%.*]] to %f.Frame** -; CHECK-NEXT: [[FRAMEPTR:%.*]] = load %f.Frame*, %f.Frame** [[TMP2]], align 8 -; CHECK-NEXT: [[VALUE0_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], %f.Frame* [[FRAMEPTR]], i32 0, i32 1 -; CHECK-NEXT: store i32 [[TMP1:%.*]], i32* [[VALUE0_SPILL_ADDR]], align 4 -; CHECK-NEXT: [[N_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 0 -; CHECK-NEXT: [[N_RELOAD:%.*]] = load i32, i32* [[N_RELOAD_ADDR]], align 4 +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: [[VALUE0_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 1 +; CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[VALUE0_SPILL_ADDR]], align 4 +; CHECK-NEXT: [[N_RELOAD:%.*]] = load i32, ptr [[TMP2]], align 4 ; CHECK-NEXT: [[SUM0:%.*]] = call i32 @add(i32 [[N_RELOAD]], i32 [[TMP1]]) -; CHECK-NEXT: [[SUM0_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 2 -; CHECK-NEXT: store i32 [[SUM0]], i32* [[SUM0_SPILL_ADDR]], align 4 -; CHECK-NEXT: ret i8* bitcast (i8* (i8*, i32)* @f.resume.1 to i8*) +; CHECK-NEXT: [[SUM0_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 2 +; CHECK-NEXT: store i32 [[SUM0]], ptr [[SUM0_SPILL_ADDR]], align 4 +; CHECK-NEXT: ret ptr @f.resume.1 ; ; ; CHECK-LABEL: @f.resume.1( ; CHECK-NEXT: entryresume.1: -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP0:%.*]] to %f.Frame** -; CHECK-NEXT: [[FRAMEPTR:%.*]] = load %f.Frame*, %f.Frame** [[TMP2]], align 8 -; CHECK-NEXT: [[VALUE1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], %f.Frame* [[FRAMEPTR]], i32 0, i32 3 -; CHECK-NEXT: store i32 [[TMP1:%.*]], i32* [[VALUE1_SPILL_ADDR]], align 4 -; CHECK-NEXT: [[SUM0_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 2 -; CHECK-NEXT: [[SUM0_RELOAD:%.*]] = load i32, i32* [[SUM0_RELOAD_ADDR]], align 4 -; CHECK-NEXT: [[VALUE0_RELOAD_ADDR5:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 1 -; CHECK-NEXT: [[VALUE0_RELOAD6:%.*]] = load i32, i32* [[VALUE0_RELOAD_ADDR5]], align 4 +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: [[VALUE1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 3 +; CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[VALUE1_SPILL_ADDR]], align 4 +; CHECK-NEXT: [[SUM0_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 2 +; CHECK-NEXT: [[SUM0_RELOAD:%.*]] = load i32, ptr [[SUM0_RELOAD_ADDR]], align 4 +; CHECK-NEXT: [[VALUE0_RELOAD_ADDR5:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 1 +; CHECK-NEXT: [[VALUE0_RELOAD6:%.*]] = load i32, ptr [[VALUE0_RELOAD_ADDR5]], align 4 ; CHECK-NEXT: [[SUM1:%.*]] = call i32 @add(i32 [[SUM0_RELOAD]], i32 [[VALUE0_RELOAD6]]) ; CHECK-NEXT: [[SUM2:%.*]] = call i32 @add(i32 [[SUM1]], i32 [[TMP1]]) -; CHECK-NEXT: [[SUM2_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 4 -; CHECK-NEXT: store i32 [[SUM2]], i32* [[SUM2_SPILL_ADDR]], align 4 -; CHECK-NEXT: ret i8* bitcast (i8* (i8*, i32)* @f.resume.2 to i8*) +; CHECK-NEXT: [[SUM2_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 4 +; CHECK-NEXT: store i32 [[SUM2]], ptr [[SUM2_SPILL_ADDR]], align 4 +; CHECK-NEXT: ret ptr @f.resume.2 ; ; ; CHECK-LABEL: @f.resume.2( ; CHECK-NEXT: entryresume.2: -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP0:%.*]] to %f.Frame** -; CHECK-NEXT: [[FRAMEPTR:%.*]] = load %f.Frame*, %f.Frame** [[TMP2]], align 8 -; CHECK-NEXT: [[SUM2_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], %f.Frame* [[FRAMEPTR]], i32 0, i32 4 -; CHECK-NEXT: [[SUM2_RELOAD:%.*]] = load i32, i32* [[SUM2_RELOAD_ADDR]], align 4 -; CHECK-NEXT: [[VALUE1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 3 -; CHECK-NEXT: [[VALUE1_RELOAD:%.*]] = load i32, i32* [[VALUE1_RELOAD_ADDR]], align 4 -; CHECK-NEXT: [[VALUE0_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 1 -; CHECK-NEXT: [[VALUE0_RELOAD:%.*]] = load i32, i32* [[VALUE0_RELOAD_ADDR]], align 4 +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: [[SUM2_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 4 +; CHECK-NEXT: [[SUM2_RELOAD:%.*]] = load i32, ptr [[SUM2_RELOAD_ADDR]], align 4 +; CHECK-NEXT: [[VALUE1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 3 +; CHECK-NEXT: [[VALUE1_RELOAD:%.*]] = load i32, ptr [[VALUE1_RELOAD_ADDR]], align 4 +; CHECK-NEXT: [[VALUE0_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 1 +; CHECK-NEXT: [[VALUE0_RELOAD:%.*]] = load i32, ptr [[VALUE0_RELOAD_ADDR]], align 4 ; CHECK-NEXT: [[SUM3:%.*]] = call i32 @add(i32 [[SUM2_RELOAD]], i32 [[VALUE0_RELOAD]]) ; CHECK-NEXT: [[SUM4:%.*]] = call i32 @add(i32 [[SUM3]], i32 [[VALUE1_RELOAD]]) ; CHECK-NEXT: [[SUM5:%.*]] = call i32 @add(i32 [[SUM4]], i32 [[TMP1:%.*]]) ; CHECK-NEXT: call void @print(i32 [[SUM5]]) -; CHECK-NEXT: [[TMP3:%.*]] = bitcast %f.Frame* [[FRAMEPTR]] to i8* -; CHECK-NEXT: call void @deallocate(i8* [[TMP3]]) -; CHECK-NEXT: ret i8* null +; CHECK-NEXT: call void @deallocate(ptr [[TMP2]]) +; CHECK-NEXT: ret ptr null ; diff --git a/llvm/test/Transforms/Coroutines/coro-retcon.ll b/llvm/test/Transforms/Coroutines/coro-retcon.ll index 5f7c475..b42f1c5 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon.ll @@ -1,28 +1,25 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; First example from Doc/Coroutines.rst (two block loop) converted to retcon -; RUN: opt -opaque-pointers=0 < %s -passes='default' -S | FileCheck %s -; RUN: opt -opaque-pointers=0 < %s -passes='module(coro-early),cgscc(coro-split),module(coro-cleanup)' -S | FileCheck --check-prefix=CORO %s +; RUN: opt < %s -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split),module(coro-cleanup)' -S | FileCheck --check-prefix=CORO %s -define i8* @f(i8* %buffer, i32 %n) { +define ptr @f(ptr %buffer, i32 %n) { ; CHECK-LABEL: @f( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = bitcast i8* [[BUFFER:%.*]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_VAL_SPILL_ADDR]], align 4 +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4 ; CHECK-NEXT: tail call void @print(i32 [[N]]) -; CHECK-NEXT: ret i8* bitcast (i8* (i8*, i1)* @f.resume.0 to i8*) +; CHECK-NEXT: ret ptr @f.resume.0 ; ; CORO-LABEL: @f( ; CORO-NEXT: entry: -; CORO-NEXT: [[FRAMEPTR:%.*]] = bitcast i8* [[BUFFER:%.*]] to %f.Frame* -; CORO-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], %f.Frame* [[FRAMEPTR]], i32 0, i32 0 -; CORO-NEXT: store i32 [[N:%.*]], i32* [[N_VAL_SPILL_ADDR]], align 4 +; CORO-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[BUFFER:%.*]], i32 0, i32 0 +; CORO-NEXT: store i32 [[N:%.*]], ptr [[N_VAL_SPILL_ADDR]], align 4 ; CORO-NEXT: call void @print(i32 [[N]]) -; CORO-NEXT: [[TMP0:%.*]] = bitcast i8* (i8*, i1)* @f.resume.0 to i8* -; CORO-NEXT: ret i8* [[TMP0]] +; CORO-NEXT: ret ptr @f.resume.0 ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast (i8* (i8*, i1)* @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) + %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: @@ -36,7 +33,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } @@ -53,128 +50,110 @@ define i32 @main() { ; CORO-LABEL: @main( ; CORO-NEXT: entry: ; CORO-NEXT: [[TMP0:%.*]] = alloca [8 x i8], align 4 -; CORO-NEXT: [[BUFFER:%.*]] = bitcast [8 x i8]* [[TMP0]] to i8* -; CORO-NEXT: [[CONT0:%.*]] = call i8* @f(i8* [[BUFFER]], i32 4) -; CORO-NEXT: [[CONT0_CAST:%.*]] = bitcast i8* [[CONT0]] to i8* (i8*, i1)* -; CORO-NEXT: [[CONT1:%.*]] = call i8* [[CONT0_CAST]](i8* [[BUFFER]], i1 zeroext false) -; CORO-NEXT: [[CONT1_CAST:%.*]] = bitcast i8* [[CONT1]] to i8* (i8*, i1)* -; CORO-NEXT: [[CONT2:%.*]] = call i8* [[CONT1_CAST]](i8* [[BUFFER]], i1 zeroext false) -; CORO-NEXT: [[CONT2_CAST:%.*]] = bitcast i8* [[CONT2]] to i8* (i8*, i1)* -; CORO-NEXT: [[TMP1:%.*]] = call i8* [[CONT2_CAST]](i8* [[BUFFER]], i1 zeroext true) +; CORO-NEXT: [[CONT0:%.*]] = call ptr @f(ptr [[TMP0]], i32 4) +; CORO-NEXT: [[CONT1:%.*]] = call ptr [[CONT0]](ptr [[TMP0]], i1 zeroext false) +; CORO-NEXT: [[CONT2:%.*]] = call ptr [[CONT1]](ptr [[TMP0]], i1 zeroext false) +; CORO-NEXT: [[TMP1:%.*]] = call ptr [[CONT2]](ptr [[TMP0]], i1 zeroext true) ; CORO-NEXT: ret i32 0 ; entry: %0 = alloca [8 x i8], align 4 - %buffer = bitcast [8 x i8]* %0 to i8* - %prepare = call i8* @llvm.coro.prepare.retcon(i8* bitcast (i8* (i8*, i32)* @f to i8*)) - %f = bitcast i8* %prepare to i8* (i8*, i32)* - %cont0 = call i8* %f(i8* %buffer, i32 4) - %cont0.cast = bitcast i8* %cont0 to i8* (i8*, i1)* - %cont1 = call i8* %cont0.cast(i8* %buffer, i1 zeroext false) - %cont1.cast = bitcast i8* %cont1 to i8* (i8*, i1)* - %cont2 = call i8* %cont1.cast(i8* %buffer, i1 zeroext false) - %cont2.cast = bitcast i8* %cont2 to i8* (i8*, i1)* - call i8* %cont2.cast(i8* %buffer, i1 zeroext true) + %prepare = call ptr @llvm.coro.prepare.retcon(ptr @f) + %cont0 = call ptr %prepare(ptr %0, i32 4) + %cont1 = call ptr %cont0(ptr %0, i1 zeroext false) + %cont2 = call ptr %cont1(ptr %0, i1 zeroext false) + call ptr %cont2(ptr %0, i1 zeroext true) ret i32 0 } ; Unfortunately, we don't seem to fully optimize this right now due ; to some sort of phase-ordering thing. -define hidden { i8*, i8* } @g(i8* %buffer, i16* %ptr) { +define hidden { ptr, ptr } @g(ptr %buffer, ptr %ptr) { ; CHECK-LABEL: @g( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @allocate(i32 8) -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[BUFFER:%.*]] to i8** -; CHECK-NEXT: store i8* [[TMP0]], i8** [[TMP1]], align 8 -; CHECK-NEXT: [[PTR_SPILL_ADDR:%.*]] = bitcast i8* [[TMP0]] to i16** -; CHECK-NEXT: store i16* [[PTR:%.*]], i16** [[PTR_SPILL_ADDR]], align 8 -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i16* [[PTR]] to i8* -; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i8*, i8* } { i8* bitcast ({ i8*, i8* } (i8*, i1)* @g.resume.0 to i8*), i8* undef }, i8* [[TMP2]], 1 -; CHECK-NEXT: ret { i8*, i8* } [[TMP3]] +; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @allocate(i32 8) +; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8 +; CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[TMP0]], align 8 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, ptr } { ptr @g.resume.0, ptr undef }, ptr [[PTR]], 1 +; CHECK-NEXT: ret { ptr, ptr } [[TMP1]] ; ; CORO-LABEL: @g( ; CORO-NEXT: entry: -; CORO-NEXT: [[TMP0:%.*]] = call i8* @allocate(i32 8) -; CORO-NEXT: [[TMP1:%.*]] = bitcast i8* [[BUFFER:%.*]] to i8** -; CORO-NEXT: store i8* [[TMP0]], i8** [[TMP1]], align 8 -; CORO-NEXT: [[FRAMEPTR:%.*]] = bitcast i8* [[TMP0]] to %g.Frame* -; CORO-NEXT: [[PTR_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], %g.Frame* [[FRAMEPTR]], i32 0, i32 0 -; CORO-NEXT: store i16* [[PTR:%.*]], i16** [[PTR_SPILL_ADDR]], align 8 -; CORO-NEXT: [[PTR_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], %g.Frame* [[FRAMEPTR]], i32 0, i32 0 -; CORO-NEXT: [[PTR_RELOAD:%.*]] = load i16*, i16** [[PTR_RELOAD_ADDR]], align 8 -; CORO-NEXT: [[PTR2:%.*]] = bitcast i16* [[PTR_RELOAD]] to i8* -; CORO-NEXT: [[TMP2:%.*]] = bitcast { i8*, i8* } (i8*, i1)* @g.resume.0 to i8* -; CORO-NEXT: [[TMP3:%.*]] = insertvalue { i8*, i8* } undef, i8* [[TMP2]], 0 -; CORO-NEXT: [[TMP4:%.*]] = insertvalue { i8*, i8* } [[TMP3]], i8* [[PTR2]], 1 -; CORO-NEXT: ret { i8*, i8* } [[TMP4]] +; CORO-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 8) +; CORO-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8 +; CORO-NEXT: [[PTR_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP0]], i32 0, i32 0 +; CORO-NEXT: store ptr [[PTR:%.*]], ptr [[PTR_SPILL_ADDR]], align 8 +; CORO-NEXT: [[PTR_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[TMP0]], i32 0, i32 0 +; CORO-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[PTR_RELOAD_ADDR]], align 8 +; CORO-NEXT: [[TMP1:%.*]] = insertvalue { ptr, ptr } undef, ptr @g.resume.0, 0 +; CORO-NEXT: [[TMP2:%.*]] = insertvalue { ptr, ptr } [[TMP1]], ptr [[PTR_RELOAD]], 1 +; CORO-NEXT: ret { ptr, ptr } [[TMP2]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast ({ i8*, i8* } (i8*, i1)* @g_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) + %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @g_prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: - %ptr2 = bitcast i16* %ptr to i8* - %unwind0 = call i1 (...) @llvm.coro.suspend.retcon.i1(i8* %ptr2) + %unwind0 = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %ptr) br i1 %unwind0, label %cleanup, label %resume resume: br label %loop cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -define i8* @nosuspend(i8* %buffer, i32 %n) { +define ptr @nosuspend(ptr %buffer, i32 %n) { ; CHECK-LABEL: @nosuspend( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[A]], align 4 -; CHECK-NEXT: call void @use_var_ptr(i32* nonnull [[A]]) -; CHECK-NEXT: [[AL:%.*]] = load i32, i32* [[A]], align 4 +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[A]], align 4 +; CHECK-NEXT: call void @use_var_ptr(ptr nonnull [[A]]) +; CHECK-NEXT: [[AL:%.*]] = load i32, ptr [[A]], align 4 ; CHECK-NEXT: call void @use_var(i32 [[AL]]) -; CHECK-NEXT: ret i8* null +; CHECK-NEXT: ret ptr null ; ; CORO-LABEL: @nosuspend( ; CORO-NEXT: entry: -; CORO-NEXT: [[FRAMEPTR:%.*]] = bitcast i8* undef to %nosuspend.Frame* ; CORO-NEXT: [[A:%.*]] = alloca i32, align 4 -; CORO-NEXT: store i32 [[N:%.*]], i32* [[A]], align 4 -; CORO-NEXT: call void @use_var_ptr(i32* [[A]]) -; CORO-NEXT: [[AL:%.*]] = load i32, i32* [[A]], align 4 +; CORO-NEXT: store i32 [[N:%.*]], ptr [[A]], align 4 +; CORO-NEXT: call void @use_var_ptr(ptr [[A]]) +; CORO-NEXT: [[AL:%.*]] = load i32, ptr [[A]], align 4 ; CORO-NEXT: call void @use_var(i32 [[AL]]) -; CORO-NEXT: ret i8* null +; CORO-NEXT: ret ptr null ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast (i8* (i8*, i1)* @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) + %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) %a = alloca i32 - store i32 %n, i32* %a + store i32 %n, ptr %a br label %cleanup cleanup: - call void @use_var_ptr(i32* %a) - %al = load i32, i32* %a + call void @use_var_ptr(ptr %a) + %al = load i32, ptr %a call void @use_var(i32 %al) - call i1 @llvm.coro.end(i8* %hdl, i1 0) - ret i8* %hdl + call i1 @llvm.coro.end(ptr %hdl, i1 0) + ret ptr %hdl } -declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*) -declare i8* @llvm.coro.begin(token, i8*) +declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(i8*, i1) -declare i8* @llvm.coro.prepare.retcon(i8*) +declare i1 @llvm.coro.end(ptr, i1) +declare ptr @llvm.coro.prepare.retcon(ptr) declare void @use_var(i32) -declare void @use_var_ptr(i32*) +declare void @use_var_ptr(ptr) -declare i8* @prototype(i8*, i1 zeroext) -declare {i8*,i8*} @g_prototype(i8*, i1 zeroext) +declare ptr @prototype(ptr, i1 zeroext) +declare {ptr,ptr} @g_prototype(ptr, i1 zeroext) -declare noalias i8* @allocate(i32 %size) -declare void @deallocate(i8* %ptr) +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll b/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll index eb81f30..a464c8a 100644 --- a/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll +++ b/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll @@ -1,36 +1,34 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Verifies that we insert spills of PHI instruction _after) all PHI Nodes -; RUN: opt -opaque-pointers=0 < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg' -S | FileCheck %s +; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg' -S | FileCheck %s ; 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 } +; CHECK: %f.Frame = type { ptr, ptr, i32, i32, i1 } -define i8* @f(i1 %n) presplitcoroutine { +define ptr @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*)) -; CHECK-NEXT: [[ALLOC:%.*]] = call i8* @malloc(i32 32) -; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull i8* @llvm.coro.begin(token [[ID]], i8* [[ALLOC]]) -; CHECK-NEXT: [[FRAMEPTR:%.*]] = bitcast i8* [[HDL]] to %f.Frame* -; CHECK-NEXT: [[RESUME_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], %f.Frame* [[FRAMEPTR]], i32 0, i32 0 -; CHECK-NEXT: store void (%f.Frame*)* @f.resume, void (%f.Frame*)** [[RESUME_ADDR]], align 8 -; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 1 -; CHECK-NEXT: store void (%f.Frame*)* @f.destroy, void (%f.Frame*)** [[DESTROY_ADDR]], align 8 +; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @f.resumers) +; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 32) +; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]]) +; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8 +; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1 +; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[N:%.*]], i32 0, i32 2 ; CHECK-NEXT: [[SPEC_SELECT5:%.*]] = select i1 [[N]], i32 1, i32 3 -; CHECK-NEXT: [[PHI2_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 3 -; CHECK-NEXT: store i32 [[SPEC_SELECT5]], i32* [[PHI2_SPILL_ADDR]], align 4 -; CHECK-NEXT: [[PHI1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 2 -; CHECK-NEXT: store i32 [[SPEC_SELECT]], i32* [[PHI1_SPILL_ADDR]], align 4 -; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR]], i32 0, i32 4 -; CHECK-NEXT: store i1 false, i1* [[INDEX_ADDR4]], align 1 -; CHECK-NEXT: ret i8* [[HDL]] +; CHECK-NEXT: [[PHI2_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3 +; CHECK-NEXT: store i32 [[SPEC_SELECT5]], ptr [[PHI2_SPILL_ADDR]], align 4 +; CHECK-NEXT: [[PHI1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2 +; CHECK-NEXT: store i32 [[SPEC_SELECT]], ptr [[PHI1_SPILL_ADDR]], align 4 +; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4 +; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1 +; CHECK-NEXT: ret ptr [[HDL]] ; entry: - %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) %size = call i32 @llvm.coro.size.i32() - %alloc = call i8* @malloc(i32 %size) - %hdl = call i8* @llvm.coro.begin(token %id, i8* %alloc) + %alloc = call ptr @malloc(i32 %size) + %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc) br i1 %n, label %begin, label %alt alt: br label %begin @@ -48,25 +46,25 @@ resume: br label %cleanup cleanup: - %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) - call void @free(i8* %mem) + %mem = call ptr @llvm.coro.free(token %id, ptr %hdl) + call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(i8* %hdl, i1 0) - ret i8* %hdl + call i1 @llvm.coro.end(ptr %hdl, i1 0) + ret ptr %hdl } -declare i8* @llvm.coro.free(token, i8*) +declare ptr @llvm.coro.free(token, ptr) declare i32 @llvm.coro.size.i32() declare i8 @llvm.coro.suspend(token, i1) -declare void @llvm.coro.resume(i8*) -declare void @llvm.coro.destroy(i8*) +declare void @llvm.coro.resume(ptr) +declare void @llvm.coro.destroy(ptr) -declare token @llvm.coro.id(i32, i8*, i8*, i8*) +declare token @llvm.coro.id(i32, ptr, ptr, ptr) declare i1 @llvm.coro.alloc(token) -declare i8* @llvm.coro.begin(token, i8*) -declare i1 @llvm.coro.end(i8*, i1) +declare ptr @llvm.coro.begin(token, ptr) +declare i1 @llvm.coro.end(ptr, i1) -declare noalias i8* @malloc(i32) +declare noalias ptr @malloc(i32) declare i32 @print(i32) -declare void @free(i8*) +declare void @free(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-split-recursive.ll b/llvm/test/Transforms/Coroutines/coro-split-recursive.ll index 4d15598..3dff46e 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-recursive.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-recursive.ll @@ -1,11 +1,11 @@ -; RUN: opt -passes='module(coro-early),cgscc(coro-split)' -opaque-pointers=0 -S < %s | FileCheck %s +; RUN: opt -passes='module(coro-early),cgscc(coro-split)' -S < %s | FileCheck %s ; RUN: opt -passes='module(coro-early),cgscc(coro-split)' -opaque-pointers=1 -S < %s | FileCheck %s -declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) +declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) -declare i8* @llvm.coro.begin(token, i8* writeonly) +declare ptr @llvm.coro.begin(token, ptr writeonly) -declare token @llvm.coro.save(i8*) +declare token @llvm.coro.save(ptr) declare i8 @llvm.coro.suspend(token, i1) @@ -19,14 +19,13 @@ declare i1 @get.i1() define void @foo() presplitcoroutine { entry: %__promise = alloca i32, align 8 - %0 = bitcast i32* %__promise to i8* - %1 = call token @llvm.coro.id(i32 16, i8* %0, i8* null, i8* null) - %2 = call i8* @llvm.coro.begin(token %1, i8* null) + %0 = call token @llvm.coro.id(i32 16, ptr %__promise, ptr null, ptr null) + %1 = call ptr @llvm.coro.begin(token %0, ptr null) %c = call i1 @get.i1() br i1 %c, label %if.then154, label %init.suspend init.suspend: ; preds = %entry - %save = call token @llvm.coro.save(i8* null) + %save = call token @llvm.coro.save(ptr null) %i3 = call i8 @llvm.coro.suspend(token %save, i1 false) %cond = icmp eq i8 %i3, 0 br i1 %cond, label %if.then154, label %invoke.cont163 diff --git a/llvm/test/Transforms/Coroutines/coro-swifterror.ll b/llvm/test/Transforms/Coroutines/coro-swifterror.ll index c111f1f..1fba4e4 100644 --- a/llvm/test/Transforms/Coroutines/coro-swifterror.ll +++ b/llvm/test/Transforms/Coroutines/coro-swifterror.ll @@ -1,33 +1,32 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -opaque-pointers=0 < %s -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s target datalayout = "E-p:32:32" -define i8* @f(i8* %buffer, i32 %n, i8** swifterror %errorslot) { +define ptr @f(ptr %buffer, i32 %n, ptr swifterror %errorslot) { ; CHECK-LABEL: @f( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = bitcast i8* [[BUFFER:%.*]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_VAL_SPILL_ADDR]], align 4 +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4 ; CHECK-NEXT: tail call void @print(i32 [[N]]) -; CHECK-NEXT: store i8* null, i8** [[ERRORSLOT:%.*]], align 4 -; CHECK-NEXT: tail call void @maybeThrow(i8** nonnull swifterror [[ERRORSLOT]]) -; CHECK-NEXT: [[TMP0:%.*]] = load i8*, i8** [[ERRORSLOT]], align 4 -; CHECK-NEXT: tail call void @logError(i8* [[TMP0]]) -; CHECK-NEXT: store i8* [[TMP0]], i8** [[ERRORSLOT]], align 4 -; CHECK-NEXT: ret i8* bitcast (i8* (i8*, i1, i8**)* @f.resume.0 to i8*) +; CHECK-NEXT: store ptr null, ptr [[ERRORSLOT:%.*]], align 4 +; CHECK-NEXT: tail call void @maybeThrow(ptr nonnull swifterror [[ERRORSLOT]]) +; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ERRORSLOT]], align 4 +; CHECK-NEXT: tail call void @logError(ptr [[TMP0]]) +; CHECK-NEXT: store ptr [[TMP0]], ptr [[ERRORSLOT]], align 4 +; CHECK-NEXT: ret ptr @f.resume.0 ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast (i8* (i8*, i1, i8**)* @f_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) + %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @f_prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ] call void @print(i32 %n.val) - call void @maybeThrow(i8** swifterror %errorslot) - %errorload1 = load i8*, i8** %errorslot - call void @logError(i8* %errorload1) - %suspend_result = call { i1, i8** } (...) @llvm.coro.suspend.retcon.i1p0p0i8() - %unwind0 = extractvalue { i1, i8** } %suspend_result, 0 + call void @maybeThrow(ptr swifterror %errorslot) + %errorload1 = load ptr, ptr %errorslot + call void @logError(ptr %errorload1) + %suspend_result = call { i1, ptr } (...) @llvm.coro.suspend.retcon.i1p0p0i8() + %unwind0 = extractvalue { i1, ptr } %suspend_result, 0 br i1 %unwind0, label %cleanup, label %resume resume: @@ -35,42 +34,40 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } ; TODO: figure out a way to eliminate this -define i8* @g(i8* %buffer, i32 %n) { +define ptr @g(ptr %buffer, i32 %n) { ; CHECK-LABEL: @g( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[TMP0:%.*]] = alloca swifterror i8*, align 4 -; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = bitcast i8* [[BUFFER:%.*]] to i32* -; CHECK-NEXT: store i32 [[N:%.*]], i32* [[N_VAL_SPILL_ADDR]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = alloca swifterror ptr, align 4 +; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4 ; CHECK-NEXT: tail call void @print(i32 [[N]]) -; CHECK-NEXT: store i8* null, i8** [[TMP0]], align 4 -; CHECK-NEXT: call void @maybeThrow(i8** nonnull swifterror [[TMP0]]) -; CHECK-NEXT: [[TMP1:%.*]] = load i8*, i8** [[TMP0]], align 4 -; CHECK-NEXT: [[DOTSPILL_ADDR:%.*]] = getelementptr inbounds i8, i8* [[BUFFER]], i32 4 -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[DOTSPILL_ADDR]] to i8** -; CHECK-NEXT: store i8* [[TMP1]], i8** [[TMP2]], align 4 -; CHECK-NEXT: call void @logError(i8* [[TMP1]]) -; CHECK-NEXT: ret i8* bitcast (i8* (i8*, i1)* @g.resume.0 to i8*) +; CHECK-NEXT: store ptr null, ptr [[TMP0]], align 4 +; CHECK-NEXT: call void @maybeThrow(ptr nonnull swifterror [[TMP0]]) +; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 4 +; CHECK-NEXT: [[DOTSPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[BUFFER]], i32 0, i32 1 +; CHECK-NEXT: store ptr [[TMP1]], ptr [[DOTSPILL_ADDR]], align 4 +; CHECK-NEXT: call void @logError(ptr [[TMP1]]) +; CHECK-NEXT: ret ptr @g.resume.0 ; entry: - %errorslot = alloca swifterror i8*, align 4 - store i8* null, i8** %errorslot - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast (i8* (i8*, i1)* @g_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) + %errorslot = alloca swifterror ptr, align 4 + store ptr null, ptr %errorslot + %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @g_prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ] call void @print(i32 %n.val) - call void @maybeThrow(i8** swifterror %errorslot) - %errorload1 = load i8*, i8** %errorslot - call void @logError(i8* %errorload1) + call void @maybeThrow(ptr swifterror %errorslot) + %errorload1 = load ptr, ptr %errorslot + call void @logError(ptr %errorload1) %unwind0 = call i1 (...) @llvm.coro.suspend.retcon.i1() br i1 %unwind0, label %cleanup, label %resume @@ -79,25 +76,25 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*) -declare i8* @llvm.coro.begin(token, i8*) -declare { i1, i8** } @llvm.coro.suspend.retcon.i1p0p0i8(...) +declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +declare ptr @llvm.coro.begin(token, ptr) +declare { i1, ptr } @llvm.coro.suspend.retcon.i1p0p0i8(...) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(i8*, i1) -declare i8* @llvm.coro.prepare.retcon(i8*) +declare i1 @llvm.coro.end(ptr, i1) +declare ptr @llvm.coro.prepare.retcon(ptr) -declare i8* @f_prototype(i8*, i1 zeroext, i8** swifterror) -declare i8* @g_prototype(i8*, i1 zeroext) +declare ptr @f_prototype(ptr, i1 zeroext, ptr swifterror) +declare ptr @g_prototype(ptr, i1 zeroext) -declare noalias i8* @allocate(i32 %size) -declare void @deallocate(i8* %ptr) +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) declare void @print(i32) -declare void @maybeThrow(i8** swifterror) -declare void @logError(i8*) +declare void @maybeThrow(ptr swifterror) +declare void @logError(ptr) -- 2.7.4