592 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=early-cse -earlycse-debug-hash < %s | FileCheck %s --check-prefixes=CHECK,NO_ASSUME3; RUN: opt < %s -S -passes='early-cse<memssa>' | FileCheck %s --check-prefixes=CHECK,NO_ASSUME4; RUN: opt < %s -S -passes='early-cse<memssa>' --enable-knowledge-retention | FileCheck %s --check-prefixes=CHECK,USE_ASSUME5 6declare void @llvm.experimental.guard(i1,...)7 8declare void @llvm.assume(i1)9 10define i32 @test0(ptr %ptr, i1 %cond) {11; We can do store to load forwarding over a guard, since it does not12; clobber memory13; NO_ASSUME-LABEL: @test0(14; NO_ASSUME-NEXT: store i32 40, ptr [[PTR:%.*]], align 415; NO_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"() ]16; NO_ASSUME-NEXT: ret i32 4017;18; USE_ASSUME-LABEL: @test0(19; USE_ASSUME-NEXT: store i32 40, ptr [[PTR:%.*]], align 420; USE_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"() ]21; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]22; USE_ASSUME-NEXT: ret i32 4023;24 25 store i32 40, ptr %ptr26 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]27 %rval = load i32, ptr %ptr28 ret i32 %rval29}30 31define i32 @test1(ptr %val, i1 %cond) {32; We can CSE loads over a guard, since it does not clobber memory33; NO_ASSUME-LABEL: @test1(34; NO_ASSUME-NEXT: [[VAL0:%.*]] = load i32, ptr [[VAL:%.*]], align 435; NO_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"() ]36; NO_ASSUME-NEXT: ret i32 037;38; USE_ASSUME-LABEL: @test1(39; USE_ASSUME-NEXT: [[VAL0:%.*]] = load i32, ptr [[VAL:%.*]], align 440; USE_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"() ]41; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[VAL]], i64 4), "nonnull"(ptr [[VAL]]), "align"(ptr [[VAL]], i64 4) ]42; USE_ASSUME-NEXT: ret i32 043;44 45 %val0 = load i32, ptr %val46 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]47 %val1 = load i32, ptr %val48 %rval = sub i32 %val0, %val149 ret i32 %rval50}51 52define i32 @test2() {53; Guards on "true" get removed54; CHECK-LABEL: @test2(55; CHECK-NEXT: ret i32 056;57 call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]58 ret i32 059}60 61define i32 @test3(i32 %val) {62; After a guard has executed the condition it was guarding is known to63; be true.64; CHECK-LABEL: @test3(65; CHECK-NEXT: [[COND0:%.*]] = icmp slt i32 [[VAL:%.*]], 4066; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND0]]) [ "deopt"() ]67; CHECK-NEXT: ret i32 -168;69 70 %cond0 = icmp slt i32 %val, 4071 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ]72 %cond1 = icmp slt i32 %val, 4073 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]74 75 %cond2 = icmp slt i32 %val, 4076 %rval = sext i1 %cond2 to i3277 ret i32 %rval78}79 80define i32 @test3.unhandled(i32 %val) {81; After a guard has executed the condition it was guarding is known to82; be true.83; CHECK-LABEL: @test3.unhandled(84; CHECK-NEXT: [[COND0:%.*]] = icmp slt i32 [[VAL:%.*]], 4085; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND0]]) [ "deopt"() ]86; CHECK-NEXT: [[COND1:%.*]] = icmp sge i32 [[VAL]], 4087; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND1]]) [ "deopt"() ]88; CHECK-NEXT: ret i32 089;90 91; Demonstrates a case we do not yet handle (it is legal to fold %cond292; to false)93 %cond0 = icmp slt i32 %val, 4094 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ]95 %cond1 = icmp sge i32 %val, 4096 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]97 ret i32 098}99 100define i32 @test4(i32 %val, i1 %c) {101; Same as test3, but with some control flow involved.102; CHECK-LABEL: @test4(103; CHECK-NEXT: entry:104; CHECK-NEXT: [[COND0:%.*]] = icmp slt i32 [[VAL:%.*]], 40105; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND0]]) [ "deopt"() ]106; CHECK-NEXT: br label [[BB0:%.*]]107; CHECK: bb0:108; CHECK-NEXT: [[COND2:%.*]] = icmp ult i32 [[VAL]], 200109; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND2]]) [ "deopt"() ]110; CHECK-NEXT: br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]111; CHECK: left:112; CHECK-NEXT: ret i32 0113; CHECK: right:114; CHECK-NEXT: ret i32 20115;116 117 118 119 120entry:121 %cond0 = icmp slt i32 %val, 40122 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ]123 %cond1 = icmp slt i32 %val, 40124 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]125 br label %bb0126 127bb0:128 %cond2 = icmp ult i32 %val, 200129 call void(i1,...) @llvm.experimental.guard(i1 %cond2) [ "deopt"() ]130 br i1 %c, label %left, label %right131 132left:133 %cond3 = icmp ult i32 %val, 200134 call void(i1,...) @llvm.experimental.guard(i1 %cond3) [ "deopt"() ]135 ret i32 0136 137right:138 ret i32 20139}140 141define i32 @test5(i32 %val, i1 %c) {142; Same as test4, but the %left block has multiple predecessors.143; CHECK-LABEL: @test5(144; CHECK-NEXT: entry:145; CHECK-NEXT: [[COND0:%.*]] = icmp slt i32 [[VAL:%.*]], 40146; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND0]]) [ "deopt"() ]147; CHECK-NEXT: br label [[BB0:%.*]]148; CHECK: bb0:149; CHECK-NEXT: [[COND2:%.*]] = icmp ult i32 [[VAL]], 200150; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND2]]) [ "deopt"() ]151; CHECK-NEXT: br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]152; CHECK: left:153; CHECK-NEXT: br label [[RIGHT]]154; CHECK: right:155; CHECK-NEXT: br label [[LEFT]]156;157 158 159 160 161 162entry:163 %cond0 = icmp slt i32 %val, 40164 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ]165 %cond1 = icmp slt i32 %val, 40166 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]167 br label %bb0168 169bb0:170 %cond2 = icmp ult i32 %val, 200171 call void(i1,...) @llvm.experimental.guard(i1 %cond2) [ "deopt"() ]172 br i1 %c, label %left, label %right173 174left:175 %cond3 = icmp ult i32 %val, 200176 call void(i1,...) @llvm.experimental.guard(i1 %cond3) [ "deopt"() ]177 br label %right178 179right:180 br label %left181}182 183define void @test6(i1 %c, ptr %ptr) {184; Check that we do not DSE over calls to @llvm.experimental.guard.185; Guard intrinsics do _read_ memory, so th call to guard below needs186; to see the store of 500 to %ptr187; CHECK-LABEL: @test6(188; CHECK-NEXT: store i32 500, ptr [[PTR:%.*]], align 4189; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[C:%.*]]) [ "deopt"() ]190; CHECK-NEXT: store i32 600, ptr [[PTR]], align 4191; CHECK-NEXT: ret void192;193 194 195 store i32 500, ptr %ptr196 call void(i1,...) @llvm.experimental.guard(i1 %c) [ "deopt"() ]197 store i32 600, ptr %ptr198 ret void199}200 201define void @test07(i32 %a, i32 %b) {202; Check that we are able to remove the guards on the same condition even if the203; condition is not being recalculated.204; CHECK-LABEL: @test07(205; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]206; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]207; CHECK-NEXT: ret void208;209 210 %cmp = icmp eq i32 %a, %b211 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]212 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]213 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]214 ret void215}216 217define void @test08(i32 %a, i32 %b, ptr %ptr) {218; Check that we deal correctly with stores when removing guards in the same219; block in case when the condition is not recalculated.220; NO_ASSUME-LABEL: @test08(221; NO_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]222; NO_ASSUME-NEXT: store i32 100, ptr [[PTR:%.*]], align 4223; NO_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]224; NO_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4225; NO_ASSUME-NEXT: ret void226;227; USE_ASSUME-LABEL: @test08(228; USE_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]229; USE_ASSUME-NEXT: store i32 100, ptr [[PTR:%.*]], align 4230; USE_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]231; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]232; USE_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4233; USE_ASSUME-NEXT: ret void234;235 236 %cmp = icmp eq i32 %a, %b237 store i32 100, ptr %ptr238 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]239 store i32 200, ptr %ptr240 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]241 store i32 300, ptr %ptr242 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]243 store i32 400, ptr %ptr244 ret void245}246 247define void @test09(i32 %a, i32 %b, i1 %c, ptr %ptr) {248; Similar to test08, but with more control flow.249; TODO: Can we get rid of the store in the end of entry given that it is250; post-dominated by other stores?251; NO_ASSUME-LABEL: @test09(252; NO_ASSUME-NEXT: entry:253; NO_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]254; NO_ASSUME-NEXT: store i32 100, ptr [[PTR:%.*]], align 4255; NO_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]256; NO_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4257; NO_ASSUME-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]258; NO_ASSUME: if.true:259; NO_ASSUME-NEXT: store i32 500, ptr [[PTR]], align 4260; NO_ASSUME-NEXT: br label [[MERGE:%.*]]261; NO_ASSUME: if.false:262; NO_ASSUME-NEXT: store i32 600, ptr [[PTR]], align 4263; NO_ASSUME-NEXT: br label [[MERGE]]264; NO_ASSUME: merge:265; NO_ASSUME-NEXT: ret void266;267; USE_ASSUME-LABEL: @test09(268; USE_ASSUME-NEXT: entry:269; USE_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]270; USE_ASSUME-NEXT: store i32 100, ptr [[PTR:%.*]], align 4271; USE_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]272; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]273; USE_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4274; USE_ASSUME-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]275; USE_ASSUME: if.true:276; USE_ASSUME-NEXT: store i32 500, ptr [[PTR]], align 4277; USE_ASSUME-NEXT: br label [[MERGE:%.*]]278; USE_ASSUME: if.false:279; USE_ASSUME-NEXT: store i32 600, ptr [[PTR]], align 4280; USE_ASSUME-NEXT: br label [[MERGE]]281; USE_ASSUME: merge:282; USE_ASSUME-NEXT: ret void283;284 285entry:286 %cmp = icmp eq i32 %a, %b287 store i32 100, ptr %ptr288 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]289 store i32 200, ptr %ptr290 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]291 store i32 300, ptr %ptr292 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]293 store i32 400, ptr %ptr294 br i1 %c, label %if.true, label %if.false295 296if.true:297 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]298 store i32 500, ptr %ptr299 br label %merge300 301if.false:302 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]303 store i32 600, ptr %ptr304 br label %merge305 306merge:307 ret void308}309 310define void @test10(i32 %a, i32 %b, i1 %c, ptr %ptr) {311; Make sure that non-dominating guards do not cause other guards removal.312; CHECK-LABEL: @test10(313; CHECK-NEXT: entry:314; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]315; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]316; CHECK: if.true:317; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]318; CHECK-NEXT: store i32 100, ptr [[PTR:%.*]], align 4319; CHECK-NEXT: br label [[MERGE:%.*]]320; CHECK: if.false:321; CHECK-NEXT: store i32 200, ptr [[PTR]], align 4322; CHECK-NEXT: br label [[MERGE]]323; CHECK: merge:324; CHECK-NEXT: store i32 300, ptr [[PTR]], align 4325; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]326; CHECK-NEXT: store i32 400, ptr [[PTR]], align 4327; CHECK-NEXT: ret void328;329 330entry:331 %cmp = icmp eq i32 %a, %b332 br i1 %c, label %if.true, label %if.false333 334if.true:335 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]336 store i32 100, ptr %ptr337 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]338 br label %merge339 340if.false:341 store i32 200, ptr %ptr342 br label %merge343 344merge:345 store i32 300, ptr %ptr346 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]347 store i32 400, ptr %ptr348 ret void349}350 351define void @test11(i32 %a, i32 %b, ptr %ptr) {352; Make sure that branching condition is applied to guards.353; CHECK-LABEL: @test11(354; CHECK-NEXT: entry:355; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]356; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]357; CHECK: if.true:358; CHECK-NEXT: br label [[MERGE:%.*]]359; CHECK: if.false:360; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]361; CHECK-NEXT: br label [[MERGE]]362; CHECK: merge:363; CHECK-NEXT: ret void364;365 366entry:367 %cmp = icmp eq i32 %a, %b368 br i1 %cmp, label %if.true, label %if.false369 370if.true:371 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]372 br label %merge373 374if.false:375 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]376 br label %merge377 378merge:379 ret void380}381 382define void @test12(i32 %a, i32 %b) {383; Check that the assume marks its condition as being true (and thus allows to384; eliminate the dominated guards).385; CHECK-LABEL: @test12(386; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]387; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])388; CHECK-NEXT: ret void389;390 391 %cmp = icmp eq i32 %a, %b392 call void @llvm.assume(i1 %cmp)393 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]394 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]395 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]396 ret void397}398 399define void @test13(i32 %a, i32 %b, ptr %ptr) {400; Check that we deal correctly with stores when removing guards due to assume.401; NO_ASSUME-LABEL: @test13(402; NO_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]403; NO_ASSUME-NEXT: call void @llvm.assume(i1 [[CMP]])404; NO_ASSUME-NEXT: store i32 400, ptr [[PTR:%.*]], align 4405; NO_ASSUME-NEXT: ret void406;407; USE_ASSUME-LABEL: @test13(408; USE_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]409; USE_ASSUME-NEXT: call void @llvm.assume(i1 [[CMP]])410; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR:%.*]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]411; USE_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4412; USE_ASSUME-NEXT: ret void413;414 415 %cmp = icmp eq i32 %a, %b416 call void @llvm.assume(i1 %cmp)417 store i32 100, ptr %ptr418 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]419 store i32 200, ptr %ptr420 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]421 store i32 300, ptr %ptr422 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]423 store i32 400, ptr %ptr424 ret void425}426 427define void @test14(i32 %a, i32 %b, i1 %c, ptr %ptr) {428; Similar to test13, but with more control flow.429; TODO: Can we get rid of the store in the end of entry given that it is430; post-dominated by other stores?431; NO_ASSUME-LABEL: @test14(432; NO_ASSUME-NEXT: entry:433; NO_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]434; NO_ASSUME-NEXT: call void @llvm.assume(i1 [[CMP]])435; NO_ASSUME-NEXT: store i32 400, ptr [[PTR:%.*]], align 4436; NO_ASSUME-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]437; NO_ASSUME: if.true:438; NO_ASSUME-NEXT: store i32 500, ptr [[PTR]], align 4439; NO_ASSUME-NEXT: br label [[MERGE:%.*]]440; NO_ASSUME: if.false:441; NO_ASSUME-NEXT: store i32 600, ptr [[PTR]], align 4442; NO_ASSUME-NEXT: br label [[MERGE]]443; NO_ASSUME: merge:444; NO_ASSUME-NEXT: ret void445;446; USE_ASSUME-LABEL: @test14(447; USE_ASSUME-NEXT: entry:448; USE_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]449; USE_ASSUME-NEXT: call void @llvm.assume(i1 [[CMP]])450; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR:%.*]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]451; USE_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4452; USE_ASSUME-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]453; USE_ASSUME: if.true:454; USE_ASSUME-NEXT: store i32 500, ptr [[PTR]], align 4455; USE_ASSUME-NEXT: br label [[MERGE:%.*]]456; USE_ASSUME: if.false:457; USE_ASSUME-NEXT: store i32 600, ptr [[PTR]], align 4458; USE_ASSUME-NEXT: br label [[MERGE]]459; USE_ASSUME: merge:460; USE_ASSUME-NEXT: ret void461;462 463entry:464 %cmp = icmp eq i32 %a, %b465 call void @llvm.assume(i1 %cmp)466 store i32 100, ptr %ptr467 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]468 store i32 200, ptr %ptr469 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]470 store i32 300, ptr %ptr471 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]472 store i32 400, ptr %ptr473 br i1 %c, label %if.true, label %if.false474 475if.true:476 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]477 store i32 500, ptr %ptr478 br label %merge479 480if.false:481 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]482 store i32 600, ptr %ptr483 br label %merge484 485merge:486 ret void487}488 489define void @test15(i32 %a, i32 %b, i1 %c, ptr %ptr) {490; Make sure that non-dominating assumes do not cause guards removal.491; CHECK-LABEL: @test15(492; CHECK-NEXT: entry:493; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]494; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]495; CHECK: if.true:496; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])497; CHECK-NEXT: store i32 100, ptr [[PTR:%.*]], align 4498; CHECK-NEXT: br label [[MERGE:%.*]]499; CHECK: if.false:500; CHECK-NEXT: store i32 200, ptr [[PTR]], align 4501; CHECK-NEXT: br label [[MERGE]]502; CHECK: merge:503; CHECK-NEXT: store i32 300, ptr [[PTR]], align 4504; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]505; CHECK-NEXT: store i32 400, ptr [[PTR]], align 4506; CHECK-NEXT: ret void507;508 509entry:510 %cmp = icmp eq i32 %a, %b511 br i1 %c, label %if.true, label %if.false512 513if.true:514 call void @llvm.assume(i1 %cmp)515 store i32 100, ptr %ptr516 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]517 br label %merge518 519if.false:520 store i32 200, ptr %ptr521 br label %merge522 523merge:524 store i32 300, ptr %ptr525 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]526 store i32 400, ptr %ptr527 ret void528}529 530define void @test16(i32 %a, i32 %b) {531; Check that we don't bother to do anything with assumes even if we know the532; condition being true.533; CHECK-LABEL: @test16(534; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]535; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])536; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])537; CHECK-NEXT: ret void538;539 540 %cmp = icmp eq i32 %a, %b541 call void @llvm.assume(i1 %cmp)542 call void @llvm.assume(i1 %cmp)543 ret void544}545 546define void @test17(i32 %a, i32 %b, i1 %c, ptr %ptr) {547; Check that we don't bother to do anything with assumes even if we know the548; condition being true or false (includes come control flow).549; CHECK-LABEL: @test17(550; CHECK-NEXT: entry:551; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]552; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]553; CHECK: if.true:554; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])555; CHECK-NEXT: br label [[MERGE:%.*]]556; CHECK: if.false:557; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])558; CHECK-NEXT: br label [[MERGE]]559; CHECK: merge:560; CHECK-NEXT: ret void561;562 563entry:564 %cmp = icmp eq i32 %a, %b565 br i1 %c, label %if.true, label %if.false566 567if.true:568 call void @llvm.assume(i1 %cmp)569 br label %merge570 571if.false:572 call void @llvm.assume(i1 %cmp)573 br label %merge574 575merge:576 ret void577}578 579define void @test18(i1 %c) {580; Check that we don't bother to do anything with assumes even if we know the581; condition being true and not being an instruction.582; CHECK-LABEL: @test18(583; CHECK-NEXT: call void @llvm.assume(i1 [[C:%.*]])584; CHECK-NEXT: call void @llvm.assume(i1 [[C]])585; CHECK-NEXT: ret void586;587 588 call void @llvm.assume(i1 %c)589 call void @llvm.assume(i1 %c)590 ret void591}592