File: coro-alloca-loop-carried-address.ll

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 1,998,492 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (85 lines) | stat: -rw-r--r-- 3,634 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s

@escape_hatch0 = external global i64
@escape_hatch1 = external global i64

define void @foo() presplitcoroutine {
; CHECK-LABEL: @foo(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @foo.resumers)
; CHECK-NEXT:    [[ALLOC:%.*]] = call ptr @malloc(i64 40)
; CHECK-NEXT:    [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT:    store ptr @foo.resume, ptr [[VFRAME]], align 8
; CHECK-NEXT:    [[DESTROY_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
; CHECK-NEXT:    store ptr @foo.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT:    [[STACKVAR0_RELOAD_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME]], ptr [[VFRAME]], i32 0, i32 2
; CHECK-NEXT:    [[STACKVAR1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME]], ptr [[VFRAME]], i32 0, i32 3
; CHECK-NEXT:    [[STACKVAR0_INT:%.*]] = ptrtoint ptr [[STACKVAR0_RELOAD_ADDR]] to i64
; CHECK-NEXT:    store i64 [[STACKVAR0_INT]], ptr @escape_hatch0, align 4
; CHECK-NEXT:    [[STACKVAR1_INT:%.*]] = ptrtoint ptr [[STACKVAR1_RELOAD_ADDR]] to i64
; CHECK-NEXT:    store i64 [[STACKVAR1_INT]], ptr @escape_hatch1, align 4
; CHECK-NEXT:    br label [[LOOP:%.*]]
; CHECK:       loop:
; CHECK-NEXT:    store i64 1234, ptr [[STACKVAR0_RELOAD_ADDR]], align 4
; CHECK-NEXT:    call void @bar()
; CHECK-NEXT:    [[INDEX_ADDR1:%.*]] = getelementptr inbounds [[FOO_FRAME]], ptr [[VFRAME]], i32 0, i32 4
; CHECK-NEXT:    store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[AFTERCOROEND:%.*]]
; CHECK:       AfterCoroEnd:
; CHECK-NEXT:    ret void
;
entry:
  %stackvar0 = alloca i64
  %stackvar1 = alloca i64

  ; address of %stackvar escapes and may be relied upon even after
  ; suspending/resuming the coroutine regardless of the lifetime markers.
  %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
  %size = call i64 @llvm.coro.size.i64()
  %alloc = call ptr @malloc(i64 %size)
  %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc)

  ; %stackvar0 must be rewritten to reference the coroutine Frame!
  %stackvar0_int = ptrtoint ptr %stackvar0 to i64
  store i64 %stackvar0_int, ptr @escape_hatch0
  ; %stackvar1 must be rewritten to reference the coroutine Frame!
  %stackvar1_int = ptrtoint ptr %stackvar1 to i64
  store i64 %stackvar1_int, ptr @escape_hatch1

  br label %loop

loop:
  call void @llvm.lifetime.start(i64 8, ptr %stackvar0)

  store i64 1234, ptr %stackvar0

  ; Call could potentially change value in memory referenced by %stackvar0 /
  ; %stackvar1 and rely on it staying the same across suspension.
  call void @bar()

  call void @llvm.lifetime.end(i64 8, ptr %stackvar0)

  %save = call token @llvm.coro.save(ptr null)
  %suspend = call i8 @llvm.coro.suspend(token %save, i1 false)
  switch i8 %suspend, label %exit [
  i8 0, label %loop
  i8 1, label %exit
  ]

exit:
  call i1 @llvm.coro.end(ptr null, i1 false, token none)
  ret void
}

declare void @bar()
declare ptr @malloc(i64)

declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr)
declare i64 @llvm.coro.size.i64()
declare ptr @llvm.coro.begin(token, ptr writeonly)
declare token @llvm.coro.save(ptr)
declare i8 @llvm.coro.suspend(token, i1)
declare i1 @llvm.coro.end(ptr, i1, token)
declare void @llvm.lifetime.start(i64, ptr nocapture)
declare void @llvm.lifetime.end(i64, ptr nocapture)