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