1200 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes='dse' -S %s | FileCheck %s3 4declare void @escape_and_clobber(ptr)5declare void @escape_writeonly(ptr) writeonly6declare void @clobber()7 8define i32 @test_not_captured_before_load_same_bb(ptr %in.ptr) {9; CHECK-LABEL: @test_not_captured_before_load_same_bb(10; CHECK-NEXT: [[A:%.*]] = alloca i32, align 411; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 212; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 213; CHECK-NEXT: store i32 99, ptr [[A]], align 414; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])15; CHECK-NEXT: ret i32 [[IN_LV_2]]16;17 %a = alloca i32, align 418 store i32 55, ptr %a19 %in.lv.1 = load ptr , ptr %in.ptr, align 220 %in.lv.2 = load i32 , ptr %in.lv.1, align 221 store i32 99, ptr %a, align 422 call void @escape_and_clobber(ptr %a)23 ret i32 %in.lv.224}25 26define i32 @test_not_captured_before_load_same_bb_escape_unreachable_block(ptr %in.ptr) {27; CHECK-LABEL: @test_not_captured_before_load_same_bb_escape_unreachable_block(28; CHECK-NEXT: [[A:%.*]] = alloca i32, align 429; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 230; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 231; CHECK-NEXT: store i32 99, ptr [[A]], align 432; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])33; CHECK-NEXT: ret i32 [[IN_LV_2]]34; CHECK: unreach:35; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])36; CHECK-NEXT: ret i32 037;38 %a = alloca i32, align 439 store i32 55, ptr %a40 %in.lv.1 = load ptr , ptr %in.ptr, align 241 %in.lv.2 = load i32 , ptr %in.lv.1, align 242 store i32 99, ptr %a, align 443 call void @escape_and_clobber(ptr %a)44 ret i32 %in.lv.245 46unreach:47 call void @escape_and_clobber(ptr %a)48 ret i32 049}50 51define i32 @test_not_captured_before_load_same_bb_escape_unreachable_block2(ptr %in.ptr) {52; CHECK-LABEL: @test_not_captured_before_load_same_bb_escape_unreachable_block2(53; CHECK-NEXT: br label [[BB:%.*]]54; CHECK: unreach:55; CHECK-NEXT: call void @escape_and_clobber(ptr [[A:%.*]])56; CHECK-NEXT: ret i32 057; CHECK: bb:58; CHECK-NEXT: [[A]] = alloca i32, align 459; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 260; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 261; CHECK-NEXT: store i32 99, ptr [[A]], align 462; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])63; CHECK-NEXT: ret i32 [[IN_LV_2]]64;65 br label %bb66 67unreach:68 call void @escape_and_clobber(ptr %a)69 ret i32 070 71bb:72 %a = alloca i32, align 473 store i32 55, ptr %a74 %in.lv.1 = load ptr , ptr %in.ptr, align 275 %in.lv.2 = load i32 , ptr %in.lv.1, align 276 store i32 99, ptr %a, align 477 call void @escape_and_clobber(ptr %a)78 ret i32 %in.lv.279}80 81define i32 @test_captured_and_clobbered_after_load_same_bb_2(ptr %in.ptr) {82; CHECK-LABEL: @test_captured_and_clobbered_after_load_same_bb_2(83; CHECK-NEXT: [[A:%.*]] = alloca i32, align 484; CHECK-NEXT: store i32 55, ptr [[A]], align 485; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 286; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 287; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])88; CHECK-NEXT: store i32 99, ptr [[A]], align 489; CHECK-NEXT: call void @clobber()90; CHECK-NEXT: ret i32 [[IN_LV_2]]91;92 %a = alloca i32, align 493 store i32 55, ptr %a94 %in.lv.1 = load ptr , ptr %in.ptr, align 295 %in.lv.2 = load i32 , ptr %in.lv.1, align 296 call void @escape_and_clobber(ptr %a)97 store i32 99, ptr %a, align 498 call void @clobber()99 ret i32 %in.lv.2100}101 102define i32 @test_captured_after_load_same_bb_2_clobbered_later(ptr %in.ptr) {103; CHECK-LABEL: @test_captured_after_load_same_bb_2_clobbered_later(104; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4105; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2106; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2107; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])108; CHECK-NEXT: store i32 99, ptr [[A]], align 4109; CHECK-NEXT: call void @clobber()110; CHECK-NEXT: ret i32 [[IN_LV_2]]111;112 %a = alloca i32, align 4113 store i32 55, ptr %a114 %in.lv.1 = load ptr , ptr %in.ptr, align 2115 %in.lv.2 = load i32 , ptr %in.lv.1, align 2116 call void @escape_writeonly(ptr %a)117 store i32 99, ptr %a, align 4118 call void @clobber()119 ret i32 %in.lv.2120}121 122define i32 @test_captured_and_clobbered_before_load_same_bb_1(ptr %in.ptr) {123; CHECK-LABEL: @test_captured_and_clobbered_before_load_same_bb_1(124; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4125; CHECK-NEXT: store i32 55, ptr [[A]], align 4126; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2127; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])128; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2129; CHECK-NEXT: store i32 99, ptr [[A]], align 4130; CHECK-NEXT: call void @clobber()131; CHECK-NEXT: ret i32 [[IN_LV_2]]132;133 %a = alloca i32, align 4134 store i32 55, ptr %a135 %in.lv.1 = load ptr , ptr %in.ptr, align 2136 call void @escape_and_clobber(ptr %a)137 %in.lv.2 = load i32 , ptr %in.lv.1, align 2138 store i32 99, ptr %a, align 4139 call void @clobber()140 ret i32 %in.lv.2141}142 143define i32 @test_captured_before_load_same_bb_1_clobbered_later(ptr %in.ptr) {144; CHECK-LABEL: @test_captured_before_load_same_bb_1_clobbered_later(145; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4146; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2147; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])148; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2149; CHECK-NEXT: store i32 99, ptr [[A]], align 4150; CHECK-NEXT: call void @clobber()151; CHECK-NEXT: ret i32 [[IN_LV_2]]152;153 %a = alloca i32, align 4154 store i32 55, ptr %a155 %in.lv.1 = load ptr , ptr %in.ptr, align 2156 call void @escape_writeonly(ptr %a)157 %in.lv.2 = load i32 , ptr %in.lv.1, align 2158 store i32 99, ptr %a, align 4159 call void @clobber()160 ret i32 %in.lv.2161}162 163define i32 @test_captured_before_load_same_bb_2(ptr %in.ptr) {164; CHECK-LABEL: @test_captured_before_load_same_bb_2(165; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4166; CHECK-NEXT: store i32 55, ptr [[A]], align 4167; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])168; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2169; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2170; CHECK-NEXT: store i32 99, ptr [[A]], align 4171; CHECK-NEXT: call void @clobber()172; CHECK-NEXT: ret i32 [[IN_LV_2]]173;174 %a = alloca i32, align 4175 store i32 55, ptr %a176 call void @escape_writeonly(ptr %a)177 %in.lv.1 = load ptr , ptr %in.ptr, align 2178 %in.lv.2 = load i32 , ptr %in.lv.1, align 2179 store i32 99, ptr %a, align 4180 call void @clobber()181 ret i32 %in.lv.2182}183 184define i32 @test_not_captured_before_load_same_bb_clobber(ptr %in.ptr) {185; CHECK-LABEL: @test_not_captured_before_load_same_bb_clobber(186; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4187; CHECK-NEXT: call void @clobber()188; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2189; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2190; CHECK-NEXT: store i32 99, ptr [[A]], align 4191; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])192; CHECK-NEXT: ret i32 [[IN_LV_2]]193;194 %a = alloca i32, align 4195 store i32 55, ptr %a196 call void @clobber()197 %in.lv.1 = load ptr , ptr %in.ptr, align 2198 %in.lv.2 = load i32 , ptr %in.lv.1, align 2199 store i32 99, ptr %a, align 4200 call void @escape_and_clobber(ptr %a)201 ret i32 %in.lv.2202}203 204define i32 @test_captured_before_load_same_bb(ptr %in.ptr) {205; CHECK-LABEL: @test_captured_before_load_same_bb(206; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4207; CHECK-NEXT: store i32 55, ptr [[A]], align 4208; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])209; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2210; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2211; CHECK-NEXT: store i32 99, ptr [[A]], align 4212; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])213; CHECK-NEXT: ret i32 [[IN_LV_2]]214;215 %a = alloca i32, align 4216 store i32 55, ptr %a217 call void @escape_and_clobber(ptr %a)218 %in.lv.1 = load ptr , ptr %in.ptr, align 2219 %in.lv.2 = load i32 , ptr %in.lv.1, align 2220 store i32 99, ptr %a, align 4221 call void @escape_and_clobber(ptr %a)222 ret i32 %in.lv.2223}224 225define i32 @test_captured_sibling_path_to_load_other_blocks_1(ptr %in.ptr, i1 %c.1) {226; CHECK-LABEL: @test_captured_sibling_path_to_load_other_blocks_1(227; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4228; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]229; CHECK: then:230; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])231; CHECK-NEXT: br label [[EXIT:%.*]]232; CHECK: else:233; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2234; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2235; CHECK-NEXT: br label [[EXIT]]236; CHECK: exit:237; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]238; CHECK-NEXT: store i32 99, ptr [[A]], align 4239; CHECK-NEXT: call void @clobber()240; CHECK-NEXT: ret i32 [[P]]241;242 %a = alloca i32, align 4243 store i32 55, ptr %a244 br i1 %c.1, label %then, label %else245 246then:247 call void @escape_writeonly(ptr %a)248 br label %exit249 250else:251 %in.lv.1 = load ptr , ptr %in.ptr, align 2252 %in.lv.2 = load i32 , ptr %in.lv.1, align 2253 br label %exit254 255exit:256 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]257 store i32 99, ptr %a, align 4258 call void @clobber()259 ret i32 %p260}261 262define i32 @test_only_captured_sibling_path_with_ret_to_load_other_blocks(ptr %in.ptr, i1 %c.1) {263; CHECK-LABEL: @test_only_captured_sibling_path_with_ret_to_load_other_blocks(264; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4265; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]266; CHECK: then:267; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])268; CHECK-NEXT: ret i32 0269; CHECK: else:270; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2271; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2272; CHECK-NEXT: br label [[EXIT:%.*]]273; CHECK: exit:274; CHECK-NEXT: call void @clobber()275; CHECK-NEXT: ret i32 [[IN_LV_2]]276;277 %a = alloca i32, align 4278 store i32 55, ptr %a279 br i1 %c.1, label %then, label %else280 281then:282 call void @escape_writeonly(ptr %a)283 ret i32 0284 285else:286 %in.lv.1 = load ptr , ptr %in.ptr, align 2287 %in.lv.2 = load i32 , ptr %in.lv.1, align 2288 br label %exit289 290exit:291 store i32 99, ptr %a, align 4292 call void @clobber()293 ret i32 %in.lv.2294}295 296define i32 @test_captured_before_load_other_blocks_2(ptr %in.ptr, i1 %c.1) {297; CHECK-LABEL: @test_captured_before_load_other_blocks_2(298; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4299; CHECK-NEXT: store i32 55, ptr [[A]], align 4300; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]301; CHECK: then:302; CHECK-NEXT: br label [[EXIT:%.*]]303; CHECK: else:304; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])305; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2306; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2307; CHECK-NEXT: br label [[EXIT]]308; CHECK: exit:309; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]310; CHECK-NEXT: store i32 99, ptr [[A]], align 4311; CHECK-NEXT: call void @clobber()312; CHECK-NEXT: ret i32 [[P]]313;314 %a = alloca i32, align 4315 store i32 55, ptr %a316 br i1 %c.1, label %then, label %else317 318then:319 br label %exit320 321else:322 call void @escape_and_clobber(ptr %a)323 %in.lv.1 = load ptr , ptr %in.ptr, align 2324 %in.lv.2 = load i32 , ptr %in.lv.1, align 2325 br label %exit326 327exit:328 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]329 store i32 99, ptr %a, align 4330 call void @clobber()331 ret i32 %p332}333 334define i32 @test_captured_before_load_other_blocks_4(ptr %in.ptr, i1 %c.1) {335; CHECK-LABEL: @test_captured_before_load_other_blocks_4(336; CHECK-NEXT: entry:337; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4338; CHECK-NEXT: store i32 55, ptr [[A]], align 4339; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])340; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2341; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2342; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]343; CHECK: then:344; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])345; CHECK-NEXT: br label [[EXIT]]346; CHECK: exit:347; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ENTRY:%.*]] ]348; CHECK-NEXT: store i32 99, ptr [[A]], align 4349; CHECK-NEXT: call void @clobber()350; CHECK-NEXT: ret i32 [[P]]351;352entry:353 %a = alloca i32, align 4354 store i32 55, ptr %a355 call void @escape_writeonly(ptr %a)356 %in.lv.1 = load ptr , ptr %in.ptr, align 2357 %in.lv.2 = load i32 , ptr %in.lv.1, align 2358 br i1 %c.1, label %then, label %exit359 360then:361 call void @escape_writeonly(ptr %a)362 br label %exit363 364exit:365 %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]366 store i32 99, ptr %a, align 4367 call void @clobber()368 ret i32 %p369}370 371define i32 @test_captured_before_load_other_blocks_5(ptr %in.ptr, i1 %c.1) {372; CHECK-LABEL: @test_captured_before_load_other_blocks_5(373; CHECK-NEXT: entry:374; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4375; CHECK-NEXT: store i32 55, ptr [[A]], align 4376; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]377; CHECK: then:378; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])379; CHECK-NEXT: br label [[EXIT]]380; CHECK: exit:381; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2382; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2383; CHECK-NEXT: store i32 99, ptr [[A]], align 4384; CHECK-NEXT: call void @clobber()385; CHECK-NEXT: ret i32 [[IN_LV_2]]386;387entry:388 %a = alloca i32, align 4389 store i32 55, ptr %a390 br i1 %c.1, label %then, label %exit391 392then:393 call void @escape_writeonly(ptr %a)394 br label %exit395 396exit:397 %in.lv.1 = load ptr , ptr %in.ptr, align 2398 %in.lv.2 = load i32 , ptr %in.lv.1, align 2399 store i32 99, ptr %a, align 4400 call void @clobber()401 ret i32 %in.lv.2402}403 404define i32 @test_captured_before_load_other_blocks_6(ptr %in.ptr, i1 %c.1) {405; CHECK-LABEL: @test_captured_before_load_other_blocks_6(406; CHECK-NEXT: entry:407; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4408; CHECK-NEXT: store i32 55, ptr [[A]], align 4409; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]410; CHECK: then:411; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])412; CHECK-NEXT: br label [[EXIT]]413; CHECK: exit:414; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2415; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2416; CHECK-NEXT: store i32 99, ptr [[A]], align 4417; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])418; CHECK-NEXT: call void @clobber()419; CHECK-NEXT: ret i32 [[IN_LV_2]]420;421entry:422 %a = alloca i32, align 4423 store i32 55, ptr %a424 br i1 %c.1, label %then, label %exit425 426then:427 call void @escape_writeonly(ptr %a)428 br label %exit429 430exit:431 %in.lv.1 = load ptr , ptr %in.ptr, align 2432 %in.lv.2 = load i32 , ptr %in.lv.1, align 2433 store i32 99, ptr %a, align 4434 call void @escape_writeonly(ptr %a)435 call void @clobber()436 ret i32 %in.lv.2437}438 439define i32 @test_not_captured_before_load_other_blocks_1(ptr %in.ptr, i1 %c.1) {440; CHECK-LABEL: @test_not_captured_before_load_other_blocks_1(441; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4442; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2443; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2444; CHECK-NEXT: store i32 99, ptr [[A]], align 4445; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]446; CHECK: then:447; CHECK-NEXT: br label [[EXIT:%.*]]448; CHECK: else:449; CHECK-NEXT: br label [[EXIT]]450; CHECK: exit:451; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])452; CHECK-NEXT: ret i32 [[IN_LV_2]]453;454 %a = alloca i32, align 4455 store i32 55, ptr %a456 %in.lv.1 = load ptr , ptr %in.ptr, align 2457 %in.lv.2 = load i32 , ptr %in.lv.1, align 2458 store i32 99, ptr %a, align 4459 br i1 %c.1, label %then, label %else460 461then:462 br label %exit463 464else:465 br label %exit466 467exit:468 call void @escape_and_clobber(ptr %a)469 ret i32 %in.lv.2470}471 472define i32 @test_not_captured_before_load_other_blocks_2(ptr %in.ptr, i1 %c.1) {473; CHECK-LABEL: @test_not_captured_before_load_other_blocks_2(474; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4475; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2476; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2477; CHECK-NEXT: store i32 99, ptr [[A]], align 4478; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]479; CHECK: then:480; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])481; CHECK-NEXT: br label [[EXIT:%.*]]482; CHECK: else:483; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])484; CHECK-NEXT: br label [[EXIT]]485; CHECK: exit:486; CHECK-NEXT: ret i32 [[IN_LV_2]]487;488 %a = alloca i32, align 4489 store i32 55, ptr %a490 %in.lv.1 = load ptr , ptr %in.ptr, align 2491 %in.lv.2 = load i32 , ptr %in.lv.1, align 2492 store i32 99, ptr %a, align 4493 br i1 %c.1, label %then, label %else494 495then:496 call void @escape_and_clobber(ptr %a)497 br label %exit498 499else:500 call void @escape_and_clobber(ptr %a)501 br label %exit502 503exit:504 ret i32 %in.lv.2505}506 507define i32 @test_not_captured_before_load_other_blocks_3(ptr %in.ptr, i1 %c.1) {508; CHECK-LABEL: @test_not_captured_before_load_other_blocks_3(509; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4510; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2511; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2512; CHECK-NEXT: store i32 99, ptr [[A]], align 4513; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]514; CHECK: then:515; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])516; CHECK-NEXT: br label [[EXIT:%.*]]517; CHECK: else:518; CHECK-NEXT: br label [[EXIT]]519; CHECK: exit:520; CHECK-NEXT: ret i32 [[IN_LV_2]]521;522 %a = alloca i32, align 4523 store i32 55, ptr %a524 %in.lv.1 = load ptr , ptr %in.ptr, align 2525 %in.lv.2 = load i32 , ptr %in.lv.1, align 2526 store i32 99, ptr %a, align 4527 br i1 %c.1, label %then, label %else528 529then:530 call void @escape_and_clobber(ptr %a)531 br label %exit532 533else:534 br label %exit535 536exit:537 ret i32 %in.lv.2538}539 540define i32 @test_not_captured_before_load_other_blocks_4(ptr %in.ptr, i1 %c.1) {541; CHECK-LABEL: @test_not_captured_before_load_other_blocks_4(542; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4543; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]544; CHECK: then:545; CHECK-NEXT: br label [[EXIT:%.*]]546; CHECK: else:547; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2548; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2549; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])550; CHECK-NEXT: br label [[EXIT]]551; CHECK: exit:552; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]553; CHECK-NEXT: store i32 99, ptr [[A]], align 4554; CHECK-NEXT: call void @clobber()555; CHECK-NEXT: ret i32 [[P]]556;557 %a = alloca i32, align 4558 store i32 55, ptr %a559 br i1 %c.1, label %then, label %else560 561then:562 br label %exit563 564else:565 %in.lv.1 = load ptr , ptr %in.ptr, align 2566 %in.lv.2 = load i32 , ptr %in.lv.1, align 2567 call void @escape_writeonly(ptr %a)568 br label %exit569 570exit:571 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]572 store i32 99, ptr %a, align 4573 call void @clobber()574 ret i32 %p575}576 577define i32 @test_not_captured_before_load_other_blocks_5(ptr %in.ptr, i1 %c.1) {578; CHECK-LABEL: @test_not_captured_before_load_other_blocks_5(579; CHECK-NEXT: entry:580; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4581; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]582; CHECK: then:583; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2584; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2585; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])586; CHECK-NEXT: br label [[EXIT]]587; CHECK: exit:588; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]589; CHECK-NEXT: store i32 99, ptr [[A]], align 4590; CHECK-NEXT: call void @clobber()591; CHECK-NEXT: ret i32 [[P]]592;593entry:594 %a = alloca i32, align 4595 store i32 55, ptr %a596 br i1 %c.1, label %then, label %exit597 598then:599 %in.lv.1 = load ptr , ptr %in.ptr, align 2600 %in.lv.2 = load i32 , ptr %in.lv.1, align 2601 call void @escape_writeonly(ptr %a)602 br label %exit603 604exit:605 %p = phi i32 [ %in.lv.2, %then ], [ 0, %entry ]606 store i32 99, ptr %a, align 4607 call void @clobber()608 ret i32 %p609}610 611define i32 @test_not_captured_before_load_other_blocks_6(ptr %in.ptr, i1 %c.1) {612; CHECK-LABEL: @test_not_captured_before_load_other_blocks_6(613; CHECK-NEXT: entry:614; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4615; CHECK-NEXT: store i32 55, ptr [[A]], align 4616; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]617; CHECK: then:618; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2619; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2620; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])621; CHECK-NEXT: br label [[EXIT]]622; CHECK: exit:623; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]624; CHECK-NEXT: store i32 99, ptr [[A]], align 4625; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])626; CHECK-NEXT: call void @clobber()627; CHECK-NEXT: ret i32 [[P]]628;629entry:630 %a = alloca i32, align 4631 store i32 55, ptr %a632 br i1 %c.1, label %then, label %exit633 634then:635 %in.lv.1 = load ptr , ptr %in.ptr, align 2636 %in.lv.2 = load i32 , ptr %in.lv.1, align 2637 call void @escape_writeonly(ptr %a)638 br label %exit639 640exit:641 %p = phi i32 [ %in.lv.2, %then ], [ 0, %entry ]642 store i32 99, ptr %a, align 4643 call void @escape_writeonly(ptr %a)644 call void @clobber()645 ret i32 %p646}647 648define i32 @test_not_captured_before_load_other_blocks_7(ptr %in.ptr, i1 %c.1) {649; CHECK-LABEL: @test_not_captured_before_load_other_blocks_7(650; CHECK-NEXT: entry:651; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4652; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2653; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2654; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])655; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]656; CHECK: then:657; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])658; CHECK-NEXT: br label [[EXIT]]659; CHECK: exit:660; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ENTRY:%.*]] ]661; CHECK-NEXT: store i32 99, ptr [[A]], align 4662; CHECK-NEXT: call void @clobber()663; CHECK-NEXT: ret i32 [[P]]664;665entry:666 %a = alloca i32, align 4667 store i32 55, ptr %a668 %in.lv.1 = load ptr , ptr %in.ptr, align 2669 %in.lv.2 = load i32 , ptr %in.lv.1, align 2670 call void @escape_writeonly(ptr %a)671 br i1 %c.1, label %then, label %exit672 673then:674 call void @escape_writeonly(ptr %a)675 br label %exit676 677exit:678 %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]679 store i32 99, ptr %a, align 4680 call void @clobber()681 ret i32 %p682}683 684define i32 @test_not_captured_before_load_same_bb_but_read(ptr %in.ptr) {685; CHECK-LABEL: @test_not_captured_before_load_same_bb_but_read(686; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4687; CHECK-NEXT: store i32 55, ptr [[A]], align 4688; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2689; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2690; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[A]], align 4691; CHECK-NEXT: store i32 99, ptr [[A]], align 4692; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])693; CHECK-NEXT: [[RES:%.*]] = add i32 [[IN_LV_2]], [[LV]]694; CHECK-NEXT: ret i32 [[RES]]695;696 %a = alloca i32, align 4697 store i32 55, ptr %a698 %in.lv.1 = load ptr , ptr %in.ptr, align 2699 %in.lv.2 = load i32 , ptr %in.lv.1, align 2700 %lv = load i32, ptr %a701 store i32 99, ptr %a, align 4702 call void @escape_and_clobber(ptr %a)703 %res = add i32 %in.lv.2, %lv704 ret i32 %res705}706 707define i32 @test_not_captured_before_load_may_alias_same_bb_but_read(ptr %in.ptr, ptr %b, i1 %c) {708; CHECK-LABEL: @test_not_captured_before_load_may_alias_same_bb_but_read(709; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4710; CHECK-NEXT: store i32 55, ptr [[A]], align 4711; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2712; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2713; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], ptr [[A]], ptr [[B:%.*]]714; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4715; CHECK-NEXT: store i32 99, ptr [[A]], align 4716; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])717; CHECK-NEXT: [[RES:%.*]] = add i32 [[IN_LV_2]], [[LV]]718; CHECK-NEXT: ret i32 [[RES]]719;720 %a = alloca i32, align 4721 store i32 55, ptr %a722 %in.lv.1 = load ptr , ptr %in.ptr, align 2723 %in.lv.2 = load i32 , ptr %in.lv.1, align 2724 %ptr = select i1 %c, ptr %a, ptr %b725 %lv = load i32, ptr %ptr726 store i32 99, ptr %a, align 4727 call void @escape_and_clobber(ptr %a)728 %res = add i32 %in.lv.2, %lv729 ret i32 %res730}731 732define i32 @test_captured_after_loop(ptr %in.ptr, i1 %c.1) {733; CHECK-LABEL: @test_captured_after_loop(734; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4735; CHECK-NEXT: br label [[LOOP:%.*]]736; CHECK: loop:737; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2738; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2739; CHECK-NEXT: store i32 99, ptr [[A]], align 4740; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]741; CHECK: exit:742; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])743; CHECK-NEXT: ret i32 [[IN_LV_2]]744;745 %a = alloca i32, align 4746 store i32 55, ptr %a747 br label %loop748 749loop:750 %in.lv.1 = load ptr , ptr %in.ptr, align 2751 %in.lv.2 = load i32 , ptr %in.lv.1, align 2752 store i32 99, ptr %a, align 4753 br i1 %c.1, label %loop, label %exit754 755exit:756 call void @escape_and_clobber(ptr %a)757 ret i32 %in.lv.2758}759 760define i32 @test_captured_in_loop(ptr %in.ptr, i1 %c.1) {761; CHECK-LABEL: @test_captured_in_loop(762; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4763; CHECK-NEXT: store i32 55, ptr [[A]], align 4764; CHECK-NEXT: br label [[LOOP:%.*]]765; CHECK: loop:766; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2767; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2768; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])769; CHECK-NEXT: store i32 99, ptr [[A]], align 4770; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]771; CHECK: exit:772; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])773; CHECK-NEXT: ret i32 [[IN_LV_2]]774;775 %a = alloca i32, align 4776 store i32 55, ptr %a777 br label %loop778 779loop:780 %in.lv.1 = load ptr , ptr %in.ptr, align 2781 %in.lv.2 = load i32 , ptr %in.lv.1, align 2782 call void @escape_writeonly(ptr %a)783 store i32 99, ptr %a, align 4784 br i1 %c.1, label %loop, label %exit785 786exit:787 call void @escape_and_clobber(ptr %a)788 ret i32 %in.lv.2789}790 791declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)792 793@global = external global ptr794 795define void @test_memset_not_captured_before_load() {796; CHECK-LABEL: @test_memset_not_captured_before_load(797; CHECK-NEXT: [[A:%.*]] = alloca [2 x i32], align 4798; CHECK-NEXT: [[LV_1:%.*]] = load ptr, ptr @global, align 8799; CHECK-NEXT: store i32 1, ptr [[A]], align 4800; CHECK-NEXT: [[GEP_LV:%.*]] = getelementptr inbounds [10 x i16], ptr [[LV_1]], i64 0, i32 1801; CHECK-NEXT: [[LV_2:%.*]] = load i16, ptr [[GEP_LV]], align 2802; CHECK-NEXT: [[EXT_LV_2:%.*]] = zext i16 [[LV_2]] to i32803; CHECK-NEXT: [[GEP_A_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 1804; CHECK-NEXT: store i32 [[EXT_LV_2]], ptr [[GEP_A_1]], align 4805; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])806; CHECK-NEXT: ret void807;808 %a = alloca [2 x i32], align 4809 call void @llvm.memset.p0.i32(ptr %a, i8 0, i32 8, i1 false)810 %lv.1 = load ptr, ptr @global, align 8811 store i32 1, ptr %a, align 4812 %gep.lv = getelementptr inbounds [10 x i16], ptr %lv.1, i64 0, i32 1813 %lv.2 = load i16, ptr %gep.lv, align 2814 %ext.lv.2 = zext i16 %lv.2 to i32815 %gep.a.1 = getelementptr inbounds [2 x i32], ptr %a, i32 0, i32 1816 store i32 %ext.lv.2, ptr %gep.a.1, align 4817 call void @escape_and_clobber(ptr %a)818 ret void819}820 821define void @test_test_not_captured_before_load(i1 %c.1) {822; CHECK-LABEL: @test_test_not_captured_before_load(823; CHECK-NEXT: bb:824; CHECK-NEXT: [[A:%.*]] = alloca [2 x i32], align 4825; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[A]], i32 4826; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[TMP0]], i8 0, i32 4, i1 false)827; CHECK-NEXT: [[LV_1:%.*]] = load ptr, ptr @global, align 8828; CHECK-NEXT: [[GEP_LV:%.*]] = getelementptr inbounds [10 x i16], ptr [[LV_1]], i64 0, i32 1829; CHECK-NEXT: [[LV_2:%.*]] = load i16, ptr [[GEP_LV]], align 2830; CHECK-NEXT: store i32 1, ptr [[A]], align 4831; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]832; CHECK: then:833; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])834; CHECK-NEXT: br label [[EXIT:%.*]]835; CHECK: else:836; CHECK-NEXT: br label [[EXIT]]837; CHECK: exit:838; CHECK-NEXT: [[EXT_LV_2:%.*]] = zext i16 [[LV_2]] to i32839; CHECK-NEXT: [[GEP_A_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 1840; CHECK-NEXT: store i32 [[EXT_LV_2]], ptr [[GEP_A_1]], align 4841; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])842; CHECK-NEXT: ret void843;844bb:845 %a = alloca [2 x i32], align 4846 call void @llvm.memset.p0.i32(ptr %a, i8 0, i32 8, i1 false)847 %lv.1 = load ptr, ptr @global, align 8848 %gep.lv = getelementptr inbounds [10 x i16], ptr %lv.1, i64 0, i32 1849 %lv.2 = load i16, ptr %gep.lv, align 2850 store i32 1, ptr %a, align 4851 br i1 %c.1, label %then, label %else852 853then:854 call void @escape_and_clobber(ptr %a)855 br label %exit856 857else:858 br label %exit859 860exit:861 %ext.lv.2 = zext i16 %lv.2 to i32862 %gep.a.1 = getelementptr inbounds [2 x i32], ptr %a, i32 0, i32 1863 store i32 %ext.lv.2, ptr %gep.a.1, align 4864 call void @escape_and_clobber(ptr %a)865 ret void866}867 868declare void @llvm.lifetime.start.p0(ptr nocapture) #0869declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1870 871declare void @use.i64(i64)872 873define i64 @test_a_not_captured_at_all(ptr %ptr, ptr %ptr.2, i1 %c) {874; CHECK-LABEL: @test_a_not_captured_at_all(875; CHECK-NEXT: entry:876; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8877; CHECK-NEXT: [[B:%.*]] = alloca i64, align 8878; CHECK-NEXT: store ptr [[B]], ptr [[PTR:%.*]], align 8879; CHECK-NEXT: [[LV_1:%.*]] = load ptr, ptr [[PTR_2:%.*]], align 8880; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[THEN:%.*]]881; CHECK: then:882; CHECK-NEXT: [[LV_2:%.*]] = load i64, ptr [[LV_1]], align 4883; CHECK-NEXT: call void @use.i64(i64 [[LV_2]])884; CHECK-NEXT: br label [[EXIT]]885; CHECK: exit:886; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[A]])887; CHECK-NEXT: call void @clobber()888; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[A]], i8 0, i64 8, i1 false)889; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[A]], align 4890; CHECK-NEXT: ret i64 [[L]]891;892entry:893 %a = alloca i64, align 8894 %b = alloca i64, align 8895 store ptr %b, ptr %ptr, align 8896 %lv.1 = load ptr, ptr %ptr.2, align 8897 br i1 %c, label %exit, label %then898 899then:900 %lv.2 = load i64, ptr %lv.1901 call void @use.i64(i64 %lv.2)902 br label %exit903 904exit:905 call void @llvm.lifetime.start.p0(ptr %a)906 store i64 99, ptr %a907 call void @clobber()908 call void @llvm.memset.p0.i64(ptr %a, i8 0, i64 8, i1 false)909 %l = load i64, ptr %a910 ret i64 %l911}912 913define i32 @test_not_captured_both_paths_1(ptr %in.ptr, i1 %c.1) {914; CHECK-LABEL: @test_not_captured_both_paths_1(915; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4916; CHECK-NEXT: store i32 55, ptr [[A]], align 4917; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]918; CHECK: then:919; CHECK-NEXT: store i32 99, ptr [[A]], align 4920; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])921; CHECK-NEXT: br label [[EXIT:%.*]]922; CHECK: else:923; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2924; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2925; CHECK-NEXT: store i32 99, ptr [[A]], align 4926; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])927; CHECK-NEXT: br label [[EXIT]]928; CHECK: exit:929; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]930; CHECK-NEXT: call void @clobber()931; CHECK-NEXT: ret i32 [[P]]932;933 %a = alloca i32, align 4934 store i32 55, ptr %a935 br i1 %c.1, label %then, label %else936 937then:938 store i32 99, ptr %a, align 4939 call void @escape_writeonly(ptr %a)940 br label %exit941 942else:943 %in.lv.1 = load ptr , ptr %in.ptr, align 2944 %in.lv.2 = load i32 , ptr %in.lv.1, align 2945 store i32 99, ptr %a, align 4946 call void @escape_writeonly(ptr %a)947 br label %exit948 949exit:950 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]951 call void @clobber()952 ret i32 %p953}954 955define i32 @test_not_captured_both_paths_2(ptr %in.ptr, i1 %c.1) {956; CHECK-LABEL: @test_not_captured_both_paths_2(957; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4958; CHECK-NEXT: store i32 55, ptr [[A]], align 4959; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]960; CHECK: then:961; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2962; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2963; CHECK-NEXT: store i32 99, ptr [[A]], align 4964; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])965; CHECK-NEXT: br label [[EXIT:%.*]]966; CHECK: else:967; CHECK-NEXT: store i32 99, ptr [[A]], align 4968; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])969; CHECK-NEXT: br label [[EXIT]]970; CHECK: exit:971; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ELSE]] ]972; CHECK-NEXT: call void @clobber()973; CHECK-NEXT: ret i32 [[P]]974;975 %a = alloca i32, align 4976 store i32 55, ptr %a977 br i1 %c.1, label %then, label %else978 979then:980 %in.lv.1 = load ptr , ptr %in.ptr, align 2981 %in.lv.2 = load i32 , ptr %in.lv.1, align 2982 store i32 99, ptr %a, align 4983 call void @escape_writeonly(ptr %a)984 br label %exit985 986else:987 store i32 99, ptr %a, align 4988 call void @escape_writeonly(ptr %a)989 br label %exit990 991exit:992 %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]993 call void @clobber()994 ret i32 %p995}996 997define i32 @test_captured_before_store_both_paths_2(ptr %in.ptr, i1 %c.1) {998; CHECK-LABEL: @test_captured_before_store_both_paths_2(999; CHECK-NEXT: [[A:%.*]] = alloca i32, align 41000; CHECK-NEXT: store i32 55, ptr [[A]], align 41001; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]1002; CHECK: then:1003; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])1004; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 21005; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 21006; CHECK-NEXT: store i32 99, ptr [[A]], align 41007; CHECK-NEXT: br label [[EXIT:%.*]]1008; CHECK: else:1009; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])1010; CHECK-NEXT: store i32 99, ptr [[A]], align 41011; CHECK-NEXT: br label [[EXIT]]1012; CHECK: exit:1013; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ELSE]] ]1014; CHECK-NEXT: call void @clobber()1015; CHECK-NEXT: ret i32 [[P]]1016;1017 %a = alloca i32, align 41018 store i32 55, ptr %a1019 br i1 %c.1, label %then, label %else1020 1021then:1022 call void @escape_writeonly(ptr %a)1023 %in.lv.1 = load ptr , ptr %in.ptr, align 21024 %in.lv.2 = load i32 , ptr %in.lv.1, align 21025 store i32 99, ptr %a, align 41026 br label %exit1027 1028else:1029 call void @escape_writeonly(ptr %a)1030 store i32 99, ptr %a, align 41031 br label %exit1032 1033exit:1034 %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]1035 call void @clobber()1036 ret i32 %p1037}1038 1039 1040declare noalias ptr @alloc() nounwind1041 1042define i32 @test_not_captured_before_load_same_bb_noalias_call(ptr %in.ptr) {1043; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call(1044; CHECK-NEXT: [[A:%.*]] = call ptr @alloc()1045; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 21046; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 21047; CHECK-NEXT: store i32 99, ptr [[A]], align 41048; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])1049; CHECK-NEXT: ret i32 [[IN_LV_2]]1050;1051 %a = call ptr @alloc()1052 store i32 55, ptr %a1053 %in.lv.1 = load ptr , ptr %in.ptr, align 21054 %in.lv.2 = load i32 , ptr %in.lv.1, align 21055 store i32 99, ptr %a, align 41056 call void @escape_and_clobber(ptr %a)1057 ret i32 %in.lv.21058}1059 1060define i32 @test_not_captured_before_load_same_bb_noalias_arg(ptr %in.ptr, ptr noalias %a) {1061; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg(1062; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 21063; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 21064; CHECK-NEXT: store i32 99, ptr [[A:%.*]], align 41065; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])1066; CHECK-NEXT: ret i32 [[IN_LV_2]]1067;1068 store i32 55, ptr %a1069 %in.lv.1 = load ptr , ptr %in.ptr, align 21070 %in.lv.2 = load i32 , ptr %in.lv.1, align 21071 store i32 99, ptr %a, align 41072 call void @escape_and_clobber(ptr %a)1073 ret i32 %in.lv.21074}1075 1076define i32 @instruction_captures_multiple_objects(ptr %p.1, ptr %p.2, ptr %p.3, i1 %c) {1077; CHECK-LABEL: @instruction_captures_multiple_objects(1078; CHECK-NEXT: entry:1079; CHECK-NEXT: [[A_1:%.*]] = alloca i32, align 41080; CHECK-NEXT: [[A_2:%.*]] = alloca i32, align 41081; CHECK-NEXT: store i32 0, ptr [[P_1:%.*]], align 81082; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]1083; CHECK: then:1084; CHECK-NEXT: [[LV_2:%.*]] = load ptr, ptr [[P_2:%.*]], align 81085; CHECK-NEXT: [[LV_2_2:%.*]] = load i32, ptr [[LV_2]], align 41086; CHECK-NEXT: ret i32 [[LV_2_2]]1087; CHECK: else:1088; CHECK-NEXT: [[LV_3:%.*]] = load ptr, ptr [[P_3:%.*]], align 81089; CHECK-NEXT: [[LV_3_2:%.*]] = load i32, ptr [[LV_3]], align 41090; CHECK-NEXT: call void @capture_and_clobber_multiple(ptr [[A_1]], ptr [[A_2]])1091; CHECK-NEXT: ret i32 [[LV_3_2]]1092;1093entry:1094 %a.1 = alloca i321095 %a.2 = alloca i321096 store i32 0, ptr %p.1, align 81097 br i1 %c, label %then, label %else1098 1099then:1100 store i32 99, ptr %a.2, align 41101 %lv.2 = load ptr, ptr %p.21102 %lv.2.2 = load i32, ptr %lv.21103 store i32 0, ptr %a.1, align 81104 ret i32 %lv.2.21105 1106else:1107 %lv.3 = load ptr, ptr %p.31108 %lv.3.2 = load i32, ptr %lv.31109 call void @capture_and_clobber_multiple(ptr %a.1, ptr %a.2)1110 ret i32 %lv.3.21111}1112 1113declare void @capture_and_clobber_multiple(ptr, ptr)1114 1115declare void @llvm.lifetime.end.p0(ptr nocapture)1116 1117define i64 @earliest_escape_ptrtoint(ptr %p.1) {1118; CHECK-LABEL: @earliest_escape_ptrtoint(1119; CHECK-NEXT: entry:1120; CHECK-NEXT: [[A_1:%.*]] = alloca i64, align 81121; CHECK-NEXT: [[A_2:%.*]] = alloca i64, align 81122; CHECK-NEXT: [[LV_1:%.*]] = load ptr, ptr [[P_1:%.*]], align 81123; CHECK-NEXT: [[LV_2:%.*]] = load i64, ptr [[LV_1]], align 41124; CHECK-NEXT: store ptr [[A_1]], ptr [[P_1]], align 81125; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[A_2]])1126; CHECK-NEXT: ret i64 [[LV_2]]1127;1128entry:1129 %a.1 = alloca i641130 %a.2 = alloca i641131 store i64 99, ptr %a.11132 %lv.1 = load ptr, ptr %p.11133 %lv.2 = load i64, ptr %lv.11134 store ptr %a.1, ptr %p.1, align 81135 %int = ptrtoint ptr %a.2 to i641136 store i64 %int , ptr %a.2, align 81137 call void @llvm.lifetime.end.p0(ptr %a.2)1138 ret i64 %lv.21139}1140 1141define i32 @test_not_captured_before_load_of_ptrtoint(i64 %in) {1142; CHECK-LABEL: @test_not_captured_before_load_of_ptrtoint(1143; CHECK-NEXT: [[A:%.*]] = alloca i32, align 41144; CHECK-NEXT: [[IN_PTR:%.*]] = inttoptr i64 [[IN:%.*]] to ptr1145; CHECK-NEXT: [[IN_PTR_LOAD:%.*]] = load i32, ptr [[IN_PTR]], align 41146; CHECK-NEXT: store i32 99, ptr [[A]], align 41147; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])1148; CHECK-NEXT: ret i32 [[IN_PTR_LOAD]]1149;1150 %a = alloca i32, align 41151 store i32 55, ptr %a1152 %in.ptr = inttoptr i64 %in to ptr1153 %in.ptr.load = load i32, ptr %in.ptr1154 store i32 99, ptr %a1155 call void @escape_and_clobber(ptr %a)1156 ret i32 %in.ptr.load1157}1158 1159declare ptr @getptr()1160 1161define i32 @test_not_captured_before_load_of_call() {1162; CHECK-LABEL: @test_not_captured_before_load_of_call(1163; CHECK-NEXT: [[A:%.*]] = alloca i32, align 41164; CHECK-NEXT: [[IN_PTR:%.*]] = call ptr @getptr() #[[ATTR4:[0-9]+]]1165; CHECK-NEXT: [[IN_PTR_LOAD:%.*]] = load i32, ptr [[IN_PTR]], align 41166; CHECK-NEXT: store i32 99, ptr [[A]], align 41167; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])1168; CHECK-NEXT: ret i32 [[IN_PTR_LOAD]]1169;1170 %a = alloca i32, align 41171 store i32 55, ptr %a1172 %in.ptr = call ptr @getptr() readnone1173 %in.ptr.load = load i32, ptr %in.ptr1174 store i32 99, ptr %a1175 call void @escape_and_clobber(ptr %a)1176 ret i32 %in.ptr.load1177}1178 1179define i32 @test_not_captured_multiple_objects(i1 %c, ptr %in.ptr) {1180; CHECK-LABEL: @test_not_captured_multiple_objects(1181; CHECK-NEXT: [[A:%.*]] = alloca i32, align 41182; CHECK-NEXT: [[B:%.*]] = alloca i32, align 41183; CHECK-NEXT: [[O:%.*]] = select i1 [[C:%.*]], ptr [[A]], ptr [[B]]1184; CHECK-NEXT: [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 21185; CHECK-NEXT: [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 21186; CHECK-NEXT: store i32 99, ptr [[O]], align 41187; CHECK-NEXT: call void @escape_and_clobber(ptr [[O]])1188; CHECK-NEXT: ret i32 [[IN_LV_2]]1189;1190 %a = alloca i32, align 41191 %b = alloca i32, align 41192 %o = select i1 %c, ptr %a, ptr %b1193 store i32 55, ptr %o1194 %in.lv.1 = load ptr , ptr %in.ptr, align 21195 %in.lv.2 = load i32 , ptr %in.lv.1, align 21196 store i32 99, ptr %o1197 call void @escape_and_clobber(ptr %o)1198 ret i32 %in.lv.21199}1200