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
7
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
13
14target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
15
16declare void @func(i32*, i32*)
17declare void @func_cold(i32*) cold willreturn nounwind
18declare void @func_strbool(i32*) "no-jump-tables"
19declare void @func_many(i32*) "no-jump-tables" nounwind "less-precise-fpmad" willreturn norecurse
20declare void @func_argattr(i32* align 8, i32* nonnull) nounwind
21declare void @func_argattr2(i32* noundef align 8, i32* noundef nonnull) nounwind
22declare void @may_throw()
23
24define 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
49;
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]])
75; ALL-NEXT:    ret void
76;
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
101;
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
126;
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
149;
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)
163  ret void
164}
165
166%struct.S = type { i32, i8, i32* }
167
168define 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]]
204;
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]]
240;
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]]
276;
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]]
312;
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]]
346;
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
376  ret i32 %28
377}
378
379define 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]]
416;
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]]
453;
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]]
490;
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]]
527;
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]]
562;
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
593  ret i32 %28
594}
595
596define 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:%.*]]
604; BASIC:       A:
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]]
609; BASIC:       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]]
615; BASIC:       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
621;
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:%.*]]
629; ALL:       A:
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]]
634; ALL:       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]]
640; ALL:       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
646;
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:%.*]]
654; WITH-AC:       A:
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]]
659; WITH-AC:       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]]
665; WITH-AC:       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
671;
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
696;
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:%.*]]
702; FULL-SIMPLIFY:       A:
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]]
707; FULL-SIMPLIFY:       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]]
712; FULL-SIMPLIFY:       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
717;
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
740;
741  store i32 0, i32* %P, align 4
742  store i32 0, i32* %P1, align 8
743  br i1 %cond, label %A, label %B
744A:
745  store i32 0, i32* %P, align 8
746  store i32 0, i32* %P1, align 4
747  br i1 %cond, label %C, label %B
748B:
749  store i32 0, i32* %P, align 8
750  store i32 0, i32* %P1, align 8
751  br label %C
752C:
753  store i32 0, i32* %P, align 32
754  store i32 0, i32* %P1, align 4
755  ret i32 0
756}
757
758define 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:%.*]]
763; BASIC:       6:
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]]
776; BASIC:       12:
777; BASIC-NEXT:    ret i32 0
778;
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:%.*]]
783; ALL:       6:
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]]
796; ALL:       12:
797; ALL-NEXT:    ret i32 0
798;
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:%.*]]
803; WITH-AC:       6:
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]]
816; WITH-AC:       12:
817; WITH-AC-NEXT:    ret i32 0
818;
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:%.*]]
823; CROSS-BLOCK:       6:
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]]
836; CROSS-BLOCK:       12:
837; CROSS-BLOCK-NEXT:    ret i32 0
838;
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:%.*]]
843; FULL-SIMPLIFY:       6:
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]]
855; FULL-SIMPLIFY:       12:
856; FULL-SIMPLIFY-NEXT:    ret i32 0
857;
858  %5 = icmp ne i32* %1, null
859  br i1 %5, label %6, label %12
860
8616:                                                ; preds = %4
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
871  br label %12
872
87312:                                               ; preds = %6, %4
874  ret i32 0
875}
876
877declare void @may_throwv2(i32* %P)
878
879define 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:%.*]]
884; BASIC:       Catch:
885; BASIC-NEXT:    [[V:%.*]] = landingpad { i8*, i32 }
886; BASIC-NEXT:    catch i8* null
887; BASIC-NEXT:    br label [[EXIT]]
888; BASIC:       Exit:
889; BASIC-NEXT:    [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
890; BASIC-NEXT:    ret i32 [[DOT0]]
891;
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:%.*]]
896; ALL:       Catch:
897; ALL-NEXT:    [[V:%.*]] = landingpad { i8*, i32 }
898; ALL-NEXT:    catch i8* null
899; ALL-NEXT:    br label [[EXIT]]
900; ALL:       Exit:
901; ALL-NEXT:    [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
902; ALL-NEXT:    ret i32 [[DOT0]]
903;
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:%.*]]
908; WITH-AC:       Catch:
909; WITH-AC-NEXT:    [[V:%.*]] = landingpad { i8*, i32 }
910; WITH-AC-NEXT:    catch i8* null
911; WITH-AC-NEXT:    br label [[EXIT]]
912; WITH-AC:       Exit:
913; WITH-AC-NEXT:    [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
914; WITH-AC-NEXT:    ret i32 [[DOT0]]
915;
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]]
924; CROSS-BLOCK:       Exit:
925; CROSS-BLOCK-NEXT:    [[DOT0:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ 0, [[CATCH]] ]
926; CROSS-BLOCK-NEXT:    ret i32 [[DOT0]]
927;
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]]
939;
940  invoke void @may_throwv2(i32* nonnull %P)
941  to label %Exit unwind label %Catch
942
943Catch:                                                ; preds = %0
944  %v = landingpad { i8*, i32 }
945  catch i8* null
946  br label %Exit
947
948Exit:                                                ; preds = %7, %5
949  %.0 = phi i32 [ 1, %0 ], [ 0, %Catch ]
950  ret i32 %.0
951}
952
953declare dso_local i32 @__gxx_personality_v0(...)
954
955define 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]]
972;
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]]
989;
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]]
1006;
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]]
1023;
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]]
1039;
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
1051  ret i32 %11
1052}
1053
1054define 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:%.*]]
1058; BASIC:       4:
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:%.*]]
1062; BASIC:       6:
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]]
1077; BASIC:       17:
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]]
1083;
1084; ALL-LABEL: define {{[^@]+}}@test6
1085; ALL-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1086; ALL-NEXT:    br label [[TMP4:%.*]]
1087; ALL:       4:
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:%.*]]
1091; ALL:       6:
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]]
1106; ALL:       17:
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]]
1112;
1113; WITH-AC-LABEL: define {{[^@]+}}@test6
1114; WITH-AC-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1115; WITH-AC-NEXT:    br label [[TMP4:%.*]]
1116; WITH-AC:       4:
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:%.*]]
1120; WITH-AC:       6:
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]]
1135; WITH-AC:       17:
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]]
1141;
1142; CROSS-BLOCK-LABEL: define {{[^@]+}}@test6
1143; CROSS-BLOCK-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1144; CROSS-BLOCK-NEXT:    br label [[TMP4:%.*]]
1145; CROSS-BLOCK:       4:
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:%.*]]
1149; CROSS-BLOCK:       6:
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]]
1164; CROSS-BLOCK:       17:
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]]
1170;
1171; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test6
1172; FULL-SIMPLIFY-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* [[TMP2:%.*]]) {
1173; FULL-SIMPLIFY-NEXT:    br label [[TMP4:%.*]]
1174; FULL-SIMPLIFY:       4:
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:%.*]]
1178; FULL-SIMPLIFY:       6:
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]]
1198;
1199  br label %4
1200
12014:                                                ; preds = %6, %3
1202  %.0 = phi i32 [ 0, %3 ], [ %16, %6 ]
1203  %5 = icmp slt i32 %.0, %1
1204  br i1 %5, label %6, label %17
1205
12066:                                                ; preds = %4
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
1218  br label %4
1219
122017:                                               ; preds = %4
1221  %18 = sext i32 %1 to i64
1222  %19 = getelementptr inbounds i32, i32* %2, i64 %18
1223  %20 = load i32, i32* %19, align 4
1224  ret i32 %20
1225}
1226
1227%struct.A = type { i8*, i64*, [4 x [4 x %struct.D]], i64 }
1228%struct.D = type { i64, i64 }
1229
1230define 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]]
1249;
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]]
1268;
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]]
1287;
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]]
1306;
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]]
1324;
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
1338  ret i32 %13
1339}
1340