1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt -assume-builder -verify --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=BASIC
3 ; RUN: opt -assume-builder -verify --enable-knowledge-retention --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
4 ; RUN: opt -enable-new-pm=0 -assumption-cache-tracker -assume-builder -verify --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=WITH-AC
5 ; RUN: opt -enable-new-pm=0 -domtree -assumption-cache-tracker -assume-builder -verify --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=CROSS-BLOCK,CROSS-BLOCK-OLDPM
6 ; RUN: opt -enable-new-pm=0 -assume-builder -domtree -assumption-cache-tracker -assume-simplify -verify --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=FULL-SIMPLIFY
8 ; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=BASIC
9 ; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
10 ; RUN: opt -passes='require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=WITH-AC
11 ; RUN: opt -passes='require<domtree>,require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=CROSS-BLOCK,CROSS-BLOCK-NEWMP
12 ; RUN: opt -passes='assume-builder,require<domtree>,require<assumptions>,assume-simplify,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=FULL-SIMPLIFY
14 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
16 declare void @func(i32*, i32*)
17 declare void @func_cold(i32*) cold willreturn nounwind
18 declare void @func_strbool(i32*) "no-jump-tables"
19 declare void @func_many(i32*) "no-jump-tables" nounwind "less-precise-fpmad" willreturn norecurse
20 declare void @func_argattr(i32* align 8, i32* nonnull) nounwind
21 declare void @func_argattr2(i32* noundef align 8, i32* noundef nonnull) nounwind
22 declare void @may_throw()
24 define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
25 ; BASIC-LABEL: define {{[^@]+}}@test
26 ; BASIC-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]]) {
27 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P]]), "dereferenceable"(i32* [[P]], i64 16) ]
28 ; BASIC-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
29 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12) ]
30 ; BASIC-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
31 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
32 ; BASIC-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) [[ATTR6:#.*]]
33 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
34 ; BASIC-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
35 ; BASIC-NEXT: call void @func(i32* [[P1]], i32* [[P]])
36 ; BASIC-NEXT: call void @func_strbool(i32* [[P1]])
37 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
38 ; BASIC-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
39 ; BASIC-NEXT: call void @func_many(i32* align 8 [[P1]])
40 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
41 ; BASIC-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
42 ; BASIC-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
43 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
44 ; BASIC-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
45 ; BASIC-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
46 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
47 ; BASIC-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
48 ; BASIC-NEXT: ret void
50 ; ALL-LABEL: define {{[^@]+}}@test
51 ; ALL-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]]) {
52 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P]]), "dereferenceable"(i32* [[P]], i64 16) ]
53 ; ALL-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
54 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12) ]
55 ; ALL-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
56 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "cold"(), "nounwind"(), "willreturn"() ]
57 ; ALL-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) [[ATTR6:#.*]]
58 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "cold"(), "nounwind"(), "willreturn"() ]
59 ; ALL-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
60 ; ALL-NEXT: call void @func(i32* [[P1]], i32* [[P]])
61 ; ALL-NEXT: call void @func_strbool(i32* [[P1]])
62 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
63 ; ALL-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
64 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "norecurse"(), "nounwind"(), "willreturn"() ]
65 ; ALL-NEXT: call void @func_many(i32* align 8 [[P1]])
66 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8), "norecurse"(), "nounwind"(), "willreturn"() ]
67 ; ALL-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
68 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nounwind"() ]
69 ; ALL-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
70 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]), "nounwind"() ]
71 ; ALL-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
72 ; ALL-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
73 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
74 ; ALL-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
77 ; WITH-AC-LABEL: define {{[^@]+}}@test
78 ; WITH-AC-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]]) {
79 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P]]), "dereferenceable"(i32* [[P]], i64 16) ]
80 ; WITH-AC-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
81 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12) ]
82 ; WITH-AC-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
83 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
84 ; WITH-AC-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) [[ATTR6:#.*]]
85 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
86 ; WITH-AC-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
87 ; WITH-AC-NEXT: call void @func(i32* [[P1]], i32* [[P]])
88 ; WITH-AC-NEXT: call void @func_strbool(i32* [[P1]])
89 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
90 ; WITH-AC-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
91 ; WITH-AC-NEXT: call void @func_many(i32* align 8 [[P1]])
92 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
93 ; WITH-AC-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
94 ; WITH-AC-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
95 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
96 ; WITH-AC-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
97 ; WITH-AC-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
98 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
99 ; WITH-AC-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
100 ; WITH-AC-NEXT: ret void
102 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test
103 ; CROSS-BLOCK-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]]) {
104 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P]]), "dereferenceable"(i32* [[P]], i64 16) ]
105 ; CROSS-BLOCK-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
106 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12) ]
107 ; CROSS-BLOCK-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
108 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
109 ; CROSS-BLOCK-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) [[ATTR6:#.*]]
110 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
111 ; CROSS-BLOCK-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
112 ; CROSS-BLOCK-NEXT: call void @func(i32* [[P1]], i32* [[P]])
113 ; CROSS-BLOCK-NEXT: call void @func_strbool(i32* [[P1]])
114 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
115 ; CROSS-BLOCK-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
116 ; CROSS-BLOCK-NEXT: call void @func_many(i32* align 8 [[P1]])
117 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
118 ; CROSS-BLOCK-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
119 ; CROSS-BLOCK-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
120 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
121 ; CROSS-BLOCK-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
122 ; CROSS-BLOCK-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
123 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
124 ; CROSS-BLOCK-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
125 ; CROSS-BLOCK-NEXT: ret void
127 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test
128 ; FULL-SIMPLIFY-SAME: (i32* nonnull dereferenceable(16) [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]]) {
129 ; FULL-SIMPLIFY-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
130 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12) ]
131 ; FULL-SIMPLIFY-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
132 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
133 ; FULL-SIMPLIFY-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) [[ATTR6:#.*]]
134 ; FULL-SIMPLIFY-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
135 ; FULL-SIMPLIFY-NEXT: call void @func(i32* [[P1]], i32* [[P]])
136 ; FULL-SIMPLIFY-NEXT: call void @func_strbool(i32* [[P1]])
137 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
138 ; FULL-SIMPLIFY-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
139 ; FULL-SIMPLIFY-NEXT: call void @func_many(i32* align 8 [[P1]])
140 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
141 ; FULL-SIMPLIFY-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
142 ; FULL-SIMPLIFY-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
143 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
144 ; FULL-SIMPLIFY-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
145 ; FULL-SIMPLIFY-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
146 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
147 ; FULL-SIMPLIFY-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
148 ; FULL-SIMPLIFY-NEXT: ret void
150 call void @func(i32* nonnull dereferenceable(16) %P, i32* null)
151 call void @func(i32* dereferenceable(12) %P1, i32* nonnull %P)
152 call void @func_cold(i32* dereferenceable(12) %P1) cold
153 call void @func_cold(i32* dereferenceable(12) %P1)
154 call void @func(i32* %P1, i32* %P)
155 call void @func_strbool(i32* %P1)
156 call void @func(i32* dereferenceable(32) %P, i32* dereferenceable(8) %P)
157 call void @func_many(i32* align 8 %P1)
158 call void @func_many(i32* align 8 noundef %P1)
159 call void @func_argattr(i32* %P2, i32* %P3)
160 call void @func_argattr2(i32* %P2, i32* %P3)
161 call void @func(i32* nonnull %P1, i32* nonnull %P)
162 call void @func(i32* nonnull noundef %P1, i32* nonnull noundef %P)
166 %struct.S = type { i32, i8, i32* }
168 define i32 @test2(%struct.S* %0, i32* %1, i8* %2) {
169 ; BASIC-LABEL: define {{[^@]+}}@test2
170 ; BASIC-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) {
171 ; BASIC-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
172 ; BASIC-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
173 ; BASIC-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
174 ; BASIC-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
175 ; BASIC-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
176 ; BASIC-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
177 ; BASIC-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
178 ; BASIC-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
179 ; BASIC-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
180 ; BASIC-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
181 ; BASIC-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
182 ; BASIC-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
183 ; BASIC-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
184 ; BASIC-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
185 ; BASIC-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
186 ; BASIC-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
187 ; BASIC-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
188 ; BASIC-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
189 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8) ]
190 ; BASIC-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
191 ; BASIC-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
192 ; BASIC-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
193 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4) ]
194 ; BASIC-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
195 ; BASIC-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
196 ; BASIC-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
197 ; BASIC-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
198 ; BASIC-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
199 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
200 ; BASIC-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
201 ; BASIC-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
202 ; BASIC-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
203 ; BASIC-NEXT: ret i32 [[TMP28]]
205 ; ALL-LABEL: define {{[^@]+}}@test2
206 ; ALL-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) {
207 ; ALL-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
208 ; ALL-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
209 ; ALL-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
210 ; ALL-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
211 ; ALL-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
212 ; ALL-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
213 ; ALL-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
214 ; ALL-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
215 ; ALL-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
216 ; ALL-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
217 ; ALL-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
218 ; ALL-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
219 ; ALL-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
220 ; ALL-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
221 ; ALL-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
222 ; ALL-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
223 ; ALL-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
224 ; ALL-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
225 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8) ]
226 ; ALL-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
227 ; ALL-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
228 ; ALL-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
229 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4) ]
230 ; ALL-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
231 ; ALL-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
232 ; ALL-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
233 ; ALL-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
234 ; ALL-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
235 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
236 ; ALL-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
237 ; ALL-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
238 ; ALL-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
239 ; ALL-NEXT: ret i32 [[TMP28]]
241 ; WITH-AC-LABEL: define {{[^@]+}}@test2
242 ; WITH-AC-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) {
243 ; WITH-AC-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
244 ; WITH-AC-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
245 ; WITH-AC-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
246 ; WITH-AC-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
247 ; WITH-AC-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
248 ; WITH-AC-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
249 ; WITH-AC-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
250 ; WITH-AC-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
251 ; WITH-AC-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
252 ; WITH-AC-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
253 ; WITH-AC-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
254 ; WITH-AC-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
255 ; WITH-AC-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
256 ; WITH-AC-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
257 ; WITH-AC-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
258 ; WITH-AC-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
259 ; WITH-AC-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
260 ; WITH-AC-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
261 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8) ]
262 ; WITH-AC-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
263 ; WITH-AC-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
264 ; WITH-AC-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
265 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4) ]
266 ; WITH-AC-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
267 ; WITH-AC-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
268 ; WITH-AC-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
269 ; WITH-AC-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
270 ; WITH-AC-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
271 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
272 ; WITH-AC-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
273 ; WITH-AC-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
274 ; WITH-AC-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
275 ; WITH-AC-NEXT: ret i32 [[TMP28]]
277 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test2
278 ; CROSS-BLOCK-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) {
279 ; CROSS-BLOCK-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
280 ; CROSS-BLOCK-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
281 ; CROSS-BLOCK-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
282 ; CROSS-BLOCK-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
283 ; CROSS-BLOCK-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
284 ; CROSS-BLOCK-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
285 ; CROSS-BLOCK-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
286 ; CROSS-BLOCK-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
287 ; CROSS-BLOCK-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
288 ; CROSS-BLOCK-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
289 ; CROSS-BLOCK-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
290 ; CROSS-BLOCK-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
291 ; CROSS-BLOCK-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
292 ; CROSS-BLOCK-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
293 ; CROSS-BLOCK-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
294 ; CROSS-BLOCK-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
295 ; CROSS-BLOCK-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
296 ; CROSS-BLOCK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
297 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8) ]
298 ; CROSS-BLOCK-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
299 ; CROSS-BLOCK-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
300 ; CROSS-BLOCK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
301 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4) ]
302 ; CROSS-BLOCK-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
303 ; CROSS-BLOCK-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
304 ; CROSS-BLOCK-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
305 ; CROSS-BLOCK-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
306 ; CROSS-BLOCK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
307 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
308 ; CROSS-BLOCK-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
309 ; CROSS-BLOCK-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
310 ; CROSS-BLOCK-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
311 ; CROSS-BLOCK-NEXT: ret i32 [[TMP28]]
313 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test2
314 ; FULL-SIMPLIFY-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) {
315 ; FULL-SIMPLIFY-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
316 ; FULL-SIMPLIFY-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
317 ; FULL-SIMPLIFY-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
318 ; FULL-SIMPLIFY-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
319 ; FULL-SIMPLIFY-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
320 ; FULL-SIMPLIFY-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
321 ; FULL-SIMPLIFY-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
322 ; FULL-SIMPLIFY-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
323 ; FULL-SIMPLIFY-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
324 ; FULL-SIMPLIFY-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
325 ; FULL-SIMPLIFY-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
326 ; FULL-SIMPLIFY-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
327 ; FULL-SIMPLIFY-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
328 ; FULL-SIMPLIFY-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
329 ; FULL-SIMPLIFY-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
330 ; FULL-SIMPLIFY-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
331 ; FULL-SIMPLIFY-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
332 ; FULL-SIMPLIFY-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
333 ; FULL-SIMPLIFY-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
334 ; FULL-SIMPLIFY-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
335 ; FULL-SIMPLIFY-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
336 ; FULL-SIMPLIFY-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
337 ; FULL-SIMPLIFY-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
338 ; FULL-SIMPLIFY-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
339 ; FULL-SIMPLIFY-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
340 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8), "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4), "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
341 ; FULL-SIMPLIFY-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
342 ; FULL-SIMPLIFY-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
343 ; FULL-SIMPLIFY-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
344 ; FULL-SIMPLIFY-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
345 ; FULL-SIMPLIFY-NEXT: ret i32 [[TMP28]]
347 %4 = alloca %struct.S*, align 8
348 %5 = alloca i32*, align 8
349 %6 = alloca i8*, align 8
350 %7 = alloca %struct.S, align 8
351 store %struct.S* %0, %struct.S** %4, align 8
352 store i32* %1, i32** %5, align 8
353 store i8* %2, i8** %6
354 %8 = load i32*, i32** %5, align 8
355 %9 = load i32, i32* %8, align 4
356 %10 = trunc i32 %9 to i8
357 %11 = load i8*, i8** %6, align 8
358 store i8 %10, i8* %11, align 1
359 %12 = bitcast %struct.S* %7 to i8*
360 %13 = load %struct.S*, %struct.S** %4
361 %14 = bitcast %struct.S* %13 to i8*
362 %15 = bitcast %struct.S* %7 to i8*
363 %16 = load %struct.S*, %struct.S** %4, align 8
364 %17 = getelementptr inbounds %struct.S, %struct.S* %16, i32 0, i32 0
365 %18 = load i32, i32* %17, align 8
366 %19 = load %struct.S*, %struct.S** %4, align 8
367 %20 = getelementptr inbounds %struct.S, %struct.S* %19, i32 0, i32 1
368 %21 = load i8, i8* %20, align 4
369 %22 = sext i8 %21 to i32
370 %23 = add nsw i32 %18, %22
371 %24 = load %struct.S*, %struct.S** %4, align 8
372 %25 = getelementptr inbounds %struct.S, %struct.S* %24, i32 0, i32 2
373 %26 = load i32*, i32** %25, align 8
374 %27 = load i32, i32* %26, align 4
375 %28 = add nsw i32 %23, %27
379 define i32 @test3(%struct.S* %0, i32* %1, i8* %2) "null-pointer-is-valid"="true" {
380 ; BASIC-LABEL: define {{[^@]+}}@test3
381 ; BASIC-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) [[ATTR4:#.*]] {
382 ; BASIC-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
383 ; BASIC-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
384 ; BASIC-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
385 ; BASIC-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
386 ; BASIC-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
387 ; BASIC-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
388 ; BASIC-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
389 ; BASIC-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
390 ; BASIC-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
391 ; BASIC-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
392 ; BASIC-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
393 ; BASIC-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
394 ; BASIC-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
395 ; BASIC-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
396 ; BASIC-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
397 ; BASIC-NEXT: call void @may_throw()
398 ; BASIC-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
399 ; BASIC-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
400 ; BASIC-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
401 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8) ]
402 ; BASIC-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
403 ; BASIC-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
404 ; BASIC-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
405 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4) ]
406 ; BASIC-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 8
407 ; BASIC-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
408 ; BASIC-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
409 ; BASIC-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
410 ; BASIC-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
411 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
412 ; BASIC-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
413 ; BASIC-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
414 ; BASIC-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
415 ; BASIC-NEXT: ret i32 [[TMP28]]
417 ; ALL-LABEL: define {{[^@]+}}@test3
418 ; ALL-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) [[ATTR4:#.*]] {
419 ; ALL-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
420 ; ALL-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
421 ; ALL-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
422 ; ALL-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
423 ; ALL-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
424 ; ALL-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
425 ; ALL-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
426 ; ALL-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
427 ; ALL-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
428 ; ALL-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
429 ; ALL-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
430 ; ALL-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
431 ; ALL-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
432 ; ALL-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
433 ; ALL-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
434 ; ALL-NEXT: call void @may_throw()
435 ; ALL-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
436 ; ALL-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
437 ; ALL-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
438 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8) ]
439 ; ALL-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
440 ; ALL-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
441 ; ALL-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
442 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4) ]
443 ; ALL-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 8
444 ; ALL-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
445 ; ALL-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
446 ; ALL-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
447 ; ALL-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
448 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
449 ; ALL-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
450 ; ALL-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
451 ; ALL-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
452 ; ALL-NEXT: ret i32 [[TMP28]]
454 ; WITH-AC-LABEL: define {{[^@]+}}@test3
455 ; WITH-AC-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) [[ATTR4:#.*]] {
456 ; WITH-AC-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
457 ; WITH-AC-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
458 ; WITH-AC-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
459 ; WITH-AC-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
460 ; WITH-AC-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
461 ; WITH-AC-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
462 ; WITH-AC-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
463 ; WITH-AC-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
464 ; WITH-AC-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
465 ; WITH-AC-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
466 ; WITH-AC-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
467 ; WITH-AC-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
468 ; WITH-AC-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
469 ; WITH-AC-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
470 ; WITH-AC-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
471 ; WITH-AC-NEXT: call void @may_throw()
472 ; WITH-AC-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
473 ; WITH-AC-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
474 ; WITH-AC-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
475 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8) ]
476 ; WITH-AC-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
477 ; WITH-AC-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
478 ; WITH-AC-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
479 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4) ]
480 ; WITH-AC-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 8
481 ; WITH-AC-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
482 ; WITH-AC-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
483 ; WITH-AC-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
484 ; WITH-AC-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
485 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
486 ; WITH-AC-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
487 ; WITH-AC-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
488 ; WITH-AC-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
489 ; WITH-AC-NEXT: ret i32 [[TMP28]]
491 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test3
492 ; CROSS-BLOCK-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) [[ATTR4:#.*]] {
493 ; CROSS-BLOCK-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
494 ; CROSS-BLOCK-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
495 ; CROSS-BLOCK-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
496 ; CROSS-BLOCK-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
497 ; CROSS-BLOCK-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
498 ; CROSS-BLOCK-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
499 ; CROSS-BLOCK-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
500 ; CROSS-BLOCK-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
501 ; CROSS-BLOCK-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
502 ; CROSS-BLOCK-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
503 ; CROSS-BLOCK-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
504 ; CROSS-BLOCK-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
505 ; CROSS-BLOCK-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
506 ; CROSS-BLOCK-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
507 ; CROSS-BLOCK-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
508 ; CROSS-BLOCK-NEXT: call void @may_throw()
509 ; CROSS-BLOCK-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
510 ; CROSS-BLOCK-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
511 ; CROSS-BLOCK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
512 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8) ]
513 ; CROSS-BLOCK-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
514 ; CROSS-BLOCK-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
515 ; CROSS-BLOCK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
516 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4) ]
517 ; CROSS-BLOCK-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 8
518 ; CROSS-BLOCK-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
519 ; CROSS-BLOCK-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
520 ; CROSS-BLOCK-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
521 ; CROSS-BLOCK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
522 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
523 ; CROSS-BLOCK-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
524 ; CROSS-BLOCK-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
525 ; CROSS-BLOCK-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
526 ; CROSS-BLOCK-NEXT: ret i32 [[TMP28]]
528 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test3
529 ; FULL-SIMPLIFY-SAME: (%struct.S* [[TMP0:%.*]], i32* [[TMP1:%.*]], i8* [[TMP2:%.*]]) [[ATTR4:#.*]] {
530 ; FULL-SIMPLIFY-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
531 ; FULL-SIMPLIFY-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
532 ; FULL-SIMPLIFY-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
533 ; FULL-SIMPLIFY-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
534 ; FULL-SIMPLIFY-NEXT: store %struct.S* [[TMP0]], %struct.S** [[TMP4]], align 8
535 ; FULL-SIMPLIFY-NEXT: store i32* [[TMP1]], i32** [[TMP5]], align 8
536 ; FULL-SIMPLIFY-NEXT: store i8* [[TMP2]], i8** [[TMP6]], align 8
537 ; FULL-SIMPLIFY-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
538 ; FULL-SIMPLIFY-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
539 ; FULL-SIMPLIFY-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
540 ; FULL-SIMPLIFY-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
541 ; FULL-SIMPLIFY-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
542 ; FULL-SIMPLIFY-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
543 ; FULL-SIMPLIFY-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
544 ; FULL-SIMPLIFY-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
545 ; FULL-SIMPLIFY-NEXT: call void @may_throw()
546 ; FULL-SIMPLIFY-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
547 ; FULL-SIMPLIFY-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
548 ; FULL-SIMPLIFY-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
549 ; FULL-SIMPLIFY-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
550 ; FULL-SIMPLIFY-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
551 ; FULL-SIMPLIFY-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
552 ; FULL-SIMPLIFY-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 8
553 ; FULL-SIMPLIFY-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
554 ; FULL-SIMPLIFY-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
555 ; FULL-SIMPLIFY-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
556 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.S* [[TMP16]], i64 4), "nonnull"(%struct.S* [[TMP16]]), "align"(%struct.S* [[TMP16]], i64 8), "dereferenceable"(%struct.S* [[TMP19]], i64 5), "nonnull"(%struct.S* [[TMP19]]), "align"(%struct.S* [[TMP19]], i64 4), "dereferenceable"(%struct.S* [[TMP24]], i64 16), "nonnull"(%struct.S* [[TMP24]]), "align"(%struct.S* [[TMP24]], i64 8) ]
557 ; FULL-SIMPLIFY-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
558 ; FULL-SIMPLIFY-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
559 ; FULL-SIMPLIFY-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
560 ; FULL-SIMPLIFY-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
561 ; FULL-SIMPLIFY-NEXT: ret i32 [[TMP28]]
563 %4 = alloca %struct.S*, align 8
564 %5 = alloca i32*, align 8
565 %6 = alloca i8*, align 8
566 %7 = alloca %struct.S, align 8
567 store %struct.S* %0, %struct.S** %4, align 8
568 store i32* %1, i32** %5, align 8
569 store i8* %2, i8** %6, align 8
570 %8 = load i32*, i32** %5, align 8
571 %9 = load i32, i32* %8, align 4
572 %10 = trunc i32 %9 to i8
573 %11 = load i8*, i8** %6
574 store i8 %10, i8* %11, align 1
575 %12 = bitcast %struct.S* %7 to i8*
576 %13 = load %struct.S*, %struct.S** %4, align 32
577 %14 = bitcast %struct.S* %13 to i8*
578 call void @may_throw()
579 %15 = bitcast %struct.S* %7 to i8*
580 %16 = load %struct.S*, %struct.S** %4, align 8
581 %17 = getelementptr inbounds %struct.S, %struct.S* %16, i32 0, i32 0
582 %18 = load i32, i32* %17, align 8
583 %19 = load %struct.S*, %struct.S** %4, align 8
584 %20 = getelementptr inbounds %struct.S, %struct.S* %19, i32 0, i32 1
585 %21 = load i8, i8* %20, align 8
586 %22 = sext i8 %21 to i32
587 %23 = add nsw i32 %18, %22
588 %24 = load %struct.S*, %struct.S** %4, align 8
589 %25 = getelementptr inbounds %struct.S, %struct.S* %24, i32 0, i32 2
590 %26 = load i32*, i32** %25
591 %27 = load i32, i32* %26, align 4
592 %28 = add nsw i32 %23, %27
596 define dso_local i32 @_Z6squarePi(i32* %P, i32* %P1, i1 %cond) {
597 ; BASIC-LABEL: define {{[^@]+}}@_Z6squarePi
598 ; BASIC-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i1 [[COND:%.*]]) {
599 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
600 ; BASIC-NEXT: store i32 0, i32* [[P]], align 4
601 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
602 ; BASIC-NEXT: store i32 0, i32* [[P1]], align 8
603 ; BASIC-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
605 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
606 ; BASIC-NEXT: store i32 0, i32* [[P]], align 8
607 ; BASIC-NEXT: store i32 0, i32* [[P1]], align 4
608 ; BASIC-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
610 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 8) ]
611 ; BASIC-NEXT: store i32 0, i32* [[P]], align 8
612 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
613 ; BASIC-NEXT: store i32 0, i32* [[P1]], align 8
614 ; BASIC-NEXT: br label [[C]]
616 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 32) ]
617 ; BASIC-NEXT: store i32 0, i32* [[P]], align 32
618 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 4) ]
619 ; BASIC-NEXT: store i32 0, i32* [[P1]], align 4
620 ; BASIC-NEXT: ret i32 0
622 ; ALL-LABEL: define {{[^@]+}}@_Z6squarePi
623 ; ALL-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i1 [[COND:%.*]]) {
624 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
625 ; ALL-NEXT: store i32 0, i32* [[P]], align 4
626 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
627 ; ALL-NEXT: store i32 0, i32* [[P1]], align 8
628 ; ALL-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
630 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
631 ; ALL-NEXT: store i32 0, i32* [[P]], align 8
632 ; ALL-NEXT: store i32 0, i32* [[P1]], align 4
633 ; ALL-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
635 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 8) ]
636 ; ALL-NEXT: store i32 0, i32* [[P]], align 8
637 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
638 ; ALL-NEXT: store i32 0, i32* [[P1]], align 8
639 ; ALL-NEXT: br label [[C]]
641 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 32) ]
642 ; ALL-NEXT: store i32 0, i32* [[P]], align 32
643 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 4) ]
644 ; ALL-NEXT: store i32 0, i32* [[P1]], align 4
645 ; ALL-NEXT: ret i32 0
647 ; WITH-AC-LABEL: define {{[^@]+}}@_Z6squarePi
648 ; WITH-AC-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i1 [[COND:%.*]]) {
649 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
650 ; WITH-AC-NEXT: store i32 0, i32* [[P]], align 4
651 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
652 ; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 8
653 ; WITH-AC-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
655 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
656 ; WITH-AC-NEXT: store i32 0, i32* [[P]], align 8
657 ; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 4
658 ; WITH-AC-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
660 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 8) ]
661 ; WITH-AC-NEXT: store i32 0, i32* [[P]], align 8
662 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
663 ; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 8
664 ; WITH-AC-NEXT: br label [[C]]
666 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 32) ]
667 ; WITH-AC-NEXT: store i32 0, i32* [[P]], align 32
668 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 4) ]
669 ; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 4
670 ; WITH-AC-NEXT: ret i32 0
672 ; CROSS-BLOCK-OLDPM-LABEL: define {{[^@]+}}@_Z6squarePi
673 ; CROSS-BLOCK-OLDPM-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i1 [[COND:%.*]]) {
674 ; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
675 ; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P]], align 4
676 ; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
677 ; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P1]], align 8
678 ; CROSS-BLOCK-OLDPM-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
679 ; CROSS-BLOCK-OLDPM: A:
680 ; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
681 ; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P]], align 8
682 ; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P1]], align 4
683 ; CROSS-BLOCK-OLDPM-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
684 ; CROSS-BLOCK-OLDPM: B:
685 ; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 8) ]
686 ; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P]], align 8
687 ; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
688 ; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P1]], align 8
689 ; CROSS-BLOCK-OLDPM-NEXT: br label [[C]]
690 ; CROSS-BLOCK-OLDPM: C:
691 ; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 32) ]
692 ; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P]], align 32
693 ; CROSS-BLOCK-OLDPM-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 4) ]
694 ; CROSS-BLOCK-OLDPM-NEXT: store i32 0, i32* [[P1]], align 4
695 ; CROSS-BLOCK-OLDPM-NEXT: ret i32 0
697 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@_Z6squarePi
698 ; FULL-SIMPLIFY-SAME: (i32* nonnull align 4 dereferenceable(4) [[P:%.*]], i32* nonnull align 8 dereferenceable(4) [[P1:%.*]], i1 [[COND:%.*]]) {
699 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P]], align 4
700 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P1]], align 8
701 ; FULL-SIMPLIFY-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
703 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
704 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P]], align 8
705 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P1]], align 4
706 ; FULL-SIMPLIFY-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
708 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "ignore"(i32* undef, i64 4), "ignore"(i32* undef), "align"(i32* [[P]], i64 8) ]
709 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P]], align 8
710 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P1]], align 8
711 ; FULL-SIMPLIFY-NEXT: br label [[C]]
713 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "ignore"(i32* undef, i64 4), "ignore"(i32* undef), "align"(i32* [[P]], i64 32) ]
714 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P]], align 32
715 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[P1]], align 4
716 ; FULL-SIMPLIFY-NEXT: ret i32 0
718 ; CROSS-BLOCK-NEWMP-LABEL: define {{[^@]+}}@_Z6squarePi
719 ; CROSS-BLOCK-NEWMP-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i1 [[COND:%.*]]) {
720 ; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
721 ; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P]], align 4
722 ; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
723 ; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P1]], align 8
724 ; CROSS-BLOCK-NEWMP-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
725 ; CROSS-BLOCK-NEWMP: A:
726 ; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
727 ; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P]], align 8
728 ; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P1]], align 4
729 ; CROSS-BLOCK-NEWMP-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
730 ; CROSS-BLOCK-NEWMP: B:
731 ; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
732 ; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P]], align 8
733 ; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P1]], align 8
734 ; CROSS-BLOCK-NEWMP-NEXT: br label [[C]]
735 ; CROSS-BLOCK-NEWMP: C:
736 ; CROSS-BLOCK-NEWMP-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 32) ]
737 ; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P]], align 32
738 ; CROSS-BLOCK-NEWMP-NEXT: store i32 0, i32* [[P1]], align 4
739 ; CROSS-BLOCK-NEWMP-NEXT: ret i32 0
741 store i32 0, i32* %P, align 4
742 store i32 0, i32* %P1, align 8
743 br i1 %cond, label %A, label %B
745 store i32 0, i32* %P, align 8
746 store i32 0, i32* %P1, align 4
747 br i1 %cond, label %C, label %B
749 store i32 0, i32* %P, align 8
750 store i32 0, i32* %P1, align 8
753 store i32 0, i32* %P, align 32
754 store i32 0, i32* %P1, align 4
758 define dso_local i32 @test4A(i32* %0, i32* %1, i32 %2, i32 %3) {
759 ; BASIC-LABEL: define {{[^@]+}}@test4A
760 ; BASIC-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
761 ; BASIC-NEXT: [[TMP5:%.*]] = icmp ne i32* [[TMP1]], null
762 ; BASIC-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]]
764 ; BASIC-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP3]], [[TMP2]]
765 ; BASIC-NEXT: call void @may_throw()
766 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP0]], i64 4), "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4) ]
767 ; BASIC-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP0]], align 4
768 ; BASIC-NEXT: [[TMP9:%.*]] = add nsw i32 [[TMP7]], [[TMP8]]
769 ; BASIC-NEXT: store i32 0, i32* [[TMP0]], align 4
770 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP1]], i64 4), "nonnull"(i32* [[TMP1]]), "align"(i32* [[TMP1]], i64 4) ]
771 ; BASIC-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP1]], align 4
772 ; BASIC-NEXT: [[TMP11:%.*]] = add nsw i32 [[TMP9]], [[TMP10]]
773 ; BASIC-NEXT: call void @may_throw()
774 ; BASIC-NEXT: store i32 [[TMP11]], i32* [[TMP1]], align 4
775 ; BASIC-NEXT: br label [[TMP12]]
777 ; BASIC-NEXT: ret i32 0
779 ; ALL-LABEL: define {{[^@]+}}@test4A
780 ; ALL-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
781 ; ALL-NEXT: [[TMP5:%.*]] = icmp ne i32* [[TMP1]], null
782 ; ALL-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]]
784 ; ALL-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP3]], [[TMP2]]
785 ; ALL-NEXT: call void @may_throw()
786 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP0]], i64 4), "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4) ]
787 ; ALL-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP0]], align 4
788 ; ALL-NEXT: [[TMP9:%.*]] = add nsw i32 [[TMP7]], [[TMP8]]
789 ; ALL-NEXT: store i32 0, i32* [[TMP0]], align 4
790 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP1]], i64 4), "nonnull"(i32* [[TMP1]]), "align"(i32* [[TMP1]], i64 4) ]
791 ; ALL-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP1]], align 4
792 ; ALL-NEXT: [[TMP11:%.*]] = add nsw i32 [[TMP9]], [[TMP10]]
793 ; ALL-NEXT: call void @may_throw()
794 ; ALL-NEXT: store i32 [[TMP11]], i32* [[TMP1]], align 4
795 ; ALL-NEXT: br label [[TMP12]]
797 ; ALL-NEXT: ret i32 0
799 ; WITH-AC-LABEL: define {{[^@]+}}@test4A
800 ; WITH-AC-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
801 ; WITH-AC-NEXT: [[TMP5:%.*]] = icmp ne i32* [[TMP1]], null
802 ; WITH-AC-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]]
804 ; WITH-AC-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP3]], [[TMP2]]
805 ; WITH-AC-NEXT: call void @may_throw()
806 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP0]], i64 4), "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4) ]
807 ; WITH-AC-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP0]], align 4
808 ; WITH-AC-NEXT: [[TMP9:%.*]] = add nsw i32 [[TMP7]], [[TMP8]]
809 ; WITH-AC-NEXT: store i32 0, i32* [[TMP0]], align 4
810 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP1]], i64 4), "nonnull"(i32* [[TMP1]]), "align"(i32* [[TMP1]], i64 4) ]
811 ; WITH-AC-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP1]], align 4
812 ; WITH-AC-NEXT: [[TMP11:%.*]] = add nsw i32 [[TMP9]], [[TMP10]]
813 ; WITH-AC-NEXT: call void @may_throw()
814 ; WITH-AC-NEXT: store i32 [[TMP11]], i32* [[TMP1]], align 4
815 ; WITH-AC-NEXT: br label [[TMP12]]
817 ; WITH-AC-NEXT: ret i32 0
819 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test4A
820 ; CROSS-BLOCK-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
821 ; CROSS-BLOCK-NEXT: [[TMP5:%.*]] = icmp ne i32* [[TMP1]], null
822 ; CROSS-BLOCK-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]]
824 ; CROSS-BLOCK-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP3]], [[TMP2]]
825 ; CROSS-BLOCK-NEXT: call void @may_throw()
826 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP0]], i64 4), "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4) ]
827 ; CROSS-BLOCK-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP0]], align 4
828 ; CROSS-BLOCK-NEXT: [[TMP9:%.*]] = add nsw i32 [[TMP7]], [[TMP8]]
829 ; CROSS-BLOCK-NEXT: store i32 0, i32* [[TMP0]], align 4
830 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP1]], i64 4), "nonnull"(i32* [[TMP1]]), "align"(i32* [[TMP1]], i64 4) ]
831 ; CROSS-BLOCK-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP1]], align 4
832 ; CROSS-BLOCK-NEXT: [[TMP11:%.*]] = add nsw i32 [[TMP9]], [[TMP10]]
833 ; CROSS-BLOCK-NEXT: call void @may_throw()
834 ; CROSS-BLOCK-NEXT: store i32 [[TMP11]], i32* [[TMP1]], align 4
835 ; CROSS-BLOCK-NEXT: br label [[TMP12]]
837 ; CROSS-BLOCK-NEXT: ret i32 0
839 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test4A
840 ; FULL-SIMPLIFY-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
841 ; FULL-SIMPLIFY-NEXT: [[TMP5:%.*]] = icmp ne i32* [[TMP1]], null
842 ; FULL-SIMPLIFY-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]]
844 ; FULL-SIMPLIFY-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP3]], [[TMP2]]
845 ; FULL-SIMPLIFY-NEXT: call void @may_throw()
846 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP0]], i64 4), "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4), "dereferenceable"(i32* [[TMP1]], i64 4), "nonnull"(i32* [[TMP1]]), "align"(i32* [[TMP1]], i64 4) ]
847 ; FULL-SIMPLIFY-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP0]], align 4
848 ; FULL-SIMPLIFY-NEXT: [[TMP9:%.*]] = add nsw i32 [[TMP7]], [[TMP8]]
849 ; FULL-SIMPLIFY-NEXT: store i32 0, i32* [[TMP0]], align 4
850 ; FULL-SIMPLIFY-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP1]], align 4
851 ; FULL-SIMPLIFY-NEXT: [[TMP11:%.*]] = add nsw i32 [[TMP9]], [[TMP10]]
852 ; FULL-SIMPLIFY-NEXT: call void @may_throw()
853 ; FULL-SIMPLIFY-NEXT: store i32 [[TMP11]], i32* [[TMP1]], align 4
854 ; FULL-SIMPLIFY-NEXT: br label [[TMP12]]
856 ; FULL-SIMPLIFY-NEXT: ret i32 0
858 %5 = icmp ne i32* %1, null
859 br i1 %5, label %6, label %12
862 %7 = add nsw i32 %3, %2
863 call void @may_throw()
864 %8 = load i32, i32* %0, align 4
865 %9 = add nsw i32 %7, %8
866 store i32 0, i32* %0, align 4
867 %10 = load i32, i32* %1, align 4
868 %11 = add nsw i32 %9, %10
869 call void @may_throw()
870 store i32 %11, i32* %1, align 4
877 declare void @may_throwv2(i32* %P)
879 define dso_local i32 @terminator(i32* %P) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
880 ; BASIC-LABEL: define {{[^@]+}}@terminator
881 ; BASIC-SAME: (i32* [[P:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
882 ; BASIC-NEXT: invoke void @may_throwv2(i32* nonnull [[P]])
883 ; BASIC-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
885 ; BASIC-NEXT: [[V:%.*]] = landingpad { i8*, i32 }
886 ; BASIC-NEXT: catch i8* null
887 ; BASIC-NEXT: br label [[EXIT]]
889 ; BASIC-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
890 ; BASIC-NEXT: ret i32 [[DOT0]]
892 ; ALL-LABEL: define {{[^@]+}}@terminator
893 ; ALL-SAME: (i32* [[P:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
894 ; ALL-NEXT: invoke void @may_throwv2(i32* nonnull [[P]])
895 ; ALL-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
897 ; ALL-NEXT: [[V:%.*]] = landingpad { i8*, i32 }
898 ; ALL-NEXT: catch i8* null
899 ; ALL-NEXT: br label [[EXIT]]
901 ; ALL-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
902 ; ALL-NEXT: ret i32 [[DOT0]]
904 ; WITH-AC-LABEL: define {{[^@]+}}@terminator
905 ; WITH-AC-SAME: (i32* [[P:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
906 ; WITH-AC-NEXT: invoke void @may_throwv2(i32* nonnull [[P]])
907 ; WITH-AC-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
909 ; WITH-AC-NEXT: [[V:%.*]] = landingpad { i8*, i32 }
910 ; WITH-AC-NEXT: catch i8* null
911 ; WITH-AC-NEXT: br label [[EXIT]]
913 ; WITH-AC-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
914 ; WITH-AC-NEXT: ret i32 [[DOT0]]
916 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@terminator
917 ; CROSS-BLOCK-SAME: (i32* [[P:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
918 ; CROSS-BLOCK-NEXT: invoke void @may_throwv2(i32* nonnull [[P]])
919 ; CROSS-BLOCK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
920 ; CROSS-BLOCK: Catch:
921 ; CROSS-BLOCK-NEXT: [[V:%.*]] = landingpad { i8*, i32 }
922 ; CROSS-BLOCK-NEXT: catch i8* null
923 ; CROSS-BLOCK-NEXT: br label [[EXIT]]
925 ; CROSS-BLOCK-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
926 ; CROSS-BLOCK-NEXT: ret i32 [[DOT0]]
928 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@terminator
929 ; FULL-SIMPLIFY-SAME: (i32* [[P:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
930 ; FULL-SIMPLIFY-NEXT: invoke void @may_throwv2(i32* nonnull [[P]])
931 ; FULL-SIMPLIFY-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH:%.*]]
932 ; FULL-SIMPLIFY: Catch:
933 ; FULL-SIMPLIFY-NEXT: [[V:%.*]] = landingpad { i8*, i32 }
934 ; FULL-SIMPLIFY-NEXT: catch i8* null
935 ; FULL-SIMPLIFY-NEXT: br label [[EXIT]]
936 ; FULL-SIMPLIFY: Exit:
937 ; FULL-SIMPLIFY-NEXT: [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
938 ; FULL-SIMPLIFY-NEXT: ret i32 [[DOT0]]
940 invoke void @may_throwv2(i32* nonnull %P)
941 to label %Exit unwind label %Catch
944 %v = landingpad { i8*, i32 }
948 Exit: ; preds = %7, %5
949 %.0 = phi i32 [ 1, %0 ], [ 0, %Catch ]
953 declare dso_local i32 @__gxx_personality_v0(...)
955 define dso_local i32 @test5(i8* %0, i32 %1) {
956 ; BASIC-LABEL: define {{[^@]+}}@test5
957 ; BASIC-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
958 ; BASIC-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP0]] to i64*
959 ; BASIC-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP0]] to i16*
960 ; BASIC-NEXT: [[TMP5:%.*]] = sext i32 [[TMP1]] to i64
961 ; BASIC-NEXT: [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP4]], i64 [[TMP5]]
962 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i16* [[TMP6]], i64 2), "nonnull"(i8* [[TMP0]]), "align"(i8* [[TMP0]], i64 8) ]
963 ; BASIC-NEXT: [[TMP7:%.*]] = load i16, i16* [[TMP6]], align 2
964 ; BASIC-NEXT: [[A:%.*]] = load i16, i16* [[TMP6]], align 4
965 ; BASIC-NEXT: [[TMP8:%.*]] = sext i16 [[TMP7]] to i64
966 ; BASIC-NEXT: [[TMP9:%.*]] = getelementptr inbounds i64, i64* [[TMP3]], i64 [[TMP8]]
967 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP9]], i64 8) ]
968 ; BASIC-NEXT: [[TMP10:%.*]] = load i64, i64* [[TMP9]], align 16
969 ; BASIC-NEXT: [[B:%.*]] = load i64, i64* [[TMP9]], align 32
970 ; BASIC-NEXT: [[TMP11:%.*]] = trunc i64 [[TMP10]] to i32
971 ; BASIC-NEXT: ret i32 [[TMP11]]
973 ; ALL-LABEL: define {{[^@]+}}@test5
974 ; ALL-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
975 ; ALL-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP0]] to i64*
976 ; ALL-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP0]] to i16*
977 ; ALL-NEXT: [[TMP5:%.*]] = sext i32 [[TMP1]] to i64
978 ; ALL-NEXT: [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP4]], i64 [[TMP5]]
979 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i16* [[TMP6]], i64 2), "nonnull"(i8* [[TMP0]]), "align"(i8* [[TMP0]], i64 8) ]
980 ; ALL-NEXT: [[TMP7:%.*]] = load i16, i16* [[TMP6]], align 2
981 ; ALL-NEXT: [[A:%.*]] = load i16, i16* [[TMP6]], align 4
982 ; ALL-NEXT: [[TMP8:%.*]] = sext i16 [[TMP7]] to i64
983 ; ALL-NEXT: [[TMP9:%.*]] = getelementptr inbounds i64, i64* [[TMP3]], i64 [[TMP8]]
984 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP9]], i64 8) ]
985 ; ALL-NEXT: [[TMP10:%.*]] = load i64, i64* [[TMP9]], align 16
986 ; ALL-NEXT: [[B:%.*]] = load i64, i64* [[TMP9]], align 32
987 ; ALL-NEXT: [[TMP11:%.*]] = trunc i64 [[TMP10]] to i32
988 ; ALL-NEXT: ret i32 [[TMP11]]
990 ; WITH-AC-LABEL: define {{[^@]+}}@test5
991 ; WITH-AC-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
992 ; WITH-AC-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP0]] to i64*
993 ; WITH-AC-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP0]] to i16*
994 ; WITH-AC-NEXT: [[TMP5:%.*]] = sext i32 [[TMP1]] to i64
995 ; WITH-AC-NEXT: [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP4]], i64 [[TMP5]]
996 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i16* [[TMP6]], i64 2), "nonnull"(i8* [[TMP0]]), "align"(i8* [[TMP0]], i64 8) ]
997 ; WITH-AC-NEXT: [[TMP7:%.*]] = load i16, i16* [[TMP6]], align 2
998 ; WITH-AC-NEXT: [[A:%.*]] = load i16, i16* [[TMP6]], align 4
999 ; WITH-AC-NEXT: [[TMP8:%.*]] = sext i16 [[TMP7]] to i64
1000 ; WITH-AC-NEXT: [[TMP9:%.*]] = getelementptr inbounds i64, i64* [[TMP3]], i64 [[TMP8]]
1001 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP9]], i64 8) ]
1002 ; WITH-AC-NEXT: [[TMP10:%.*]] = load i64, i64* [[TMP9]], align 16
1003 ; WITH-AC-NEXT: [[B:%.*]] = load i64, i64* [[TMP9]], align 32
1004 ; WITH-AC-NEXT: [[TMP11:%.*]] = trunc i64 [[TMP10]] to i32
1005 ; WITH-AC-NEXT: ret i32 [[TMP11]]
1007 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test5
1008 ; CROSS-BLOCK-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1009 ; CROSS-BLOCK-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP0]] to i64*
1010 ; CROSS-BLOCK-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP0]] to i16*
1011 ; CROSS-BLOCK-NEXT: [[TMP5:%.*]] = sext i32 [[TMP1]] to i64
1012 ; CROSS-BLOCK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP4]], i64 [[TMP5]]
1013 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i16* [[TMP6]], i64 2), "nonnull"(i8* [[TMP0]]), "align"(i8* [[TMP0]], i64 8) ]
1014 ; CROSS-BLOCK-NEXT: [[TMP7:%.*]] = load i16, i16* [[TMP6]], align 2
1015 ; CROSS-BLOCK-NEXT: [[A:%.*]] = load i16, i16* [[TMP6]], align 4
1016 ; CROSS-BLOCK-NEXT: [[TMP8:%.*]] = sext i16 [[TMP7]] to i64
1017 ; CROSS-BLOCK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i64, i64* [[TMP3]], i64 [[TMP8]]
1018 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP9]], i64 8) ]
1019 ; CROSS-BLOCK-NEXT: [[TMP10:%.*]] = load i64, i64* [[TMP9]], align 16
1020 ; CROSS-BLOCK-NEXT: [[B:%.*]] = load i64, i64* [[TMP9]], align 32
1021 ; CROSS-BLOCK-NEXT: [[TMP11:%.*]] = trunc i64 [[TMP10]] to i32
1022 ; CROSS-BLOCK-NEXT: ret i32 [[TMP11]]
1024 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test5
1025 ; FULL-SIMPLIFY-SAME: (i8* nonnull align 8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1026 ; FULL-SIMPLIFY-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP0]] to i64*
1027 ; FULL-SIMPLIFY-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP0]] to i16*
1028 ; FULL-SIMPLIFY-NEXT: [[TMP5:%.*]] = sext i32 [[TMP1]] to i64
1029 ; FULL-SIMPLIFY-NEXT: [[TMP6:%.*]] = getelementptr inbounds i16, i16* [[TMP4]], i64 [[TMP5]]
1030 ; FULL-SIMPLIFY-NEXT: [[TMP7:%.*]] = load i16, i16* [[TMP6]], align 2
1031 ; FULL-SIMPLIFY-NEXT: [[A:%.*]] = load i16, i16* [[TMP6]], align 4
1032 ; FULL-SIMPLIFY-NEXT: [[TMP8:%.*]] = sext i16 [[TMP7]] to i64
1033 ; FULL-SIMPLIFY-NEXT: [[TMP9:%.*]] = getelementptr inbounds i64, i64* [[TMP3]], i64 [[TMP8]]
1034 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i16* [[TMP6]], i64 2), "dereferenceable"(i64* [[TMP9]], i64 8) ]
1035 ; FULL-SIMPLIFY-NEXT: [[TMP10:%.*]] = load i64, i64* [[TMP9]], align 16
1036 ; FULL-SIMPLIFY-NEXT: [[B:%.*]] = load i64, i64* [[TMP9]], align 32
1037 ; FULL-SIMPLIFY-NEXT: [[TMP11:%.*]] = trunc i64 [[TMP10]] to i32
1038 ; FULL-SIMPLIFY-NEXT: ret i32 [[TMP11]]
1040 %3 = bitcast i8* %0 to i64*
1041 %4 = bitcast i8* %0 to i16*
1042 %5 = sext i32 %1 to i64
1043 %6 = getelementptr inbounds i16, i16* %4, i64 %5
1044 %7 = load i16, i16* %6, align 2
1045 %A = load i16, i16* %6, align 4
1046 %8 = sext i16 %7 to i64
1047 %9 = getelementptr inbounds i64, i64* %3, i64 %8
1048 %10 = load i64, i64* %9, align 16
1049 %B = load i64, i64* %9, align 32
1050 %11 = trunc i64 %10 to i32
1054 define i32 @test6(i32* %0, i32 %1, i32* %2) {
1055 ; BASIC-LABEL: define {{[^@]+}}@test6
1056 ; BASIC-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1057 ; BASIC-NEXT: br label [[TMP4:%.*]]
1059 ; BASIC-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP16:%.*]], [[TMP6:%.*]] ]
1060 ; BASIC-NEXT: [[TMP5:%.*]] = icmp slt i32 [[DOT0]], [[TMP1]]
1061 ; BASIC-NEXT: br i1 [[TMP5]], label [[TMP6]], label [[TMP17:%.*]]
1063 ; BASIC-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP1]], [[DOT0]]
1064 ; BASIC-NEXT: [[TMP8:%.*]] = sext i32 [[TMP7]] to i64
1065 ; BASIC-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP8]]
1066 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4) ]
1067 ; BASIC-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
1068 ; BASIC-NEXT: [[TMP11:%.*]] = mul nsw i32 [[DOT0]], [[TMP10]]
1069 ; BASIC-NEXT: [[TMP12:%.*]] = sext i32 [[DOT0]] to i64
1070 ; BASIC-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP12]]
1071 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP13]], i64 4) ]
1072 ; BASIC-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4
1073 ; BASIC-NEXT: [[TMP15:%.*]] = add nsw i32 [[TMP14]], [[TMP11]]
1074 ; BASIC-NEXT: store i32 [[TMP15]], i32* [[TMP13]], align 4
1075 ; BASIC-NEXT: [[TMP16]] = add nsw i32 [[DOT0]], 1
1076 ; BASIC-NEXT: br label [[TMP4]]
1078 ; BASIC-NEXT: [[TMP18:%.*]] = sext i32 [[TMP1]] to i64
1079 ; BASIC-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP18]]
1080 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP2]]), "align"(i32* [[TMP2]], i64 4) ]
1081 ; BASIC-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP19]], align 4
1082 ; BASIC-NEXT: ret i32 [[TMP20]]
1084 ; ALL-LABEL: define {{[^@]+}}@test6
1085 ; ALL-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1086 ; ALL-NEXT: br label [[TMP4:%.*]]
1088 ; ALL-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP16:%.*]], [[TMP6:%.*]] ]
1089 ; ALL-NEXT: [[TMP5:%.*]] = icmp slt i32 [[DOT0]], [[TMP1]]
1090 ; ALL-NEXT: br i1 [[TMP5]], label [[TMP6]], label [[TMP17:%.*]]
1092 ; ALL-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP1]], [[DOT0]]
1093 ; ALL-NEXT: [[TMP8:%.*]] = sext i32 [[TMP7]] to i64
1094 ; ALL-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP8]]
1095 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4) ]
1096 ; ALL-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
1097 ; ALL-NEXT: [[TMP11:%.*]] = mul nsw i32 [[DOT0]], [[TMP10]]
1098 ; ALL-NEXT: [[TMP12:%.*]] = sext i32 [[DOT0]] to i64
1099 ; ALL-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP12]]
1100 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP13]], i64 4) ]
1101 ; ALL-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4
1102 ; ALL-NEXT: [[TMP15:%.*]] = add nsw i32 [[TMP14]], [[TMP11]]
1103 ; ALL-NEXT: store i32 [[TMP15]], i32* [[TMP13]], align 4
1104 ; ALL-NEXT: [[TMP16]] = add nsw i32 [[DOT0]], 1
1105 ; ALL-NEXT: br label [[TMP4]]
1107 ; ALL-NEXT: [[TMP18:%.*]] = sext i32 [[TMP1]] to i64
1108 ; ALL-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP18]]
1109 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP2]]), "align"(i32* [[TMP2]], i64 4) ]
1110 ; ALL-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP19]], align 4
1111 ; ALL-NEXT: ret i32 [[TMP20]]
1113 ; WITH-AC-LABEL: define {{[^@]+}}@test6
1114 ; WITH-AC-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1115 ; WITH-AC-NEXT: br label [[TMP4:%.*]]
1117 ; WITH-AC-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP16:%.*]], [[TMP6:%.*]] ]
1118 ; WITH-AC-NEXT: [[TMP5:%.*]] = icmp slt i32 [[DOT0]], [[TMP1]]
1119 ; WITH-AC-NEXT: br i1 [[TMP5]], label [[TMP6]], label [[TMP17:%.*]]
1121 ; WITH-AC-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP1]], [[DOT0]]
1122 ; WITH-AC-NEXT: [[TMP8:%.*]] = sext i32 [[TMP7]] to i64
1123 ; WITH-AC-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP8]]
1124 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4) ]
1125 ; WITH-AC-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
1126 ; WITH-AC-NEXT: [[TMP11:%.*]] = mul nsw i32 [[DOT0]], [[TMP10]]
1127 ; WITH-AC-NEXT: [[TMP12:%.*]] = sext i32 [[DOT0]] to i64
1128 ; WITH-AC-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP12]]
1129 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP13]], i64 4) ]
1130 ; WITH-AC-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4
1131 ; WITH-AC-NEXT: [[TMP15:%.*]] = add nsw i32 [[TMP14]], [[TMP11]]
1132 ; WITH-AC-NEXT: store i32 [[TMP15]], i32* [[TMP13]], align 4
1133 ; WITH-AC-NEXT: [[TMP16]] = add nsw i32 [[DOT0]], 1
1134 ; WITH-AC-NEXT: br label [[TMP4]]
1136 ; WITH-AC-NEXT: [[TMP18:%.*]] = sext i32 [[TMP1]] to i64
1137 ; WITH-AC-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP18]]
1138 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP2]]), "align"(i32* [[TMP2]], i64 4) ]
1139 ; WITH-AC-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP19]], align 4
1140 ; WITH-AC-NEXT: ret i32 [[TMP20]]
1142 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test6
1143 ; CROSS-BLOCK-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1144 ; CROSS-BLOCK-NEXT: br label [[TMP4:%.*]]
1146 ; CROSS-BLOCK-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP16:%.*]], [[TMP6:%.*]] ]
1147 ; CROSS-BLOCK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[DOT0]], [[TMP1]]
1148 ; CROSS-BLOCK-NEXT: br i1 [[TMP5]], label [[TMP6]], label [[TMP17:%.*]]
1150 ; CROSS-BLOCK-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP1]], [[DOT0]]
1151 ; CROSS-BLOCK-NEXT: [[TMP8:%.*]] = sext i32 [[TMP7]] to i64
1152 ; CROSS-BLOCK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP8]]
1153 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4) ]
1154 ; CROSS-BLOCK-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
1155 ; CROSS-BLOCK-NEXT: [[TMP11:%.*]] = mul nsw i32 [[DOT0]], [[TMP10]]
1156 ; CROSS-BLOCK-NEXT: [[TMP12:%.*]] = sext i32 [[DOT0]] to i64
1157 ; CROSS-BLOCK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP12]]
1158 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP13]], i64 4) ]
1159 ; CROSS-BLOCK-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4
1160 ; CROSS-BLOCK-NEXT: [[TMP15:%.*]] = add nsw i32 [[TMP14]], [[TMP11]]
1161 ; CROSS-BLOCK-NEXT: store i32 [[TMP15]], i32* [[TMP13]], align 4
1162 ; CROSS-BLOCK-NEXT: [[TMP16]] = add nsw i32 [[DOT0]], 1
1163 ; CROSS-BLOCK-NEXT: br label [[TMP4]]
1165 ; CROSS-BLOCK-NEXT: [[TMP18:%.*]] = sext i32 [[TMP1]] to i64
1166 ; CROSS-BLOCK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP18]]
1167 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP2]]), "align"(i32* [[TMP2]], i64 4) ]
1168 ; CROSS-BLOCK-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP19]], align 4
1169 ; CROSS-BLOCK-NEXT: ret i32 [[TMP20]]
1171 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test6
1172 ; FULL-SIMPLIFY-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1173 ; FULL-SIMPLIFY-NEXT: br label [[TMP4:%.*]]
1175 ; FULL-SIMPLIFY-NEXT: [[DOT0:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP16:%.*]], [[TMP6:%.*]] ]
1176 ; FULL-SIMPLIFY-NEXT: [[TMP5:%.*]] = icmp slt i32 [[DOT0]], [[TMP1]]
1177 ; FULL-SIMPLIFY-NEXT: br i1 [[TMP5]], label [[TMP6]], label [[TMP17:%.*]]
1179 ; FULL-SIMPLIFY-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP1]], [[DOT0]]
1180 ; FULL-SIMPLIFY-NEXT: [[TMP8:%.*]] = sext i32 [[TMP7]] to i64
1181 ; FULL-SIMPLIFY-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP8]]
1182 ; FULL-SIMPLIFY-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
1183 ; FULL-SIMPLIFY-NEXT: [[TMP11:%.*]] = mul nsw i32 [[DOT0]], [[TMP10]]
1184 ; FULL-SIMPLIFY-NEXT: [[TMP12:%.*]] = sext i32 [[DOT0]] to i64
1185 ; FULL-SIMPLIFY-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP12]]
1186 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0]]), "align"(i32* [[TMP0]], i64 4), "dereferenceable"(i32* [[TMP13]], i64 4) ]
1187 ; FULL-SIMPLIFY-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4
1188 ; FULL-SIMPLIFY-NEXT: [[TMP15:%.*]] = add nsw i32 [[TMP14]], [[TMP11]]
1189 ; FULL-SIMPLIFY-NEXT: store i32 [[TMP15]], i32* [[TMP13]], align 4
1190 ; FULL-SIMPLIFY-NEXT: [[TMP16]] = add nsw i32 [[DOT0]], 1
1191 ; FULL-SIMPLIFY-NEXT: br label [[TMP4]]
1192 ; FULL-SIMPLIFY: 17:
1193 ; FULL-SIMPLIFY-NEXT: [[TMP18:%.*]] = sext i32 [[TMP1]] to i64
1194 ; FULL-SIMPLIFY-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP18]]
1195 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP2]]), "align"(i32* [[TMP2]], i64 4) ]
1196 ; FULL-SIMPLIFY-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP19]], align 4
1197 ; FULL-SIMPLIFY-NEXT: ret i32 [[TMP20]]
1202 %.0 = phi i32 [ 0, %3 ], [ %16, %6 ]
1203 %5 = icmp slt i32 %.0, %1
1204 br i1 %5, label %6, label %17
1207 %7 = add nsw i32 %1, %.0
1208 %8 = sext i32 %7 to i64
1209 %9 = getelementptr inbounds i32, i32* %0, i64 %8
1210 %10 = load i32, i32* %9, align 4
1211 %11 = mul nsw i32 %.0, %10
1212 %12 = sext i32 %.0 to i64
1213 %13 = getelementptr inbounds i32, i32* %0, i64 %12
1214 %14 = load i32, i32* %13, align 4
1215 %15 = add nsw i32 %14, %11
1216 store i32 %15, i32* %13, align 4
1217 %16 = add nsw i32 %.0, 1
1221 %18 = sext i32 %1 to i64
1222 %19 = getelementptr inbounds i32, i32* %2, i64 %18
1223 %20 = load i32, i32* %19, align 4
1227 %struct.A = type { i8*, i64*, [4 x [4 x %struct.D]], i64 }
1228 %struct.D = type { i64, i64 }
1230 define i32 @test7(%struct.A* nonnull %0, i32 %1) {
1231 ; BASIC-LABEL: define {{[^@]+}}@test7
1232 ; BASIC-SAME: (%struct.A* nonnull [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1233 ; BASIC-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64
1234 ; BASIC-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[TMP0]], i64 0, i32 3
1235 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.A* [[TMP0]], i64 280), "align"(%struct.A* [[TMP0]], i64 16) ]
1236 ; BASIC-NEXT: [[TMP5:%.*]] = load i64, i64* [[TMP4]], align 8
1237 ; BASIC-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 2, i64 [[TMP3]], i64 [[TMP5]], i32 0
1238 ; BASIC-NEXT: [[TMP7:%.*]] = load i64, i64* [[TMP6]], align 32
1239 ; BASIC-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 1
1240 ; BASIC-NEXT: [[TMP9:%.*]] = load i64*, i64** [[TMP8]], align 8
1241 ; BASIC-NEXT: [[TMP10:%.*]] = getelementptr inbounds i64, i64* [[TMP9]], i64 [[TMP5]]
1242 ; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP10]], i64 8), "nonnull"(i64* [[TMP9]]), "align"(i64* [[TMP9]], i64 8) ]
1243 ; BASIC-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1244 ; BASIC-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1245 ; BASIC-NEXT: [[TMP11:%.*]] = bitcast %struct.A* [[TMP0]] to i32**
1246 ; BASIC-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8
1247 ; BASIC-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
1248 ; BASIC-NEXT: ret i32 [[TMP13]]
1250 ; ALL-LABEL: define {{[^@]+}}@test7
1251 ; ALL-SAME: (%struct.A* nonnull [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1252 ; ALL-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64
1253 ; ALL-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[TMP0]], i64 0, i32 3
1254 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.A* [[TMP0]], i64 280), "align"(%struct.A* [[TMP0]], i64 16) ]
1255 ; ALL-NEXT: [[TMP5:%.*]] = load i64, i64* [[TMP4]], align 8
1256 ; ALL-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 2, i64 [[TMP3]], i64 [[TMP5]], i32 0
1257 ; ALL-NEXT: [[TMP7:%.*]] = load i64, i64* [[TMP6]], align 32
1258 ; ALL-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 1
1259 ; ALL-NEXT: [[TMP9:%.*]] = load i64*, i64** [[TMP8]], align 8
1260 ; ALL-NEXT: [[TMP10:%.*]] = getelementptr inbounds i64, i64* [[TMP9]], i64 [[TMP5]]
1261 ; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP10]], i64 8), "nonnull"(i64* [[TMP9]]), "align"(i64* [[TMP9]], i64 8) ]
1262 ; ALL-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1263 ; ALL-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1264 ; ALL-NEXT: [[TMP11:%.*]] = bitcast %struct.A* [[TMP0]] to i32**
1265 ; ALL-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8
1266 ; ALL-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
1267 ; ALL-NEXT: ret i32 [[TMP13]]
1269 ; WITH-AC-LABEL: define {{[^@]+}}@test7
1270 ; WITH-AC-SAME: (%struct.A* nonnull [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1271 ; WITH-AC-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64
1272 ; WITH-AC-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[TMP0]], i64 0, i32 3
1273 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.A* [[TMP0]], i64 280), "align"(%struct.A* [[TMP0]], i64 16) ]
1274 ; WITH-AC-NEXT: [[TMP5:%.*]] = load i64, i64* [[TMP4]], align 8
1275 ; WITH-AC-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 2, i64 [[TMP3]], i64 [[TMP5]], i32 0
1276 ; WITH-AC-NEXT: [[TMP7:%.*]] = load i64, i64* [[TMP6]], align 32
1277 ; WITH-AC-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 1
1278 ; WITH-AC-NEXT: [[TMP9:%.*]] = load i64*, i64** [[TMP8]], align 8
1279 ; WITH-AC-NEXT: [[TMP10:%.*]] = getelementptr inbounds i64, i64* [[TMP9]], i64 [[TMP5]]
1280 ; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP10]], i64 8), "nonnull"(i64* [[TMP9]]), "align"(i64* [[TMP9]], i64 8) ]
1281 ; WITH-AC-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1282 ; WITH-AC-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1283 ; WITH-AC-NEXT: [[TMP11:%.*]] = bitcast %struct.A* [[TMP0]] to i32**
1284 ; WITH-AC-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8
1285 ; WITH-AC-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
1286 ; WITH-AC-NEXT: ret i32 [[TMP13]]
1288 ; CROSS-BLOCK-LABEL: define {{[^@]+}}@test7
1289 ; CROSS-BLOCK-SAME: (%struct.A* nonnull [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1290 ; CROSS-BLOCK-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64
1291 ; CROSS-BLOCK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[TMP0]], i64 0, i32 3
1292 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(%struct.A* [[TMP0]], i64 280), "align"(%struct.A* [[TMP0]], i64 16) ]
1293 ; CROSS-BLOCK-NEXT: [[TMP5:%.*]] = load i64, i64* [[TMP4]], align 8
1294 ; CROSS-BLOCK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 2, i64 [[TMP3]], i64 [[TMP5]], i32 0
1295 ; CROSS-BLOCK-NEXT: [[TMP7:%.*]] = load i64, i64* [[TMP6]], align 32
1296 ; CROSS-BLOCK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 1
1297 ; CROSS-BLOCK-NEXT: [[TMP9:%.*]] = load i64*, i64** [[TMP8]], align 8
1298 ; CROSS-BLOCK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i64, i64* [[TMP9]], i64 [[TMP5]]
1299 ; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP10]], i64 8), "nonnull"(i64* [[TMP9]]), "align"(i64* [[TMP9]], i64 8) ]
1300 ; CROSS-BLOCK-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1301 ; CROSS-BLOCK-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1302 ; CROSS-BLOCK-NEXT: [[TMP11:%.*]] = bitcast %struct.A* [[TMP0]] to i32**
1303 ; CROSS-BLOCK-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8
1304 ; CROSS-BLOCK-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
1305 ; CROSS-BLOCK-NEXT: ret i32 [[TMP13]]
1307 ; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test7
1308 ; FULL-SIMPLIFY-SAME: (%struct.A* nonnull align 16 dereferenceable(280) [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1309 ; FULL-SIMPLIFY-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64
1310 ; FULL-SIMPLIFY-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[TMP0]], i64 0, i32 3
1311 ; FULL-SIMPLIFY-NEXT: [[TMP5:%.*]] = load i64, i64* [[TMP4]], align 8
1312 ; FULL-SIMPLIFY-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 2, i64 [[TMP3]], i64 [[TMP5]], i32 0
1313 ; FULL-SIMPLIFY-NEXT: [[TMP7:%.*]] = load i64, i64* [[TMP6]], align 32
1314 ; FULL-SIMPLIFY-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP0]], i64 0, i32 1
1315 ; FULL-SIMPLIFY-NEXT: [[TMP9:%.*]] = load i64*, i64** [[TMP8]], align 8
1316 ; FULL-SIMPLIFY-NEXT: [[TMP10:%.*]] = getelementptr inbounds i64, i64* [[TMP9]], i64 [[TMP5]]
1317 ; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i64* [[TMP10]], i64 8), "nonnull"(i64* [[TMP9]]), "align"(i64* [[TMP9]], i64 8) ]
1318 ; FULL-SIMPLIFY-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1319 ; FULL-SIMPLIFY-NEXT: store i64 [[TMP7]], i64* [[TMP10]], align 8
1320 ; FULL-SIMPLIFY-NEXT: [[TMP11:%.*]] = bitcast %struct.A* [[TMP0]] to i32**
1321 ; FULL-SIMPLIFY-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8
1322 ; FULL-SIMPLIFY-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
1323 ; FULL-SIMPLIFY-NEXT: ret i32 [[TMP13]]
1325 %3 = sext i32 %1 to i64
1326 %4 = getelementptr inbounds %struct.A, %struct.A* %0, i64 0, i32 3
1327 %5 = load i64, i64* %4, align 8
1328 %6 = getelementptr inbounds %struct.A, %struct.A* %0, i64 0, i32 2, i64 %3, i64 %5, i32 0
1329 %7 = load i64, i64* %6, align 32
1330 %8 = getelementptr inbounds %struct.A, %struct.A* %0, i64 0, i32 1
1331 %9 = load i64*, i64** %8, align 8
1332 %10 = getelementptr inbounds i64, i64* %9, i64 %5
1333 store i64 %7, i64* %10, align 8
1334 store i64 %7, i64* %10, align 8
1335 %11 = bitcast %struct.A* %0 to i32**
1336 %12 = load i32*, i32** %11, align 8
1337 %13 = load i32, i32* %12, align 4