1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=BASIC
3 ; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
4 ; RUN: opt -passes='require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=WITH-AC
5 ; RUN: opt -passes='require<domtree>,require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=CROSS-BLOCK
6 ; RUN: opt -passes='assume-builder,require<domtree>,require<assumptions>,assume-simplify,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=FULL-SIMPLIFY
8 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
10 %struct.S = type { i32, i8, ptr }
11 %struct.A = type { ptr, ptr, [4 x [4 x %struct.D]], i64 }
12 %struct.D = type { i64, i64 }
14 declare void @func(ptr, ptr)
15 declare void @func_cold(ptr) #0
16 declare void @func_strbool(ptr) #1
17 declare void @func_many(ptr) #2
18 declare void @func_argattr(ptr align 8, ptr nonnull) #3
19 declare void @func_argattr2(ptr noundef align 8, ptr noundef nonnull) #3
21 declare void @may_throw()
23 define void @test(ptr %P, ptr %P1, ptr %P2, ptr %P3) {
24 ; BASIC-LABEL: define {{[^@]+}}@test
25 ; BASIC-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) {
27 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]), "dereferenceable"(ptr [[P]], i64 16) ]
28 ; BASIC-NEXT: call void @func(ptr nonnull dereferenceable(16) [[P]], ptr null)
29 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 12) ]
30 ; BASIC-NEXT: call void @func(ptr dereferenceable(12) [[P1]], ptr nonnull [[P]])
31 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
32 ; BASIC-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) #[[ATTR6:[0-9]+]]
33 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
34 ; BASIC-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]])
35 ; BASIC-NEXT: call void @func(ptr [[P1]], ptr [[P]])
36 ; BASIC-NEXT: call void @func_strbool(ptr [[P1]])
37 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 32) ]
38 ; BASIC-NEXT: call void @func(ptr dereferenceable(32) [[P]], ptr dereferenceable(8) [[P]])
39 ; BASIC-NEXT: call void @func_many(ptr align 8 [[P1]])
40 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
41 ; BASIC-NEXT: call void @func_many(ptr noundef align 8 [[P1]])
42 ; BASIC-NEXT: call void @func_argattr(ptr [[P2]], ptr [[P3]])
43 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P2]]), "align"(ptr [[P2]], i64 8), "noundef"(ptr [[P3]]), "nonnull"(ptr [[P3]]) ]
44 ; BASIC-NEXT: call void @func_argattr2(ptr [[P2]], ptr [[P3]])
45 ; BASIC-NEXT: call void @func(ptr nonnull [[P1]], ptr nonnull [[P]])
46 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P1]]), "noundef"(ptr [[P]]) ]
47 ; BASIC-NEXT: call void @func(ptr noundef nonnull [[P1]], ptr noundef nonnull [[P]])
48 ; BASIC-NEXT: ret void
50 ; ALL-LABEL: define {{[^@]+}}@test
51 ; ALL-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) {
53 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]), "dereferenceable"(ptr [[P]], i64 16) ]
54 ; ALL-NEXT: call void @func(ptr nonnull dereferenceable(16) [[P]], ptr null)
55 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 12) ]
56 ; ALL-NEXT: call void @func(ptr dereferenceable(12) [[P1]], ptr nonnull [[P]])
57 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "cold"(), "nounwind"(), "willreturn"() ]
58 ; ALL-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) #[[ATTR6:[0-9]+]]
59 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "cold"(), "nounwind"(), "willreturn"() ]
60 ; ALL-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]])
61 ; ALL-NEXT: call void @func(ptr [[P1]], ptr [[P]])
62 ; ALL-NEXT: call void @func_strbool(ptr [[P1]])
63 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 32) ]
64 ; ALL-NEXT: call void @func(ptr dereferenceable(32) [[P]], ptr dereferenceable(8) [[P]])
65 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "norecurse"(), "nounwind"(), "willreturn"() ]
66 ; ALL-NEXT: call void @func_many(ptr align 8 [[P1]])
67 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P1]]), "align"(ptr [[P1]], i64 8), "norecurse"(), "nounwind"(), "willreturn"() ]
68 ; ALL-NEXT: call void @func_many(ptr noundef align 8 [[P1]])
69 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nounwind"() ]
70 ; ALL-NEXT: call void @func_argattr(ptr [[P2]], ptr [[P3]])
71 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P2]]), "align"(ptr [[P2]], i64 8), "noundef"(ptr [[P3]]), "nonnull"(ptr [[P3]]), "nounwind"() ]
72 ; ALL-NEXT: call void @func_argattr2(ptr [[P2]], ptr [[P3]])
73 ; ALL-NEXT: call void @func(ptr nonnull [[P1]], ptr nonnull [[P]])
74 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P1]]), "noundef"(ptr [[P]]) ]
75 ; ALL-NEXT: call void @func(ptr noundef nonnull [[P1]], ptr noundef nonnull [[P]])
78 ; WITH-AC-LABEL: define {{[^@]+}}@test
79 ; WITH-AC-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) {
81 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]), "dereferenceable"(ptr [[P]], i64 16) ]
82 ; WITH-AC-NEXT: call void @func(ptr nonnull dereferenceable(16) [[P]], ptr null)
83 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 12) ]
84 ; WITH-AC-NEXT: call void @func(ptr dereferenceable(12) [[P1]], ptr nonnull [[P]])
85 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
86 ; WITH-AC-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) #[[ATTR6:[0-9]+]]
87 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
88 ; WITH-AC-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]])
89 ; WITH-AC-NEXT: call void @func(ptr [[P1]], ptr [[P]])
90 ; WITH-AC-NEXT: call void @func_strbool(ptr [[P1]])
91 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 32) ]
92 ; WITH-AC-NEXT: call void @func(ptr dereferenceable(32) [[P]], ptr dereferenceable(8) [[P]])
93 ; WITH-AC-NEXT: call void @func_many(ptr align 8 [[P1]])
94 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
95 ; WITH-AC-NEXT: call void @func_many(ptr noundef align 8 [[P1]])
96 ; WITH-AC-NEXT: call void @func_argattr(ptr [[P2]], ptr [[P3]])
97 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P2]]), "align"(ptr [[P2]], i64 8), "noundef"(ptr [[P3]]), "nonnull"(ptr [[P3]]) ]
98 ; WITH-AC-NEXT: call void @func_argattr2(ptr [[P2]], ptr [[P3]])
99 ; WITH-AC-NEXT: call void @func(ptr nonnull [[P1]], ptr nonnull [[P]])
100 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P1]]), "noundef"(ptr [[P]]) ]
101 ; WITH-AC-NEXT: call void @func(ptr noundef nonnull [[P1]], ptr noundef nonnull [[P]])
102 ; WITH-AC-NEXT: ret void
104 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test
105 ; CROSS-BLOCK-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) {
106 ; CROSS-BLOCK-NEXT: bb:
107 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]), "dereferenceable"(ptr [[P]], i64 16) ]
108 ; CROSS-BLOCK-NEXT: call void @func(ptr nonnull dereferenceable(16) [[P]], ptr null)
109 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 12) ]
110 ; CROSS-BLOCK-NEXT: call void @func(ptr dereferenceable(12) [[P1]], ptr nonnull [[P]])
111 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
112 ; CROSS-BLOCK-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) #[[ATTR6:[0-9]+]]
113 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
114 ; CROSS-BLOCK-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]])
115 ; CROSS-BLOCK-NEXT: call void @func(ptr [[P1]], ptr [[P]])
116 ; CROSS-BLOCK-NEXT: call void @func_strbool(ptr [[P1]])
117 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 32) ]
118 ; CROSS-BLOCK-NEXT: call void @func(ptr dereferenceable(32) [[P]], ptr dereferenceable(8) [[P]])
119 ; CROSS-BLOCK-NEXT: call void @func_many(ptr align 8 [[P1]])
120 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
121 ; CROSS-BLOCK-NEXT: call void @func_many(ptr noundef align 8 [[P1]])
122 ; CROSS-BLOCK-NEXT: call void @func_argattr(ptr [[P2]], ptr [[P3]])
123 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P2]]), "align"(ptr [[P2]], i64 8), "noundef"(ptr [[P3]]), "nonnull"(ptr [[P3]]) ]
124 ; CROSS-BLOCK-NEXT: call void @func_argattr2(ptr [[P2]], ptr [[P3]])
125 ; CROSS-BLOCK-NEXT: call void @func(ptr nonnull [[P1]], ptr nonnull [[P]])
126 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P1]]), "noundef"(ptr [[P]]) ]
127 ; CROSS-BLOCK-NEXT: call void @func(ptr noundef nonnull [[P1]], ptr noundef nonnull [[P]])
128 ; CROSS-BLOCK-NEXT: ret void
130 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test
131 ; FULL-SIMPLIFY-SAME: (ptr nonnull dereferenceable(16) [[P:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) {
132 ; FULL-SIMPLIFY-NEXT: bb:
133 ; FULL-SIMPLIFY-NEXT: call void @func(ptr nonnull dereferenceable(16) [[P]], ptr null)
134 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 12) ]
135 ; FULL-SIMPLIFY-NEXT: call void @func(ptr dereferenceable(12) [[P1]], ptr nonnull [[P]])
136 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
137 ; FULL-SIMPLIFY-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) #[[ATTR6:[0-9]+]]
138 ; FULL-SIMPLIFY-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]])
139 ; FULL-SIMPLIFY-NEXT: call void @func(ptr [[P1]], ptr [[P]])
140 ; FULL-SIMPLIFY-NEXT: call void @func_strbool(ptr [[P1]])
141 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 32) ]
142 ; FULL-SIMPLIFY-NEXT: call void @func(ptr dereferenceable(32) [[P]], ptr dereferenceable(8) [[P]])
143 ; FULL-SIMPLIFY-NEXT: call void @func_many(ptr align 8 [[P1]])
144 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
145 ; FULL-SIMPLIFY-NEXT: call void @func_many(ptr noundef align 8 [[P1]])
146 ; FULL-SIMPLIFY-NEXT: call void @func_argattr(ptr [[P2]], ptr [[P3]])
147 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P2]]), "align"(ptr [[P2]], i64 8), "noundef"(ptr [[P3]]), "nonnull"(ptr [[P3]]) ]
148 ; FULL-SIMPLIFY-NEXT: call void @func_argattr2(ptr [[P2]], ptr [[P3]])
149 ; FULL-SIMPLIFY-NEXT: call void @func(ptr nonnull [[P1]], ptr nonnull [[P]])
150 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P1]]), "noundef"(ptr [[P]]) ]
151 ; FULL-SIMPLIFY-NEXT: call void @func(ptr noundef nonnull [[P1]], ptr noundef nonnull [[P]])
152 ; FULL-SIMPLIFY-NEXT: ret void
155 call void @func(ptr nonnull dereferenceable(16) %P, ptr null)
156 call void @func(ptr dereferenceable(12) %P1, ptr nonnull %P)
157 call void @func_cold(ptr dereferenceable(12) %P1) #5
158 call void @func_cold(ptr dereferenceable(12) %P1)
159 call void @func(ptr %P1, ptr %P)
160 call void @func_strbool(ptr %P1)
161 call void @func(ptr dereferenceable(32) %P, ptr dereferenceable(8) %P)
162 call void @func_many(ptr align 8 %P1)
163 call void @func_many(ptr noundef align 8 %P1)
164 call void @func_argattr(ptr %P2, ptr %P3)
165 call void @func_argattr2(ptr %P2, ptr %P3)
166 call void @func(ptr nonnull %P1, ptr nonnull %P)
167 call void @func(ptr noundef nonnull %P1, ptr noundef nonnull %P)
171 define i32 @test2(ptr %arg, ptr %arg1, ptr %arg2) {
172 ; BASIC-LABEL: define {{[^@]+}}@test2
173 ; BASIC-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
175 ; BASIC-NEXT: [[I:%.*]] = alloca ptr, align 8
176 ; BASIC-NEXT: [[I3:%.*]] = alloca ptr, align 8
177 ; BASIC-NEXT: [[I4:%.*]] = alloca ptr, align 8
178 ; BASIC-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
179 ; BASIC-NEXT: store ptr [[ARG]], ptr [[I]], align 8
180 ; BASIC-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
181 ; BASIC-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
182 ; BASIC-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
183 ; BASIC-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
184 ; BASIC-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
185 ; BASIC-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
186 ; BASIC-NEXT: store i8 [[I8]], ptr [[I9]], align 1
187 ; BASIC-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 8
188 ; BASIC-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
189 ; BASIC-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
190 ; BASIC-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
191 ; BASIC-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
192 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "nonnull"(ptr [[I17]]), "align"(ptr [[I17]], i64 4) ]
193 ; BASIC-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 4
194 ; BASIC-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
195 ; BASIC-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
196 ; BASIC-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
197 ; BASIC-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
198 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I22]], i64 16), "nonnull"(ptr [[I22]]), "align"(ptr [[I22]], i64 8) ]
199 ; BASIC-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
200 ; BASIC-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
201 ; BASIC-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
202 ; BASIC-NEXT: ret i32 [[I26]]
204 ; ALL-LABEL: define {{[^@]+}}@test2
205 ; ALL-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
207 ; ALL-NEXT: [[I:%.*]] = alloca ptr, align 8
208 ; ALL-NEXT: [[I3:%.*]] = alloca ptr, align 8
209 ; ALL-NEXT: [[I4:%.*]] = alloca ptr, align 8
210 ; ALL-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
211 ; ALL-NEXT: store ptr [[ARG]], ptr [[I]], align 8
212 ; ALL-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
213 ; ALL-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
214 ; ALL-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
215 ; ALL-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
216 ; ALL-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
217 ; ALL-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
218 ; ALL-NEXT: store i8 [[I8]], ptr [[I9]], align 1
219 ; ALL-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 8
220 ; ALL-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
221 ; ALL-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
222 ; ALL-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
223 ; ALL-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
224 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "nonnull"(ptr [[I17]]), "align"(ptr [[I17]], i64 4) ]
225 ; ALL-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 4
226 ; ALL-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
227 ; ALL-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
228 ; ALL-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
229 ; ALL-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
230 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I22]], i64 16), "nonnull"(ptr [[I22]]), "align"(ptr [[I22]], i64 8) ]
231 ; ALL-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
232 ; ALL-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
233 ; ALL-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
234 ; ALL-NEXT: ret i32 [[I26]]
236 ; WITH-AC-LABEL: define {{[^@]+}}@test2
237 ; WITH-AC-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
239 ; WITH-AC-NEXT: [[I:%.*]] = alloca ptr, align 8
240 ; WITH-AC-NEXT: [[I3:%.*]] = alloca ptr, align 8
241 ; WITH-AC-NEXT: [[I4:%.*]] = alloca ptr, align 8
242 ; WITH-AC-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
243 ; WITH-AC-NEXT: store ptr [[ARG]], ptr [[I]], align 8
244 ; WITH-AC-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
245 ; WITH-AC-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
246 ; WITH-AC-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
247 ; WITH-AC-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
248 ; WITH-AC-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
249 ; WITH-AC-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
250 ; WITH-AC-NEXT: store i8 [[I8]], ptr [[I9]], align 1
251 ; WITH-AC-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 8
252 ; WITH-AC-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
253 ; WITH-AC-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
254 ; WITH-AC-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
255 ; WITH-AC-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
256 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "nonnull"(ptr [[I17]]), "align"(ptr [[I17]], i64 4) ]
257 ; WITH-AC-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 4
258 ; WITH-AC-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
259 ; WITH-AC-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
260 ; WITH-AC-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
261 ; WITH-AC-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
262 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I22]], i64 16), "nonnull"(ptr [[I22]]), "align"(ptr [[I22]], i64 8) ]
263 ; WITH-AC-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
264 ; WITH-AC-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
265 ; WITH-AC-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
266 ; WITH-AC-NEXT: ret i32 [[I26]]
268 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test2
269 ; CROSS-BLOCK-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
270 ; CROSS-BLOCK-NEXT: bb:
271 ; CROSS-BLOCK-NEXT: [[I:%.*]] = alloca ptr, align 8
272 ; CROSS-BLOCK-NEXT: [[I3:%.*]] = alloca ptr, align 8
273 ; CROSS-BLOCK-NEXT: [[I4:%.*]] = alloca ptr, align 8
274 ; CROSS-BLOCK-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
275 ; CROSS-BLOCK-NEXT: store ptr [[ARG]], ptr [[I]], align 8
276 ; CROSS-BLOCK-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
277 ; CROSS-BLOCK-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
278 ; CROSS-BLOCK-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
279 ; CROSS-BLOCK-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
280 ; CROSS-BLOCK-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
281 ; CROSS-BLOCK-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
282 ; CROSS-BLOCK-NEXT: store i8 [[I8]], ptr [[I9]], align 1
283 ; CROSS-BLOCK-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 8
284 ; CROSS-BLOCK-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
285 ; CROSS-BLOCK-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
286 ; CROSS-BLOCK-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
287 ; CROSS-BLOCK-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
288 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "nonnull"(ptr [[I17]]), "align"(ptr [[I17]], i64 4) ]
289 ; CROSS-BLOCK-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 4
290 ; CROSS-BLOCK-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
291 ; CROSS-BLOCK-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
292 ; CROSS-BLOCK-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
293 ; CROSS-BLOCK-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
294 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I22]], i64 16), "nonnull"(ptr [[I22]]), "align"(ptr [[I22]], i64 8) ]
295 ; CROSS-BLOCK-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
296 ; CROSS-BLOCK-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
297 ; CROSS-BLOCK-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
298 ; CROSS-BLOCK-NEXT: ret i32 [[I26]]
300 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test2
301 ; FULL-SIMPLIFY-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
302 ; FULL-SIMPLIFY-NEXT: bb:
303 ; FULL-SIMPLIFY-NEXT: [[I:%.*]] = alloca ptr, align 8
304 ; FULL-SIMPLIFY-NEXT: [[I3:%.*]] = alloca ptr, align 8
305 ; FULL-SIMPLIFY-NEXT: [[I4:%.*]] = alloca ptr, align 8
306 ; FULL-SIMPLIFY-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
307 ; FULL-SIMPLIFY-NEXT: store ptr [[ARG]], ptr [[I]], align 8
308 ; FULL-SIMPLIFY-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
309 ; FULL-SIMPLIFY-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
310 ; FULL-SIMPLIFY-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
311 ; FULL-SIMPLIFY-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
312 ; FULL-SIMPLIFY-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
313 ; FULL-SIMPLIFY-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
314 ; FULL-SIMPLIFY-NEXT: store i8 [[I8]], ptr [[I9]], align 1
315 ; FULL-SIMPLIFY-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 8
316 ; FULL-SIMPLIFY-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
317 ; FULL-SIMPLIFY-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
318 ; FULL-SIMPLIFY-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
319 ; FULL-SIMPLIFY-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
320 ; FULL-SIMPLIFY-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 4
321 ; FULL-SIMPLIFY-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
322 ; FULL-SIMPLIFY-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
323 ; FULL-SIMPLIFY-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
324 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "nonnull"(ptr [[I17]]), "align"(ptr [[I17]], i64 4), "dereferenceable"(ptr [[I22]], i64 16), "nonnull"(ptr [[I22]]), "align"(ptr [[I22]], i64 8) ]
325 ; FULL-SIMPLIFY-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
326 ; FULL-SIMPLIFY-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
327 ; FULL-SIMPLIFY-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
328 ; FULL-SIMPLIFY-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
329 ; FULL-SIMPLIFY-NEXT: ret i32 [[I26]]
332 %i = alloca ptr, align 8
333 %i3 = alloca ptr, align 8
334 %i4 = alloca ptr, align 8
335 %i5 = alloca %struct.S, align 8
336 store ptr %arg, ptr %i, align 8
337 store ptr %arg1, ptr %i3, align 8
338 store ptr %arg2, ptr %i4, align 8
339 %i6 = load ptr, ptr %i3, align 8
340 %i7 = load i32, ptr %i6, align 4
341 %i8 = trunc i32 %i7 to i8
342 %i9 = load ptr, ptr %i4, align 8
343 store i8 %i8, ptr %i9, align 1
344 %i11 = load ptr, ptr %i, align 8
345 %i14 = load ptr, ptr %i, align 8
346 %i16 = load i32, ptr %i14, align 8
347 %i17 = load ptr, ptr %i, align 8
348 %i18 = getelementptr inbounds %struct.S, ptr %i17, i32 0, i32 1
349 %i19 = load i8, ptr %i18, align 4
350 %i20 = sext i8 %i19 to i32
351 %i21 = add nsw i32 %i16, %i20
352 %i22 = load ptr, ptr %i, align 8
353 %i23 = getelementptr inbounds %struct.S, ptr %i22, i32 0, i32 2
354 %i24 = load ptr, ptr %i23, align 8
355 %i25 = load i32, ptr %i24, align 4
356 %i26 = add nsw i32 %i21, %i25
360 define i32 @test3(ptr %arg, ptr %arg1, ptr %arg2) #4 {
361 ; BASIC-LABEL: define {{[^@]+}}@test3
362 ; BASIC-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #[[ATTR4:[0-9]+]] {
364 ; BASIC-NEXT: [[I:%.*]] = alloca ptr, align 8
365 ; BASIC-NEXT: [[I3:%.*]] = alloca ptr, align 8
366 ; BASIC-NEXT: [[I4:%.*]] = alloca ptr, align 8
367 ; BASIC-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
368 ; BASIC-NEXT: store ptr [[ARG]], ptr [[I]], align 8
369 ; BASIC-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
370 ; BASIC-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
371 ; BASIC-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
372 ; BASIC-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
373 ; BASIC-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
374 ; BASIC-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
375 ; BASIC-NEXT: store i8 [[I8]], ptr [[I9]], align 1
376 ; BASIC-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 32
377 ; BASIC-NEXT: call void @may_throw()
378 ; BASIC-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
379 ; BASIC-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
380 ; BASIC-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
381 ; BASIC-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
382 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "align"(ptr [[I17]], i64 4) ]
383 ; BASIC-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 8
384 ; BASIC-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
385 ; BASIC-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
386 ; BASIC-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
387 ; BASIC-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
388 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I22]], i64 16), "align"(ptr [[I22]], i64 8) ]
389 ; BASIC-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
390 ; BASIC-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
391 ; BASIC-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
392 ; BASIC-NEXT: ret i32 [[I26]]
394 ; ALL-LABEL: define {{[^@]+}}@test3
395 ; ALL-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #[[ATTR4:[0-9]+]] {
397 ; ALL-NEXT: [[I:%.*]] = alloca ptr, align 8
398 ; ALL-NEXT: [[I3:%.*]] = alloca ptr, align 8
399 ; ALL-NEXT: [[I4:%.*]] = alloca ptr, align 8
400 ; ALL-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
401 ; ALL-NEXT: store ptr [[ARG]], ptr [[I]], align 8
402 ; ALL-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
403 ; ALL-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
404 ; ALL-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
405 ; ALL-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
406 ; ALL-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
407 ; ALL-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
408 ; ALL-NEXT: store i8 [[I8]], ptr [[I9]], align 1
409 ; ALL-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 32
410 ; ALL-NEXT: call void @may_throw()
411 ; ALL-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
412 ; ALL-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
413 ; ALL-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
414 ; ALL-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
415 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "align"(ptr [[I17]], i64 4) ]
416 ; ALL-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 8
417 ; ALL-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
418 ; ALL-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
419 ; ALL-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
420 ; ALL-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
421 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I22]], i64 16), "align"(ptr [[I22]], i64 8) ]
422 ; ALL-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
423 ; ALL-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
424 ; ALL-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
425 ; ALL-NEXT: ret i32 [[I26]]
427 ; WITH-AC-LABEL: define {{[^@]+}}@test3
428 ; WITH-AC-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #[[ATTR4:[0-9]+]] {
430 ; WITH-AC-NEXT: [[I:%.*]] = alloca ptr, align 8
431 ; WITH-AC-NEXT: [[I3:%.*]] = alloca ptr, align 8
432 ; WITH-AC-NEXT: [[I4:%.*]] = alloca ptr, align 8
433 ; WITH-AC-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
434 ; WITH-AC-NEXT: store ptr [[ARG]], ptr [[I]], align 8
435 ; WITH-AC-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
436 ; WITH-AC-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
437 ; WITH-AC-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
438 ; WITH-AC-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
439 ; WITH-AC-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
440 ; WITH-AC-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
441 ; WITH-AC-NEXT: store i8 [[I8]], ptr [[I9]], align 1
442 ; WITH-AC-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 32
443 ; WITH-AC-NEXT: call void @may_throw()
444 ; WITH-AC-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
445 ; WITH-AC-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
446 ; WITH-AC-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
447 ; WITH-AC-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
448 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "align"(ptr [[I17]], i64 4) ]
449 ; WITH-AC-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 8
450 ; WITH-AC-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
451 ; WITH-AC-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
452 ; WITH-AC-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
453 ; WITH-AC-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
454 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I22]], i64 16), "align"(ptr [[I22]], i64 8) ]
455 ; WITH-AC-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
456 ; WITH-AC-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
457 ; WITH-AC-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
458 ; WITH-AC-NEXT: ret i32 [[I26]]
460 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test3
461 ; CROSS-BLOCK-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #[[ATTR4:[0-9]+]] {
462 ; CROSS-BLOCK-NEXT: bb:
463 ; CROSS-BLOCK-NEXT: [[I:%.*]] = alloca ptr, align 8
464 ; CROSS-BLOCK-NEXT: [[I3:%.*]] = alloca ptr, align 8
465 ; CROSS-BLOCK-NEXT: [[I4:%.*]] = alloca ptr, align 8
466 ; CROSS-BLOCK-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
467 ; CROSS-BLOCK-NEXT: store ptr [[ARG]], ptr [[I]], align 8
468 ; CROSS-BLOCK-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
469 ; CROSS-BLOCK-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
470 ; CROSS-BLOCK-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
471 ; CROSS-BLOCK-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
472 ; CROSS-BLOCK-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
473 ; CROSS-BLOCK-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
474 ; CROSS-BLOCK-NEXT: store i8 [[I8]], ptr [[I9]], align 1
475 ; CROSS-BLOCK-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 32
476 ; CROSS-BLOCK-NEXT: call void @may_throw()
477 ; CROSS-BLOCK-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
478 ; CROSS-BLOCK-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
479 ; CROSS-BLOCK-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
480 ; CROSS-BLOCK-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
481 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "align"(ptr [[I17]], i64 4) ]
482 ; CROSS-BLOCK-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 8
483 ; CROSS-BLOCK-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
484 ; CROSS-BLOCK-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
485 ; CROSS-BLOCK-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
486 ; CROSS-BLOCK-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
487 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I22]], i64 16), "align"(ptr [[I22]], i64 8) ]
488 ; CROSS-BLOCK-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
489 ; CROSS-BLOCK-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
490 ; CROSS-BLOCK-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
491 ; CROSS-BLOCK-NEXT: ret i32 [[I26]]
493 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test3
494 ; FULL-SIMPLIFY-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #[[ATTR4:[0-9]+]] {
495 ; FULL-SIMPLIFY-NEXT: bb:
496 ; FULL-SIMPLIFY-NEXT: [[I:%.*]] = alloca ptr, align 8
497 ; FULL-SIMPLIFY-NEXT: [[I3:%.*]] = alloca ptr, align 8
498 ; FULL-SIMPLIFY-NEXT: [[I4:%.*]] = alloca ptr, align 8
499 ; FULL-SIMPLIFY-NEXT: [[I5:%.*]] = alloca [[STRUCT_S:%.*]], align 8
500 ; FULL-SIMPLIFY-NEXT: store ptr [[ARG]], ptr [[I]], align 8
501 ; FULL-SIMPLIFY-NEXT: store ptr [[ARG1]], ptr [[I3]], align 8
502 ; FULL-SIMPLIFY-NEXT: store ptr [[ARG2]], ptr [[I4]], align 8
503 ; FULL-SIMPLIFY-NEXT: [[I6:%.*]] = load ptr, ptr [[I3]], align 8
504 ; FULL-SIMPLIFY-NEXT: [[I7:%.*]] = load i32, ptr [[I6]], align 4
505 ; FULL-SIMPLIFY-NEXT: [[I8:%.*]] = trunc i32 [[I7]] to i8
506 ; FULL-SIMPLIFY-NEXT: [[I9:%.*]] = load ptr, ptr [[I4]], align 8
507 ; FULL-SIMPLIFY-NEXT: store i8 [[I8]], ptr [[I9]], align 1
508 ; FULL-SIMPLIFY-NEXT: [[I11:%.*]] = load ptr, ptr [[I]], align 32
509 ; FULL-SIMPLIFY-NEXT: call void @may_throw()
510 ; FULL-SIMPLIFY-NEXT: [[I14:%.*]] = load ptr, ptr [[I]], align 8
511 ; FULL-SIMPLIFY-NEXT: [[I16:%.*]] = load i32, ptr [[I14]], align 8
512 ; FULL-SIMPLIFY-NEXT: [[I17:%.*]] = load ptr, ptr [[I]], align 8
513 ; FULL-SIMPLIFY-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I17]], i32 0, i32 1
514 ; FULL-SIMPLIFY-NEXT: [[I19:%.*]] = load i8, ptr [[I18]], align 8
515 ; FULL-SIMPLIFY-NEXT: [[I20:%.*]] = sext i8 [[I19]] to i32
516 ; FULL-SIMPLIFY-NEXT: [[I21:%.*]] = add nsw i32 [[I16]], [[I20]]
517 ; FULL-SIMPLIFY-NEXT: [[I22:%.*]] = load ptr, ptr [[I]], align 8
518 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I17]], i64 5), "align"(ptr [[I17]], i64 4), "dereferenceable"(ptr [[I22]], i64 16), "align"(ptr [[I22]], i64 8) ]
519 ; FULL-SIMPLIFY-NEXT: [[I23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[I22]], i32 0, i32 2
520 ; FULL-SIMPLIFY-NEXT: [[I24:%.*]] = load ptr, ptr [[I23]], align 8
521 ; FULL-SIMPLIFY-NEXT: [[I25:%.*]] = load i32, ptr [[I24]], align 4
522 ; FULL-SIMPLIFY-NEXT: [[I26:%.*]] = add nsw i32 [[I21]], [[I25]]
523 ; FULL-SIMPLIFY-NEXT: ret i32 [[I26]]
526 %i = alloca ptr, align 8
527 %i3 = alloca ptr, align 8
528 %i4 = alloca ptr, align 8
529 %i5 = alloca %struct.S, align 8
530 store ptr %arg, ptr %i, align 8
531 store ptr %arg1, ptr %i3, align 8
532 store ptr %arg2, ptr %i4, align 8
533 %i6 = load ptr, ptr %i3, align 8
534 %i7 = load i32, ptr %i6, align 4
535 %i8 = trunc i32 %i7 to i8
536 %i9 = load ptr, ptr %i4, align 8
537 store i8 %i8, ptr %i9, align 1
538 %i11 = load ptr, ptr %i, align 32
539 call void @may_throw()
540 %i14 = load ptr, ptr %i, align 8
541 %i16 = load i32, ptr %i14, align 8
542 %i17 = load ptr, ptr %i, align 8
543 %i18 = getelementptr inbounds %struct.S, ptr %i17, i32 0, i32 1
544 %i19 = load i8, ptr %i18, align 8
545 %i20 = sext i8 %i19 to i32
546 %i21 = add nsw i32 %i16, %i20
547 %i22 = load ptr, ptr %i, align 8
548 %i23 = getelementptr inbounds %struct.S, ptr %i22, i32 0, i32 2
549 %i24 = load ptr, ptr %i23, align 8
550 %i25 = load i32, ptr %i24, align 4
551 %i26 = add nsw i32 %i21, %i25
555 define dso_local i32 @_Z6squarePi(ptr %P, ptr %P1, i1 %cond) {
556 ; BASIC-LABEL: define {{[^@]+}}@_Z6squarePi
557 ; BASIC-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], i1 [[COND:%.*]]) {
559 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 4) ]
560 ; BASIC-NEXT: store i32 0, ptr [[P]], align 4
561 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
562 ; BASIC-NEXT: store i32 0, ptr [[P1]], align 8
563 ; BASIC-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
565 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
566 ; BASIC-NEXT: store i32 0, ptr [[P]], align 8
567 ; BASIC-NEXT: store i32 0, ptr [[P1]], align 4
568 ; BASIC-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
570 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
571 ; BASIC-NEXT: store i32 0, ptr [[P]], align 8
572 ; BASIC-NEXT: store i32 0, ptr [[P1]], align 8
573 ; BASIC-NEXT: br label [[C]]
575 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
576 ; BASIC-NEXT: store i32 0, ptr [[P]], align 32
577 ; BASIC-NEXT: store i32 0, ptr [[P1]], align 4
578 ; BASIC-NEXT: ret i32 0
580 ; ALL-LABEL: define {{[^@]+}}@_Z6squarePi
581 ; ALL-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], i1 [[COND:%.*]]) {
583 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 4) ]
584 ; ALL-NEXT: store i32 0, ptr [[P]], align 4
585 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
586 ; ALL-NEXT: store i32 0, ptr [[P1]], align 8
587 ; ALL-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
589 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
590 ; ALL-NEXT: store i32 0, ptr [[P]], align 8
591 ; ALL-NEXT: store i32 0, ptr [[P1]], align 4
592 ; ALL-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
594 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
595 ; ALL-NEXT: store i32 0, ptr [[P]], align 8
596 ; ALL-NEXT: store i32 0, ptr [[P1]], align 8
597 ; ALL-NEXT: br label [[C]]
599 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
600 ; ALL-NEXT: store i32 0, ptr [[P]], align 32
601 ; ALL-NEXT: store i32 0, ptr [[P1]], align 4
602 ; ALL-NEXT: ret i32 0
604 ; WITH-AC-LABEL: define {{[^@]+}}@_Z6squarePi
605 ; WITH-AC-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], i1 [[COND:%.*]]) {
607 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 4) ]
608 ; WITH-AC-NEXT: store i32 0, ptr [[P]], align 4
609 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
610 ; WITH-AC-NEXT: store i32 0, ptr [[P1]], align 8
611 ; WITH-AC-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
613 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
614 ; WITH-AC-NEXT: store i32 0, ptr [[P]], align 8
615 ; WITH-AC-NEXT: store i32 0, ptr [[P1]], align 4
616 ; WITH-AC-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
618 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
619 ; WITH-AC-NEXT: store i32 0, ptr [[P]], align 8
620 ; WITH-AC-NEXT: store i32 0, ptr [[P1]], align 8
621 ; WITH-AC-NEXT: br label [[C]]
623 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
624 ; WITH-AC-NEXT: store i32 0, ptr [[P]], align 32
625 ; WITH-AC-NEXT: store i32 0, ptr [[P1]], align 4
626 ; WITH-AC-NEXT: ret i32 0
628 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@_Z6squarePi
629 ; CROSS-BLOCK-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], i1 [[COND:%.*]]) {
630 ; CROSS-BLOCK-NEXT: bb:
631 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 4) ]
632 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[P]], align 4
633 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 4), "nonnull"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ]
634 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[P1]], align 8
635 ; CROSS-BLOCK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
637 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
638 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[P]], align 8
639 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[P1]], align 4
640 ; CROSS-BLOCK-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
642 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
643 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[P]], align 8
644 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[P1]], align 8
645 ; CROSS-BLOCK-NEXT: br label [[C]]
647 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
648 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[P]], align 32
649 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[P1]], align 4
650 ; CROSS-BLOCK-NEXT: ret i32 0
652 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@_Z6squarePi
653 ; FULL-SIMPLIFY-SAME: (ptr nonnull align 4 dereferenceable(4) [[P:%.*]], ptr nonnull align 8 dereferenceable(4) [[P1:%.*]], i1 [[COND:%.*]]) {
654 ; FULL-SIMPLIFY-NEXT: bb:
655 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P]], align 4
656 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P1]], align 8
657 ; FULL-SIMPLIFY-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
659 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
660 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P]], align 8
661 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P1]], align 4
662 ; FULL-SIMPLIFY-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
664 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
665 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P]], align 8
666 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P1]], align 8
667 ; FULL-SIMPLIFY-NEXT: br label [[C]]
669 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 32) ]
670 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P]], align 32
671 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[P1]], align 4
672 ; FULL-SIMPLIFY-NEXT: ret i32 0
675 store i32 0, ptr %P, align 4
676 store i32 0, ptr %P1, align 8
677 br i1 %cond, label %A, label %B
680 store i32 0, ptr %P, align 8
681 store i32 0, ptr %P1, align 4
682 br i1 %cond, label %C, label %B
685 store i32 0, ptr %P, align 8
686 store i32 0, ptr %P1, align 8
690 store i32 0, ptr %P, align 32
691 store i32 0, ptr %P1, align 4
695 define dso_local i32 @test4A(ptr %arg, ptr %arg1, i32 %arg2, i32 %arg3) {
696 ; BASIC-LABEL: define {{[^@]+}}@test4A
697 ; BASIC-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) {
699 ; BASIC-NEXT: [[I:%.*]] = icmp ne ptr [[ARG1]], null
700 ; BASIC-NEXT: br i1 [[I]], label [[BB4:%.*]], label [[BB10:%.*]]
702 ; BASIC-NEXT: [[I5:%.*]] = add nsw i32 [[ARG3]], [[ARG2]]
703 ; BASIC-NEXT: call void @may_throw()
704 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 4), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4) ]
705 ; BASIC-NEXT: [[I6:%.*]] = load i32, ptr [[ARG]], align 4
706 ; BASIC-NEXT: [[I7:%.*]] = add nsw i32 [[I5]], [[I6]]
707 ; BASIC-NEXT: store i32 0, ptr [[ARG]], align 4
708 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 4), "nonnull"(ptr [[ARG1]]), "align"(ptr [[ARG1]], i64 4) ]
709 ; BASIC-NEXT: [[I8:%.*]] = load i32, ptr [[ARG1]], align 4
710 ; BASIC-NEXT: [[I9:%.*]] = add nsw i32 [[I7]], [[I8]]
711 ; BASIC-NEXT: call void @may_throw()
712 ; BASIC-NEXT: store i32 [[I9]], ptr [[ARG1]], align 4
713 ; BASIC-NEXT: br label [[BB10]]
715 ; BASIC-NEXT: ret i32 0
717 ; ALL-LABEL: define {{[^@]+}}@test4A
718 ; ALL-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) {
720 ; ALL-NEXT: [[I:%.*]] = icmp ne ptr [[ARG1]], null
721 ; ALL-NEXT: br i1 [[I]], label [[BB4:%.*]], label [[BB10:%.*]]
723 ; ALL-NEXT: [[I5:%.*]] = add nsw i32 [[ARG3]], [[ARG2]]
724 ; ALL-NEXT: call void @may_throw()
725 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 4), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4) ]
726 ; ALL-NEXT: [[I6:%.*]] = load i32, ptr [[ARG]], align 4
727 ; ALL-NEXT: [[I7:%.*]] = add nsw i32 [[I5]], [[I6]]
728 ; ALL-NEXT: store i32 0, ptr [[ARG]], align 4
729 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 4), "nonnull"(ptr [[ARG1]]), "align"(ptr [[ARG1]], i64 4) ]
730 ; ALL-NEXT: [[I8:%.*]] = load i32, ptr [[ARG1]], align 4
731 ; ALL-NEXT: [[I9:%.*]] = add nsw i32 [[I7]], [[I8]]
732 ; ALL-NEXT: call void @may_throw()
733 ; ALL-NEXT: store i32 [[I9]], ptr [[ARG1]], align 4
734 ; ALL-NEXT: br label [[BB10]]
736 ; ALL-NEXT: ret i32 0
738 ; WITH-AC-LABEL: define {{[^@]+}}@test4A
739 ; WITH-AC-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) {
741 ; WITH-AC-NEXT: [[I:%.*]] = icmp ne ptr [[ARG1]], null
742 ; WITH-AC-NEXT: br i1 [[I]], label [[BB4:%.*]], label [[BB10:%.*]]
744 ; WITH-AC-NEXT: [[I5:%.*]] = add nsw i32 [[ARG3]], [[ARG2]]
745 ; WITH-AC-NEXT: call void @may_throw()
746 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 4), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4) ]
747 ; WITH-AC-NEXT: [[I6:%.*]] = load i32, ptr [[ARG]], align 4
748 ; WITH-AC-NEXT: [[I7:%.*]] = add nsw i32 [[I5]], [[I6]]
749 ; WITH-AC-NEXT: store i32 0, ptr [[ARG]], align 4
750 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 4), "nonnull"(ptr [[ARG1]]), "align"(ptr [[ARG1]], i64 4) ]
751 ; WITH-AC-NEXT: [[I8:%.*]] = load i32, ptr [[ARG1]], align 4
752 ; WITH-AC-NEXT: [[I9:%.*]] = add nsw i32 [[I7]], [[I8]]
753 ; WITH-AC-NEXT: call void @may_throw()
754 ; WITH-AC-NEXT: store i32 [[I9]], ptr [[ARG1]], align 4
755 ; WITH-AC-NEXT: br label [[BB10]]
757 ; WITH-AC-NEXT: ret i32 0
759 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test4A
760 ; CROSS-BLOCK-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) {
761 ; CROSS-BLOCK-NEXT: bb:
762 ; CROSS-BLOCK-NEXT: [[I:%.*]] = icmp ne ptr [[ARG1]], null
763 ; CROSS-BLOCK-NEXT: br i1 [[I]], label [[BB4:%.*]], label [[BB10:%.*]]
765 ; CROSS-BLOCK-NEXT: [[I5:%.*]] = add nsw i32 [[ARG3]], [[ARG2]]
766 ; CROSS-BLOCK-NEXT: call void @may_throw()
767 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 4), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4) ]
768 ; CROSS-BLOCK-NEXT: [[I6:%.*]] = load i32, ptr [[ARG]], align 4
769 ; CROSS-BLOCK-NEXT: [[I7:%.*]] = add nsw i32 [[I5]], [[I6]]
770 ; CROSS-BLOCK-NEXT: store i32 0, ptr [[ARG]], align 4
771 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 4), "nonnull"(ptr [[ARG1]]), "align"(ptr [[ARG1]], i64 4) ]
772 ; CROSS-BLOCK-NEXT: [[I8:%.*]] = load i32, ptr [[ARG1]], align 4
773 ; CROSS-BLOCK-NEXT: [[I9:%.*]] = add nsw i32 [[I7]], [[I8]]
774 ; CROSS-BLOCK-NEXT: call void @may_throw()
775 ; CROSS-BLOCK-NEXT: store i32 [[I9]], ptr [[ARG1]], align 4
776 ; CROSS-BLOCK-NEXT: br label [[BB10]]
778 ; CROSS-BLOCK-NEXT: ret i32 0
780 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test4A
781 ; FULL-SIMPLIFY-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) {
782 ; FULL-SIMPLIFY-NEXT: bb:
783 ; FULL-SIMPLIFY-NEXT: [[I:%.*]] = icmp ne ptr [[ARG1]], null
784 ; FULL-SIMPLIFY-NEXT: br i1 [[I]], label [[BB4:%.*]], label [[BB10:%.*]]
785 ; FULL-SIMPLIFY: bb4:
786 ; FULL-SIMPLIFY-NEXT: [[I5:%.*]] = add nsw i32 [[ARG3]], [[ARG2]]
787 ; FULL-SIMPLIFY-NEXT: call void @may_throw()
788 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 4), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4), "dereferenceable"(ptr [[ARG1]], i64 4), "nonnull"(ptr [[ARG1]]), "align"(ptr [[ARG1]], i64 4) ]
789 ; FULL-SIMPLIFY-NEXT: [[I6:%.*]] = load i32, ptr [[ARG]], align 4
790 ; FULL-SIMPLIFY-NEXT: [[I7:%.*]] = add nsw i32 [[I5]], [[I6]]
791 ; FULL-SIMPLIFY-NEXT: store i32 0, ptr [[ARG]], align 4
792 ; FULL-SIMPLIFY-NEXT: [[I8:%.*]] = load i32, ptr [[ARG1]], align 4
793 ; FULL-SIMPLIFY-NEXT: [[I9:%.*]] = add nsw i32 [[I7]], [[I8]]
794 ; FULL-SIMPLIFY-NEXT: call void @may_throw()
795 ; FULL-SIMPLIFY-NEXT: store i32 [[I9]], ptr [[ARG1]], align 4
796 ; FULL-SIMPLIFY-NEXT: br label [[BB10]]
797 ; FULL-SIMPLIFY: bb10:
798 ; FULL-SIMPLIFY-NEXT: ret i32 0
801 %i = icmp ne ptr %arg1, null
802 br i1 %i, label %bb4, label %bb10
805 %i5 = add nsw i32 %arg3, %arg2
806 call void @may_throw()
807 %i6 = load i32, ptr %arg, align 4
808 %i7 = add nsw i32 %i5, %i6
809 store i32 0, ptr %arg, align 4
810 %i8 = load i32, ptr %arg1, align 4
811 %i9 = add nsw i32 %i7, %i8
812 call void @may_throw()
813 store i32 %i9, ptr %arg1, align 4
816 bb10: ; preds = %bb4, %bb
820 declare void @may_throwv2(ptr)
822 define dso_local i32 @terminator(ptr %P) personality ptr @__gxx_personality_v0 {
823 ; BASIC-LABEL: define {{[^@]+}}@terminator
824 ; BASIC-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
826 ; BASIC-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
827 ; BASIC-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
829 ; BASIC-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
830 ; BASIC-NEXT: catch ptr null
831 ; BASIC-NEXT: br label [[EXIT]]
833 ; BASIC-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
834 ; BASIC-NEXT: ret i32 [[DOT0]]
836 ; ALL-LABEL: define {{[^@]+}}@terminator
837 ; ALL-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
839 ; ALL-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
840 ; ALL-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
842 ; ALL-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
843 ; ALL-NEXT: catch ptr null
844 ; ALL-NEXT: br label [[EXIT]]
846 ; ALL-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
847 ; ALL-NEXT: ret i32 [[DOT0]]
849 ; WITH-AC-LABEL: define {{[^@]+}}@terminator
850 ; WITH-AC-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
852 ; WITH-AC-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
853 ; WITH-AC-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
855 ; WITH-AC-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
856 ; WITH-AC-NEXT: catch ptr null
857 ; WITH-AC-NEXT: br label [[EXIT]]
859 ; WITH-AC-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
860 ; WITH-AC-NEXT: ret i32 [[DOT0]]
862 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@terminator
863 ; CROSS-BLOCK-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
864 ; CROSS-BLOCK-NEXT: bb:
865 ; CROSS-BLOCK-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
866 ; CROSS-BLOCK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
867 ; CROSS-BLOCK: Catch:
868 ; CROSS-BLOCK-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
869 ; CROSS-BLOCK-NEXT: catch ptr null
870 ; CROSS-BLOCK-NEXT: br label [[EXIT]]
872 ; CROSS-BLOCK-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
873 ; CROSS-BLOCK-NEXT: ret i32 [[DOT0]]
875 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@terminator
876 ; FULL-SIMPLIFY-SAME: (ptr [[P:%.*]]) personality ptr @__gxx_personality_v0 {
877 ; FULL-SIMPLIFY-NEXT: bb:
878 ; FULL-SIMPLIFY-NEXT: invoke void @may_throwv2(ptr nonnull [[P]])
879 ; FULL-SIMPLIFY-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
880 ; FULL-SIMPLIFY: Catch:
881 ; FULL-SIMPLIFY-NEXT: [[V:%.*]] = landingpad { ptr, i32 }
882 ; FULL-SIMPLIFY-NEXT: catch ptr null
883 ; FULL-SIMPLIFY-NEXT: br label [[EXIT]]
884 ; FULL-SIMPLIFY: Exit:
885 ; FULL-SIMPLIFY-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[BB:%.*]] ], [ 0, [[CATCH]] ]
886 ; FULL-SIMPLIFY-NEXT: ret i32 [[DOT0]]
889 invoke void @may_throwv2(ptr nonnull %P)
890 to label %Exit unwind label %Catch
893 %v = landingpad { ptr, i32 }
897 Exit: ; preds = %Catch, %bb
898 %.0 = phi i32 [ 1, %bb ], [ 0, %Catch ]
902 declare dso_local i32 @__gxx_personality_v0(...)
904 define dso_local i32 @test5(ptr %arg, i32 %arg1) {
905 ; BASIC-LABEL: define {{[^@]+}}@test5
906 ; BASIC-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]]) {
908 ; BASIC-NEXT: [[I3:%.*]] = sext i32 [[ARG1]] to i64
909 ; BASIC-NEXT: [[I4:%.*]] = getelementptr inbounds i16, ptr [[ARG]], i64 [[I3]]
910 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I4]], i64 2), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 8) ]
911 ; BASIC-NEXT: [[I5:%.*]] = load i16, ptr [[I4]], align 2
912 ; BASIC-NEXT: [[A:%.*]] = load i16, ptr [[I4]], align 4
913 ; BASIC-NEXT: [[I6:%.*]] = sext i16 [[I5]] to i64
914 ; BASIC-NEXT: [[I7:%.*]] = getelementptr inbounds i64, ptr [[ARG]], i64 [[I6]]
915 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I7]], i64 8) ]
916 ; BASIC-NEXT: [[I8:%.*]] = load i64, ptr [[I7]], align 16
917 ; BASIC-NEXT: [[B:%.*]] = load i64, ptr [[I7]], align 32
918 ; BASIC-NEXT: [[I9:%.*]] = trunc i64 [[I8]] to i32
919 ; BASIC-NEXT: ret i32 [[I9]]
921 ; ALL-LABEL: define {{[^@]+}}@test5
922 ; ALL-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]]) {
924 ; ALL-NEXT: [[I3:%.*]] = sext i32 [[ARG1]] to i64
925 ; ALL-NEXT: [[I4:%.*]] = getelementptr inbounds i16, ptr [[ARG]], i64 [[I3]]
926 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I4]], i64 2), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 8) ]
927 ; ALL-NEXT: [[I5:%.*]] = load i16, ptr [[I4]], align 2
928 ; ALL-NEXT: [[A:%.*]] = load i16, ptr [[I4]], align 4
929 ; ALL-NEXT: [[I6:%.*]] = sext i16 [[I5]] to i64
930 ; ALL-NEXT: [[I7:%.*]] = getelementptr inbounds i64, ptr [[ARG]], i64 [[I6]]
931 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I7]], i64 8) ]
932 ; ALL-NEXT: [[I8:%.*]] = load i64, ptr [[I7]], align 16
933 ; ALL-NEXT: [[B:%.*]] = load i64, ptr [[I7]], align 32
934 ; ALL-NEXT: [[I9:%.*]] = trunc i64 [[I8]] to i32
935 ; ALL-NEXT: ret i32 [[I9]]
937 ; WITH-AC-LABEL: define {{[^@]+}}@test5
938 ; WITH-AC-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]]) {
940 ; WITH-AC-NEXT: [[I3:%.*]] = sext i32 [[ARG1]] to i64
941 ; WITH-AC-NEXT: [[I4:%.*]] = getelementptr inbounds i16, ptr [[ARG]], i64 [[I3]]
942 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I4]], i64 2), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 8) ]
943 ; WITH-AC-NEXT: [[I5:%.*]] = load i16, ptr [[I4]], align 2
944 ; WITH-AC-NEXT: [[A:%.*]] = load i16, ptr [[I4]], align 4
945 ; WITH-AC-NEXT: [[I6:%.*]] = sext i16 [[I5]] to i64
946 ; WITH-AC-NEXT: [[I7:%.*]] = getelementptr inbounds i64, ptr [[ARG]], i64 [[I6]]
947 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I7]], i64 8) ]
948 ; WITH-AC-NEXT: [[I8:%.*]] = load i64, ptr [[I7]], align 16
949 ; WITH-AC-NEXT: [[B:%.*]] = load i64, ptr [[I7]], align 32
950 ; WITH-AC-NEXT: [[I9:%.*]] = trunc i64 [[I8]] to i32
951 ; WITH-AC-NEXT: ret i32 [[I9]]
953 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test5
954 ; CROSS-BLOCK-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]]) {
955 ; CROSS-BLOCK-NEXT: bb:
956 ; CROSS-BLOCK-NEXT: [[I3:%.*]] = sext i32 [[ARG1]] to i64
957 ; CROSS-BLOCK-NEXT: [[I4:%.*]] = getelementptr inbounds i16, ptr [[ARG]], i64 [[I3]]
958 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I4]], i64 2), "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 8) ]
959 ; CROSS-BLOCK-NEXT: [[I5:%.*]] = load i16, ptr [[I4]], align 2
960 ; CROSS-BLOCK-NEXT: [[A:%.*]] = load i16, ptr [[I4]], align 4
961 ; CROSS-BLOCK-NEXT: [[I6:%.*]] = sext i16 [[I5]] to i64
962 ; CROSS-BLOCK-NEXT: [[I7:%.*]] = getelementptr inbounds i64, ptr [[ARG]], i64 [[I6]]
963 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I7]], i64 8) ]
964 ; CROSS-BLOCK-NEXT: [[I8:%.*]] = load i64, ptr [[I7]], align 16
965 ; CROSS-BLOCK-NEXT: [[B:%.*]] = load i64, ptr [[I7]], align 32
966 ; CROSS-BLOCK-NEXT: [[I9:%.*]] = trunc i64 [[I8]] to i32
967 ; CROSS-BLOCK-NEXT: ret i32 [[I9]]
969 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test5
970 ; FULL-SIMPLIFY-SAME: (ptr nonnull align 8 [[ARG:%.*]], i32 [[ARG1:%.*]]) {
971 ; FULL-SIMPLIFY-NEXT: bb:
972 ; FULL-SIMPLIFY-NEXT: [[I3:%.*]] = sext i32 [[ARG1]] to i64
973 ; FULL-SIMPLIFY-NEXT: [[I4:%.*]] = getelementptr inbounds i16, ptr [[ARG]], i64 [[I3]]
974 ; FULL-SIMPLIFY-NEXT: [[I5:%.*]] = load i16, ptr [[I4]], align 2
975 ; FULL-SIMPLIFY-NEXT: [[A:%.*]] = load i16, ptr [[I4]], align 4
976 ; FULL-SIMPLIFY-NEXT: [[I6:%.*]] = sext i16 [[I5]] to i64
977 ; FULL-SIMPLIFY-NEXT: [[I7:%.*]] = getelementptr inbounds i64, ptr [[ARG]], i64 [[I6]]
978 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I4]], i64 2), "dereferenceable"(ptr [[I7]], i64 8) ]
979 ; FULL-SIMPLIFY-NEXT: [[I8:%.*]] = load i64, ptr [[I7]], align 16
980 ; FULL-SIMPLIFY-NEXT: [[B:%.*]] = load i64, ptr [[I7]], align 32
981 ; FULL-SIMPLIFY-NEXT: [[I9:%.*]] = trunc i64 [[I8]] to i32
982 ; FULL-SIMPLIFY-NEXT: ret i32 [[I9]]
985 %i3 = sext i32 %arg1 to i64
986 %i4 = getelementptr inbounds i16, ptr %arg, i64 %i3
987 %i5 = load i16, ptr %i4, align 2
988 %A = load i16, ptr %i4, align 4
989 %i6 = sext i16 %i5 to i64
990 %i7 = getelementptr inbounds i64, ptr %arg, i64 %i6
991 %i8 = load i64, ptr %i7, align 16
992 %B = load i64, ptr %i7, align 32
993 %i9 = trunc i64 %i8 to i32
997 define i32 @test6(ptr %arg, i32 %arg1, ptr %arg2) {
998 ; BASIC-LABEL: define {{[^@]+}}@test6
999 ; BASIC-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
1001 ; BASIC-NEXT: br label [[BB3:%.*]]
1003 ; BASIC-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[I14:%.*]], [[BB4:%.*]] ]
1004 ; BASIC-NEXT: [[I:%.*]] = icmp slt i32 [[DOT0]], [[ARG1]]
1005 ; BASIC-NEXT: br i1 [[I]], label [[BB4]], label [[BB15:%.*]]
1007 ; BASIC-NEXT: [[I5:%.*]] = add nsw i32 [[ARG1]], [[DOT0]]
1008 ; BASIC-NEXT: [[I6:%.*]] = sext i32 [[I5]] to i64
1009 ; BASIC-NEXT: [[I7:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I6]]
1010 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4) ]
1011 ; BASIC-NEXT: [[I8:%.*]] = load i32, ptr [[I7]], align 4
1012 ; BASIC-NEXT: [[I9:%.*]] = mul nsw i32 [[DOT0]], [[I8]]
1013 ; BASIC-NEXT: [[I10:%.*]] = sext i32 [[DOT0]] to i64
1014 ; BASIC-NEXT: [[I11:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I10]]
1015 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I11]], i64 4) ]
1016 ; BASIC-NEXT: [[I12:%.*]] = load i32, ptr [[I11]], align 4
1017 ; BASIC-NEXT: [[I13:%.*]] = add nsw i32 [[I12]], [[I9]]
1018 ; BASIC-NEXT: store i32 [[I13]], ptr [[I11]], align 4
1019 ; BASIC-NEXT: [[I14]] = add nsw i32 [[DOT0]], 1
1020 ; BASIC-NEXT: br label [[BB3]]
1022 ; BASIC-NEXT: [[I16:%.*]] = sext i32 [[ARG1]] to i64
1023 ; BASIC-NEXT: [[I17:%.*]] = getelementptr inbounds i32, ptr [[ARG2]], i64 [[I16]]
1024 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG2]]), "align"(ptr [[ARG2]], i64 4) ]
1025 ; BASIC-NEXT: [[I18:%.*]] = load i32, ptr [[I17]], align 4
1026 ; BASIC-NEXT: ret i32 [[I18]]
1028 ; ALL-LABEL: define {{[^@]+}}@test6
1029 ; ALL-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
1031 ; ALL-NEXT: br label [[BB3:%.*]]
1033 ; ALL-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[I14:%.*]], [[BB4:%.*]] ]
1034 ; ALL-NEXT: [[I:%.*]] = icmp slt i32 [[DOT0]], [[ARG1]]
1035 ; ALL-NEXT: br i1 [[I]], label [[BB4]], label [[BB15:%.*]]
1037 ; ALL-NEXT: [[I5:%.*]] = add nsw i32 [[ARG1]], [[DOT0]]
1038 ; ALL-NEXT: [[I6:%.*]] = sext i32 [[I5]] to i64
1039 ; ALL-NEXT: [[I7:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I6]]
1040 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4) ]
1041 ; ALL-NEXT: [[I8:%.*]] = load i32, ptr [[I7]], align 4
1042 ; ALL-NEXT: [[I9:%.*]] = mul nsw i32 [[DOT0]], [[I8]]
1043 ; ALL-NEXT: [[I10:%.*]] = sext i32 [[DOT0]] to i64
1044 ; ALL-NEXT: [[I11:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I10]]
1045 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I11]], i64 4) ]
1046 ; ALL-NEXT: [[I12:%.*]] = load i32, ptr [[I11]], align 4
1047 ; ALL-NEXT: [[I13:%.*]] = add nsw i32 [[I12]], [[I9]]
1048 ; ALL-NEXT: store i32 [[I13]], ptr [[I11]], align 4
1049 ; ALL-NEXT: [[I14]] = add nsw i32 [[DOT0]], 1
1050 ; ALL-NEXT: br label [[BB3]]
1052 ; ALL-NEXT: [[I16:%.*]] = sext i32 [[ARG1]] to i64
1053 ; ALL-NEXT: [[I17:%.*]] = getelementptr inbounds i32, ptr [[ARG2]], i64 [[I16]]
1054 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG2]]), "align"(ptr [[ARG2]], i64 4) ]
1055 ; ALL-NEXT: [[I18:%.*]] = load i32, ptr [[I17]], align 4
1056 ; ALL-NEXT: ret i32 [[I18]]
1058 ; WITH-AC-LABEL: define {{[^@]+}}@test6
1059 ; WITH-AC-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
1061 ; WITH-AC-NEXT: br label [[BB3:%.*]]
1063 ; WITH-AC-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[I14:%.*]], [[BB4:%.*]] ]
1064 ; WITH-AC-NEXT: [[I:%.*]] = icmp slt i32 [[DOT0]], [[ARG1]]
1065 ; WITH-AC-NEXT: br i1 [[I]], label [[BB4]], label [[BB15:%.*]]
1067 ; WITH-AC-NEXT: [[I5:%.*]] = add nsw i32 [[ARG1]], [[DOT0]]
1068 ; WITH-AC-NEXT: [[I6:%.*]] = sext i32 [[I5]] to i64
1069 ; WITH-AC-NEXT: [[I7:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I6]]
1070 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4) ]
1071 ; WITH-AC-NEXT: [[I8:%.*]] = load i32, ptr [[I7]], align 4
1072 ; WITH-AC-NEXT: [[I9:%.*]] = mul nsw i32 [[DOT0]], [[I8]]
1073 ; WITH-AC-NEXT: [[I10:%.*]] = sext i32 [[DOT0]] to i64
1074 ; WITH-AC-NEXT: [[I11:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I10]]
1075 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I11]], i64 4) ]
1076 ; WITH-AC-NEXT: [[I12:%.*]] = load i32, ptr [[I11]], align 4
1077 ; WITH-AC-NEXT: [[I13:%.*]] = add nsw i32 [[I12]], [[I9]]
1078 ; WITH-AC-NEXT: store i32 [[I13]], ptr [[I11]], align 4
1079 ; WITH-AC-NEXT: [[I14]] = add nsw i32 [[DOT0]], 1
1080 ; WITH-AC-NEXT: br label [[BB3]]
1082 ; WITH-AC-NEXT: [[I16:%.*]] = sext i32 [[ARG1]] to i64
1083 ; WITH-AC-NEXT: [[I17:%.*]] = getelementptr inbounds i32, ptr [[ARG2]], i64 [[I16]]
1084 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG2]]), "align"(ptr [[ARG2]], i64 4) ]
1085 ; WITH-AC-NEXT: [[I18:%.*]] = load i32, ptr [[I17]], align 4
1086 ; WITH-AC-NEXT: ret i32 [[I18]]
1088 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test6
1089 ; CROSS-BLOCK-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
1090 ; CROSS-BLOCK-NEXT: bb:
1091 ; CROSS-BLOCK-NEXT: br label [[BB3:%.*]]
1093 ; CROSS-BLOCK-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[I14:%.*]], [[BB4:%.*]] ]
1094 ; CROSS-BLOCK-NEXT: [[I:%.*]] = icmp slt i32 [[DOT0]], [[ARG1]]
1095 ; CROSS-BLOCK-NEXT: br i1 [[I]], label [[BB4]], label [[BB15:%.*]]
1097 ; CROSS-BLOCK-NEXT: [[I5:%.*]] = add nsw i32 [[ARG1]], [[DOT0]]
1098 ; CROSS-BLOCK-NEXT: [[I6:%.*]] = sext i32 [[I5]] to i64
1099 ; CROSS-BLOCK-NEXT: [[I7:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I6]]
1100 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4) ]
1101 ; CROSS-BLOCK-NEXT: [[I8:%.*]] = load i32, ptr [[I7]], align 4
1102 ; CROSS-BLOCK-NEXT: [[I9:%.*]] = mul nsw i32 [[DOT0]], [[I8]]
1103 ; CROSS-BLOCK-NEXT: [[I10:%.*]] = sext i32 [[DOT0]] to i64
1104 ; CROSS-BLOCK-NEXT: [[I11:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I10]]
1105 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I11]], i64 4) ]
1106 ; CROSS-BLOCK-NEXT: [[I12:%.*]] = load i32, ptr [[I11]], align 4
1107 ; CROSS-BLOCK-NEXT: [[I13:%.*]] = add nsw i32 [[I12]], [[I9]]
1108 ; CROSS-BLOCK-NEXT: store i32 [[I13]], ptr [[I11]], align 4
1109 ; CROSS-BLOCK-NEXT: [[I14]] = add nsw i32 [[DOT0]], 1
1110 ; CROSS-BLOCK-NEXT: br label [[BB3]]
1111 ; CROSS-BLOCK: bb15:
1112 ; CROSS-BLOCK-NEXT: [[I16:%.*]] = sext i32 [[ARG1]] to i64
1113 ; CROSS-BLOCK-NEXT: [[I17:%.*]] = getelementptr inbounds i32, ptr [[ARG2]], i64 [[I16]]
1114 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG2]]), "align"(ptr [[ARG2]], i64 4) ]
1115 ; CROSS-BLOCK-NEXT: [[I18:%.*]] = load i32, ptr [[I17]], align 4
1116 ; CROSS-BLOCK-NEXT: ret i32 [[I18]]
1118 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test6
1119 ; FULL-SIMPLIFY-SAME: (ptr [[ARG:%.*]], i32 [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
1120 ; FULL-SIMPLIFY-NEXT: bb:
1121 ; FULL-SIMPLIFY-NEXT: br label [[BB3:%.*]]
1122 ; FULL-SIMPLIFY: bb3:
1123 ; FULL-SIMPLIFY-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[I14:%.*]], [[BB4:%.*]] ]
1124 ; FULL-SIMPLIFY-NEXT: [[I:%.*]] = icmp slt i32 [[DOT0]], [[ARG1]]
1125 ; FULL-SIMPLIFY-NEXT: br i1 [[I]], label [[BB4]], label [[BB15:%.*]]
1126 ; FULL-SIMPLIFY: bb4:
1127 ; FULL-SIMPLIFY-NEXT: [[I5:%.*]] = add nsw i32 [[ARG1]], [[DOT0]]
1128 ; FULL-SIMPLIFY-NEXT: [[I6:%.*]] = sext i32 [[I5]] to i64
1129 ; FULL-SIMPLIFY-NEXT: [[I7:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I6]]
1130 ; FULL-SIMPLIFY-NEXT: [[I8:%.*]] = load i32, ptr [[I7]], align 4
1131 ; FULL-SIMPLIFY-NEXT: [[I9:%.*]] = mul nsw i32 [[DOT0]], [[I8]]
1132 ; FULL-SIMPLIFY-NEXT: [[I10:%.*]] = sext i32 [[DOT0]] to i64
1133 ; FULL-SIMPLIFY-NEXT: [[I11:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 [[I10]]
1134 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG]]), "align"(ptr [[ARG]], i64 4), "dereferenceable"(ptr [[I11]], i64 4) ]
1135 ; FULL-SIMPLIFY-NEXT: [[I12:%.*]] = load i32, ptr [[I11]], align 4
1136 ; FULL-SIMPLIFY-NEXT: [[I13:%.*]] = add nsw i32 [[I12]], [[I9]]
1137 ; FULL-SIMPLIFY-NEXT: store i32 [[I13]], ptr [[I11]], align 4
1138 ; FULL-SIMPLIFY-NEXT: [[I14]] = add nsw i32 [[DOT0]], 1
1139 ; FULL-SIMPLIFY-NEXT: br label [[BB3]]
1140 ; FULL-SIMPLIFY: bb15:
1141 ; FULL-SIMPLIFY-NEXT: [[I16:%.*]] = sext i32 [[ARG1]] to i64
1142 ; FULL-SIMPLIFY-NEXT: [[I17:%.*]] = getelementptr inbounds i32, ptr [[ARG2]], i64 [[I16]]
1143 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARG2]]), "align"(ptr [[ARG2]], i64 4) ]
1144 ; FULL-SIMPLIFY-NEXT: [[I18:%.*]] = load i32, ptr [[I17]], align 4
1145 ; FULL-SIMPLIFY-NEXT: ret i32 [[I18]]
1150 bb3: ; preds = %bb4, %bb
1151 %.0 = phi i32 [ 0, %bb ], [ %i14, %bb4 ]
1152 %i = icmp slt i32 %.0, %arg1
1153 br i1 %i, label %bb4, label %bb15
1156 %i5 = add nsw i32 %arg1, %.0
1157 %i6 = sext i32 %i5 to i64
1158 %i7 = getelementptr inbounds i32, ptr %arg, i64 %i6
1159 %i8 = load i32, ptr %i7, align 4
1160 %i9 = mul nsw i32 %.0, %i8
1161 %i10 = sext i32 %.0 to i64
1162 %i11 = getelementptr inbounds i32, ptr %arg, i64 %i10
1163 %i12 = load i32, ptr %i11, align 4
1164 %i13 = add nsw i32 %i12, %i9
1165 store i32 %i13, ptr %i11, align 4
1166 %i14 = add nsw i32 %.0, 1
1169 bb15: ; preds = %bb3
1170 %i16 = sext i32 %arg1 to i64
1171 %i17 = getelementptr inbounds i32, ptr %arg2, i64 %i16
1172 %i18 = load i32, ptr %i17, align 4
1176 define i32 @test7(ptr nonnull %arg, i32 %arg1) {
1177 ; BASIC-LABEL: define {{[^@]+}}@test7
1178 ; BASIC-SAME: (ptr nonnull [[ARG:%.*]], i32 [[ARG1:%.*]]) {
1180 ; BASIC-NEXT: [[I:%.*]] = sext i32 [[ARG1]] to i64
1181 ; BASIC-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[ARG]], i64 0, i32 3
1182 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 280), "align"(ptr [[ARG]], i64 16) ]
1183 ; BASIC-NEXT: [[I3:%.*]] = load i64, ptr [[I2]], align 8
1184 ; BASIC-NEXT: [[I4:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 2, i64 [[I]], i64 [[I3]], i32 0
1185 ; BASIC-NEXT: [[I5:%.*]] = load i64, ptr [[I4]], align 32
1186 ; BASIC-NEXT: [[I6:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 1
1187 ; BASIC-NEXT: [[I7:%.*]] = load ptr, ptr [[I6]], align 8
1188 ; BASIC-NEXT: [[I8:%.*]] = getelementptr inbounds i64, ptr [[I7]], i64 [[I3]]
1189 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I8]], i64 8), "nonnull"(ptr [[I7]]), "align"(ptr [[I7]], i64 8) ]
1190 ; BASIC-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1191 ; BASIC-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1192 ; BASIC-NEXT: [[I10:%.*]] = load ptr, ptr [[ARG]], align 8
1193 ; BASIC-NEXT: [[I11:%.*]] = load i32, ptr [[I10]], align 4
1194 ; BASIC-NEXT: ret i32 [[I11]]
1196 ; ALL-LABEL: define {{[^@]+}}@test7
1197 ; ALL-SAME: (ptr nonnull [[ARG:%.*]], i32 [[ARG1:%.*]]) {
1199 ; ALL-NEXT: [[I:%.*]] = sext i32 [[ARG1]] to i64
1200 ; ALL-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[ARG]], i64 0, i32 3
1201 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 280), "align"(ptr [[ARG]], i64 16) ]
1202 ; ALL-NEXT: [[I3:%.*]] = load i64, ptr [[I2]], align 8
1203 ; ALL-NEXT: [[I4:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 2, i64 [[I]], i64 [[I3]], i32 0
1204 ; ALL-NEXT: [[I5:%.*]] = load i64, ptr [[I4]], align 32
1205 ; ALL-NEXT: [[I6:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 1
1206 ; ALL-NEXT: [[I7:%.*]] = load ptr, ptr [[I6]], align 8
1207 ; ALL-NEXT: [[I8:%.*]] = getelementptr inbounds i64, ptr [[I7]], i64 [[I3]]
1208 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I8]], i64 8), "nonnull"(ptr [[I7]]), "align"(ptr [[I7]], i64 8) ]
1209 ; ALL-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1210 ; ALL-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1211 ; ALL-NEXT: [[I10:%.*]] = load ptr, ptr [[ARG]], align 8
1212 ; ALL-NEXT: [[I11:%.*]] = load i32, ptr [[I10]], align 4
1213 ; ALL-NEXT: ret i32 [[I11]]
1215 ; WITH-AC-LABEL: define {{[^@]+}}@test7
1216 ; WITH-AC-SAME: (ptr nonnull [[ARG:%.*]], i32 [[ARG1:%.*]]) {
1218 ; WITH-AC-NEXT: [[I:%.*]] = sext i32 [[ARG1]] to i64
1219 ; WITH-AC-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[ARG]], i64 0, i32 3
1220 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 280), "align"(ptr [[ARG]], i64 16) ]
1221 ; WITH-AC-NEXT: [[I3:%.*]] = load i64, ptr [[I2]], align 8
1222 ; WITH-AC-NEXT: [[I4:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 2, i64 [[I]], i64 [[I3]], i32 0
1223 ; WITH-AC-NEXT: [[I5:%.*]] = load i64, ptr [[I4]], align 32
1224 ; WITH-AC-NEXT: [[I6:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 1
1225 ; WITH-AC-NEXT: [[I7:%.*]] = load ptr, ptr [[I6]], align 8
1226 ; WITH-AC-NEXT: [[I8:%.*]] = getelementptr inbounds i64, ptr [[I7]], i64 [[I3]]
1227 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I8]], i64 8), "nonnull"(ptr [[I7]]), "align"(ptr [[I7]], i64 8) ]
1228 ; WITH-AC-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1229 ; WITH-AC-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1230 ; WITH-AC-NEXT: [[I10:%.*]] = load ptr, ptr [[ARG]], align 8
1231 ; WITH-AC-NEXT: [[I11:%.*]] = load i32, ptr [[I10]], align 4
1232 ; WITH-AC-NEXT: ret i32 [[I11]]
1234 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test7
1235 ; CROSS-BLOCK-SAME: (ptr nonnull [[ARG:%.*]], i32 [[ARG1:%.*]]) {
1236 ; CROSS-BLOCK-NEXT: bb:
1237 ; CROSS-BLOCK-NEXT: [[I:%.*]] = sext i32 [[ARG1]] to i64
1238 ; CROSS-BLOCK-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[ARG]], i64 0, i32 3
1239 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG]], i64 280), "align"(ptr [[ARG]], i64 16) ]
1240 ; CROSS-BLOCK-NEXT: [[I3:%.*]] = load i64, ptr [[I2]], align 8
1241 ; CROSS-BLOCK-NEXT: [[I4:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 2, i64 [[I]], i64 [[I3]], i32 0
1242 ; CROSS-BLOCK-NEXT: [[I5:%.*]] = load i64, ptr [[I4]], align 32
1243 ; CROSS-BLOCK-NEXT: [[I6:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 1
1244 ; CROSS-BLOCK-NEXT: [[I7:%.*]] = load ptr, ptr [[I6]], align 8
1245 ; CROSS-BLOCK-NEXT: [[I8:%.*]] = getelementptr inbounds i64, ptr [[I7]], i64 [[I3]]
1246 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I8]], i64 8), "nonnull"(ptr [[I7]]), "align"(ptr [[I7]], i64 8) ]
1247 ; CROSS-BLOCK-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1248 ; CROSS-BLOCK-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1249 ; CROSS-BLOCK-NEXT: [[I10:%.*]] = load ptr, ptr [[ARG]], align 8
1250 ; CROSS-BLOCK-NEXT: [[I11:%.*]] = load i32, ptr [[I10]], align 4
1251 ; CROSS-BLOCK-NEXT: ret i32 [[I11]]
1253 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test7
1254 ; FULL-SIMPLIFY-SAME: (ptr nonnull align 16 dereferenceable(280) [[ARG:%.*]], i32 [[ARG1:%.*]]) {
1255 ; FULL-SIMPLIFY-NEXT: bb:
1256 ; FULL-SIMPLIFY-NEXT: [[I:%.*]] = sext i32 [[ARG1]] to i64
1257 ; FULL-SIMPLIFY-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[ARG]], i64 0, i32 3
1258 ; FULL-SIMPLIFY-NEXT: [[I3:%.*]] = load i64, ptr [[I2]], align 8
1259 ; FULL-SIMPLIFY-NEXT: [[I4:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 2, i64 [[I]], i64 [[I3]], i32 0
1260 ; FULL-SIMPLIFY-NEXT: [[I5:%.*]] = load i64, ptr [[I4]], align 32
1261 ; FULL-SIMPLIFY-NEXT: [[I6:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[ARG]], i64 0, i32 1
1262 ; FULL-SIMPLIFY-NEXT: [[I7:%.*]] = load ptr, ptr [[I6]], align 8
1263 ; FULL-SIMPLIFY-NEXT: [[I8:%.*]] = getelementptr inbounds i64, ptr [[I7]], i64 [[I3]]
1264 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[I8]], i64 8), "nonnull"(ptr [[I7]]), "align"(ptr [[I7]], i64 8) ]
1265 ; FULL-SIMPLIFY-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1266 ; FULL-SIMPLIFY-NEXT: store i64 [[I5]], ptr [[I8]], align 8
1267 ; FULL-SIMPLIFY-NEXT: [[I10:%.*]] = load ptr, ptr [[ARG]], align 8
1268 ; FULL-SIMPLIFY-NEXT: [[I11:%.*]] = load i32, ptr [[I10]], align 4
1269 ; FULL-SIMPLIFY-NEXT: ret i32 [[I11]]
1272 %i = sext i32 %arg1 to i64
1273 %i2 = getelementptr inbounds %struct.A, ptr %arg, i64 0, i32 3
1274 %i3 = load i64, ptr %i2, align 8
1275 %i4 = getelementptr inbounds %struct.A, ptr %arg, i64 0, i32 2, i64 %i, i64 %i3, i32 0
1276 %i5 = load i64, ptr %i4, align 32
1277 %i6 = getelementptr inbounds %struct.A, ptr %arg, i64 0, i32 1
1278 %i7 = load ptr, ptr %i6, align 8
1279 %i8 = getelementptr inbounds i64, ptr %i7, i64 %i3
1280 store i64 %i5, ptr %i8, align 8
1281 store i64 %i5, ptr %i8, align 8
1282 %i10 = load ptr, ptr %arg, align 8
1283 %i11 = load i32, ptr %i10, align 4
1287 attributes #0 = { cold nounwind willreturn }
1288 attributes #1 = { "no-jump-tables" }
1289 attributes #2 = { norecurse nounwind willreturn "less-precise-fpmad" "no-jump-tables" }
1290 attributes #3 = { nounwind }
1291 attributes #4 = { null_pointer_is_valid }
1292 attributes #5 = { cold }