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