Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / Attributor / value-simplify-dominance.ll
blob7d95f35b24fd03ddea123edf0d556078cb14f99f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 declare void @unknown() nocallback
7 define i32 @many_writes_nosycn(i1 %c0, i1 %c1, i1 %c2) nosync {
8 ; CHECK: Function Attrs: norecurse nosync
9 ; CHECK-LABEL: define {{[^@]+}}@many_writes_nosycn
10 ; CHECK-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1:[0-9]+]] {
11 ; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4
12 ; CHECK-NEXT:    call void @unknown()
13 ; CHECK-NEXT:    br i1 [[C0]], label [[T0:%.*]], label [[F0:%.*]]
14 ; CHECK:       t0:
15 ; CHECK-NEXT:    call void @unknown()
16 ; CHECK-NEXT:    br i1 [[C1]], label [[T1:%.*]], label [[M1:%.*]]
17 ; CHECK:       f0:
18 ; CHECK-NEXT:    call void @unknown()
19 ; CHECK-NEXT:    br i1 [[C2]], label [[F1:%.*]], label [[M1]]
20 ; CHECK:       t1:
21 ; CHECK-NEXT:    call void @unknown()
22 ; CHECK-NEXT:    store i32 7, ptr [[P]], align 4
23 ; CHECK-NEXT:    br label [[M2:%.*]]
24 ; CHECK:       f1:
25 ; CHECK-NEXT:    call void @unknown()
26 ; CHECK-NEXT:    store i32 9, ptr [[P]], align 4
27 ; CHECK-NEXT:    br label [[M2]]
28 ; CHECK:       m1:
29 ; CHECK-NEXT:    call void @unknown()
30 ; CHECK-NEXT:    store i32 11, ptr [[P]], align 4
31 ; CHECK-NEXT:    br label [[M2]]
32 ; CHECK:       m2:
33 ; CHECK-NEXT:    call void @unknown()
34 ; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[P]], align 4
35 ; CHECK-NEXT:    ret i32 [[L]]
37   %p = alloca i32
38   store i32 0, ptr %p
39   call void @unknown()
40   store i32 1, ptr %p
41   br i1 %c0, label %t0, label %f0
42 t0:
43   store i32 2, ptr %p
44   call void @unknown()
45   store i32 3, ptr %p
46   br i1 %c1, label %t1, label %m1
47 f0:
48   store i32 4, ptr %p
49   call void @unknown()
50   store i32 5, ptr %p
51   br i1 %c2, label %f1, label %m1
52 t1:
53   store i32 6, ptr %p
54   call void @unknown()
55   store i32 7, ptr %p
56   br label %m2
57 f1:
58   store i32 8, ptr %p
59   call void @unknown()
60   store i32 9, ptr %p
61   br label %m2
62 m1:
63   store i32 10, ptr %p
64   call void @unknown()
65   store i32 11, ptr %p
66   br label %m2
67 m2:
68   call void @unknown()
69   %l = load i32, ptr %p
70   ret i32 %l
73 define i32 @many_writes(i1 %c0, i1 %c1, i1 %c2) {
74 ; CHECK: Function Attrs: norecurse
75 ; CHECK-LABEL: define {{[^@]+}}@many_writes
76 ; CHECK-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR2:[0-9]+]] {
77 ; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4
78 ; CHECK-NEXT:    call void @unknown()
79 ; CHECK-NEXT:    br i1 [[C0]], label [[T0:%.*]], label [[F0:%.*]]
80 ; CHECK:       t0:
81 ; CHECK-NEXT:    call void @unknown()
82 ; CHECK-NEXT:    br i1 [[C1]], label [[T1:%.*]], label [[M1:%.*]]
83 ; CHECK:       f0:
84 ; CHECK-NEXT:    call void @unknown()
85 ; CHECK-NEXT:    br i1 [[C2]], label [[F1:%.*]], label [[M1]]
86 ; CHECK:       t1:
87 ; CHECK-NEXT:    call void @unknown()
88 ; CHECK-NEXT:    store i32 7, ptr [[P]], align 4
89 ; CHECK-NEXT:    br label [[M2:%.*]]
90 ; CHECK:       f1:
91 ; CHECK-NEXT:    call void @unknown()
92 ; CHECK-NEXT:    store i32 9, ptr [[P]], align 4
93 ; CHECK-NEXT:    br label [[M2]]
94 ; CHECK:       m1:
95 ; CHECK-NEXT:    call void @unknown()
96 ; CHECK-NEXT:    store i32 11, ptr [[P]], align 4
97 ; CHECK-NEXT:    br label [[M2]]
98 ; CHECK:       m2:
99 ; CHECK-NEXT:    call void @unknown()
100 ; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[P]], align 4
101 ; CHECK-NEXT:    ret i32 [[L]]
103   %p = alloca i32
104   store i32 0, ptr %p
105   call void @unknown()
106   store i32 1, ptr %p
107   br i1 %c0, label %t0, label %f0
109   store i32 2, ptr %p
110   call void @unknown()
111   store i32 3, ptr %p
112   br i1 %c1, label %t1, label %m1
114   store i32 4, ptr %p
115   call void @unknown()
116   store i32 5, ptr %p
117   br i1 %c2, label %f1, label %m1
119   store i32 6, ptr %p
120   call void @unknown()
121   store i32 7, ptr %p
122   br label %m2
124   store i32 8, ptr %p
125   call void @unknown()
126   store i32 9, ptr %p
127   br label %m2
129   store i32 10, ptr %p
130   call void @unknown()
131   store i32 11, ptr %p
132   br label %m2
134   call void @unknown()
135   %l = load i32, ptr %p
136   ret i32 %l
139 declare void @usei32(i32) nocallback
140 ; Ensure we use 42, not undef, for %l in the usei32 call and %r in the return.
141 define internal i32 @remote_write_and_read(ptr %p) norecurse {
142 ; TUNIT: Function Attrs: norecurse
143 ; TUNIT-LABEL: define {{[^@]+}}@remote_write_and_read
144 ; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR2]] {
145 ; TUNIT-NEXT:    call void @usei32(i32 noundef 42)
146 ; TUNIT-NEXT:    ret i32 undef
148 ; CGSCC: Function Attrs: norecurse
149 ; CGSCC-LABEL: define {{[^@]+}}@remote_write_and_read
150 ; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR2]] {
151 ; CGSCC-NEXT:    store i32 42, ptr [[P]], align 4
152 ; CGSCC-NEXT:    [[L:%.*]] = load i32, ptr [[P]], align 4
153 ; CGSCC-NEXT:    call void @usei32(i32 [[L]])
154 ; CGSCC-NEXT:    ret i32 [[L]]
156   store i32 42, ptr %p
157   %l = load i32, ptr %p
158   call void @usei32(i32 %l)
159   ret i32 %l
162 define i32 @local_stack_remote_write_and_read() norecurse {
163 ; TUNIT: Function Attrs: norecurse
164 ; TUNIT-LABEL: define {{[^@]+}}@local_stack_remote_write_and_read
165 ; TUNIT-SAME: () #[[ATTR2]] {
166 ; TUNIT-NEXT:    [[A:%.*]] = alloca i32, align 4
167 ; TUNIT-NEXT:    [[R:%.*]] = call i32 @remote_write_and_read(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]])
168 ; TUNIT-NEXT:    ret i32 42
170 ; CGSCC: Function Attrs: norecurse
171 ; CGSCC-LABEL: define {{[^@]+}}@local_stack_remote_write_and_read
172 ; CGSCC-SAME: () #[[ATTR2]] {
173 ; CGSCC-NEXT:    [[A:%.*]] = alloca i32, align 4
174 ; CGSCC-NEXT:    [[R:%.*]] = call i32 @remote_write_and_read(ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
175 ; CGSCC-NEXT:    ret i32 [[R]]
177   %a = alloca i32
178   %r = call i32 @remote_write_and_read(ptr %a)
179   ret i32 %r
182 ; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback }
183 ; TUNIT: attributes #[[ATTR1]] = { norecurse nosync }
184 ; TUNIT: attributes #[[ATTR2]] = { norecurse }
186 ; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback }
187 ; CGSCC: attributes #[[ATTR1]] = { norecurse nosync }
188 ; CGSCC: attributes #[[ATTR2]] = { norecurse }