597 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4declare void @llvm.assume(i1)5 6declare void @may_unwind()7 8declare void @use(i1)9 10define i1 @assume_dominates(i8 %a, i8 %b, i1 %c) {11; CHECK-LABEL: @assume_dominates(12; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 113; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]14; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])15; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]16; CHECK: then:17; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true18; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 219; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]20; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]21; CHECK-NEXT: ret i1 [[RES_2]]22; CHECK: else:23; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, true24; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 225; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]26; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]27; CHECK-NEXT: ret i1 [[RES_4]]28;29 %add.1 = add nsw nuw i8 %a, 130 %cmp.1 = icmp ule i8 %add.1, %b31 call void @llvm.assume(i1 %cmp.1)32 br i1 %c, label %then, label %else33 34then:35 %t.1 = icmp ule i8 %add.1, %b36 %t.2 = icmp ule i8 %a, %b37 %res.1 = xor i1 %t.1, %t.238 %add.2 = add nsw nuw i8 %a, 239 %c.1 = icmp ule i8 %add.2, %b40 %res.2 = xor i1 %res.1, %c.141 ret i1 %res.242 43else:44 %t.3 = icmp ule i8 %add.1, %b45 %t.4 = icmp ule i8 %a, %b46 %res.3 = xor i1 %t.3, %t.447 %add.2.1 = add nsw nuw i8 %a, 248 %c.2 = icmp ule i8 %add.2.1, %b49 %res.4 = xor i1 %res.3, %c.250 ret i1 %res.451}52 53define i1 @assume_dominates_with_may_unwind_call_before_assume(i8 %a, i8 %b, i1 %c) {54; CHECK-LABEL: @assume_dominates_with_may_unwind_call_before_assume(55; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 156; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]57; CHECK-NEXT: call void @may_unwind()58; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])59; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]60; CHECK: then:61; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true62; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 263; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]64; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]65; CHECK-NEXT: ret i1 [[RES_2]]66; CHECK: else:67; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, true68; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 269; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]70; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]71; CHECK-NEXT: ret i1 [[RES_4]]72;73 %add.1 = add nsw nuw i8 %a, 174 %cmp.1 = icmp ule i8 %add.1, %b75 call void @may_unwind()76 call void @llvm.assume(i1 %cmp.1)77 br i1 %c, label %then, label %else78 79then:80 %t.1 = icmp ule i8 %add.1, %b81 %t.2 = icmp ule i8 %a, %b82 %res.1 = xor i1 %t.1, %t.283 %add.2 = add nsw nuw i8 %a, 284 %c.1 = icmp ule i8 %add.2, %b85 %res.2 = xor i1 %res.1, %c.186 ret i1 %res.287 88else:89 %t.3 = icmp ule i8 %add.1, %b90 %t.4 = icmp ule i8 %a, %b91 %res.3 = xor i1 %t.3, %t.492 %add.2.1 = add nsw nuw i8 %a, 293 %c.2 = icmp ule i8 %add.2.1, %b94 %res.4 = xor i1 %res.3, %c.295 ret i1 %res.496}97 98define i1 @assume_dominates_with_may_unwind_call_after_assume(i8 %a, i8 %b, i1 %c) {99; CHECK-LABEL: @assume_dominates_with_may_unwind_call_after_assume(100; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1101; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]102; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])103; CHECK-NEXT: call void @may_unwind()104; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]105; CHECK: then:106; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true107; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2108; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]109; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]110; CHECK-NEXT: ret i1 [[RES_2]]111; CHECK: else:112; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, true113; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2114; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]115; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]116; CHECK-NEXT: ret i1 [[RES_4]]117;118 %add.1 = add nsw nuw i8 %a, 1119 %cmp.1 = icmp ule i8 %add.1, %b120 call void @llvm.assume(i1 %cmp.1)121 call void @may_unwind()122 br i1 %c, label %then, label %else123 124then:125 %t.1 = icmp ule i8 %add.1, %b126 %t.2 = icmp ule i8 %a, %b127 %res.1 = xor i1 %t.1, %t.2128 %add.2 = add nsw nuw i8 %a, 2129 %c.1 = icmp ule i8 %add.2, %b130 %res.2 = xor i1 %res.1, %c.1131 ret i1 %res.2132 133else:134 %t.3 = icmp ule i8 %add.1, %b135 %t.4 = icmp ule i8 %a, %b136 %res.3 = xor i1 %t.3, %t.4137 %add.2.1 = add nsw nuw i8 %a, 2138 %c.2 = icmp ule i8 %add.2.1, %b139 %res.4 = xor i1 %res.3, %c.2140 ret i1 %res.4141}142 143; Test case from PR54217.144define i1 @assume_does_not_dominates_successor_with_may_unwind_call_before_assume(i16 %a, i1 %i.0) {145; CHECK-LABEL: @assume_does_not_dominates_successor_with_may_unwind_call_before_assume(146; CHECK-NEXT: entry:147; CHECK-NEXT: br i1 [[I_0:%.*]], label [[EXIT:%.*]], label [[IF_THEN:%.*]]148; CHECK: if.then:149; CHECK-NEXT: call void @may_unwind()150; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[A:%.*]], 0151; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])152; CHECK-NEXT: br label [[EXIT]]153; CHECK: exit:154; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[A]], 0155; CHECK-NEXT: ret i1 [[C_2]]156;157entry:158 br i1 %i.0, label %exit, label %if.then159 160if.then:161 call void @may_unwind()162 %c.1 = icmp eq i16 %a, 0163 call void @llvm.assume(i1 %c.1)164 br label %exit165 166exit:167 %c.2 = icmp eq i16 %a, 0168 ret i1 %c.2169}170 171define i1 @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch(i16 %a) {172; CHECK-LABEL: @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch(173; CHECK-NEXT: entry:174; CHECK-NEXT: call void @may_unwind()175; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[A:%.*]], 0176; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])177; CHECK-NEXT: br label [[EXIT:%.*]]178; CHECK: exit:179; CHECK-NEXT: ret i1 true180;181entry:182 call void @may_unwind()183 %c.1 = icmp eq i16 %a, 0184 call void @llvm.assume(i1 %c.1)185 br label %exit186 187exit:188 %c.2 = icmp eq i16 %a, 0189 ret i1 %c.2190}191 192define i1 @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch_2(i16 %a, i1 %c) {193; CHECK-LABEL: @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch_2(194; CHECK-NEXT: entry:195; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]196; CHECK: then:197; CHECK-NEXT: call void @may_unwind()198; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[A:%.*]], 0199; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])200; CHECK-NEXT: br label [[EXIT]]201; CHECK: exit:202; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[A]], 0203; CHECK-NEXT: ret i1 [[C_2]]204;205entry:206 br i1 %c, label %then, label %exit207 208then:209 call void @may_unwind()210 %c.1 = icmp eq i16 %a, 0211 call void @llvm.assume(i1 %c.1)212 br label %exit213 214exit:215 %c.2 = icmp eq i16 %a, 0216 ret i1 %c.2217}218 219define i1 @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch_cycle(i16 %a, i1 %c) {220; CHECK-LABEL: @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch_cycle(221; CHECK-NEXT: entry:222; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]223; CHECK: then:224; CHECK-NEXT: call void @may_unwind()225; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[A:%.*]], 0226; CHECK-NEXT: call void @use(i1 [[C_1]])227; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])228; CHECK-NEXT: br label [[THEN]]229; CHECK: exit:230; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[A]], 0231; CHECK-NEXT: ret i1 [[C_2]]232;233entry:234 br i1 %c, label %then, label %exit235 236then:237 call void @may_unwind()238 %c.1 = icmp eq i16 %a, 0239 call void @use(i1 %c.1)240 call void @llvm.assume(i1 %c.1)241 br label %then242 243exit:244 %c.2 = icmp eq i16 %a, 0245 ret i1 %c.2246}247 248define i1 @assume_single_bb(i8 %a, i8 %b, i1 %c) {249; CHECK-LABEL: @assume_single_bb(250; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1251; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]252; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])253; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true254; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2255; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]256; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]257; CHECK-NEXT: ret i1 [[RES_2]]258;259 %add.1 = add nsw nuw i8 %a, 1260 %cmp.1 = icmp ule i8 %add.1, %b261 call void @llvm.assume(i1 %cmp.1)262 %t.1 = icmp ule i8 %add.1, %b263 %t.2 = icmp ule i8 %a, %b264 %res.1 = xor i1 %t.1, %t.2265 %add.2 = add nsw nuw i8 %a, 2266 %c.1 = icmp ule i8 %add.2, %b267 %res.2 = xor i1 %res.1, %c.1268 ret i1 %res.2269}270 271define i1 @assume_same_bb(i8 %a, i8 %b, i1 %c) {272; CHECK-LABEL: @assume_same_bb(273; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1274; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]275; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]276; CHECK: then:277; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])278; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true279; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2280; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]281; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]282; CHECK-NEXT: ret i1 [[RES_2]]283; CHECK: else:284; CHECK-NEXT: [[T_3:%.*]] = icmp ule i8 [[ADD_1]], [[B]]285; CHECK-NEXT: [[T_4:%.*]] = icmp ule i8 [[A]], [[B]]286; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[T_3]], [[T_4]]287; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2288; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]289; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]290; CHECK-NEXT: ret i1 [[RES_4]]291;292 %add.1 = add nsw nuw i8 %a, 1293 %cmp.1 = icmp ule i8 %add.1, %b294 br i1 %c, label %then, label %else295 296then:297 call void @llvm.assume(i1 %cmp.1)298 %t.1 = icmp ule i8 %add.1, %b299 %t.2 = icmp ule i8 %a, %b300 %res.1 = xor i1 %t.1, %t.2301 %add.2 = add nsw nuw i8 %a, 2302 %c.1 = icmp ule i8 %add.2, %b303 %res.2 = xor i1 %res.1, %c.1304 ret i1 %res.2305 306else:307 %t.3 = icmp ule i8 %add.1, %b308 %t.4 = icmp ule i8 %a, %b309 %res.3 = xor i1 %t.3, %t.4310 %add.2.1 = add nsw nuw i8 %a, 2311 %c.2 = icmp ule i8 %add.2.1, %b312 %res.4 = xor i1 %res.3, %c.2313 ret i1 %res.4314}315 316define i1 @assume_same_bb2(i8 %a, i8 %b, i1 %c) {317; CHECK-LABEL: @assume_same_bb2(318; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1319; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]320; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])321; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true322; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2323; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]324; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]325; CHECK-NEXT: br label [[EXIT:%.*]]326; CHECK: exit:327; CHECK-NEXT: ret i1 [[RES_2]]328;329 %add.1 = add nsw nuw i8 %a, 1330 %cmp.1 = icmp ule i8 %add.1, %b331 call void @llvm.assume(i1 %cmp.1)332 %t.1 = icmp ule i8 %add.1, %b333 %t.2 = icmp ule i8 %a, %b334 %res.1 = xor i1 %t.1, %t.2335 %add.2 = add nsw nuw i8 %a, 2336 %c.1 = icmp ule i8 %add.2, %b337 %res.2 = xor i1 %res.1, %c.1338 br label %exit339 340exit:341 ret i1 %res.2342}343 344 345; TODO: Keep track of position of assume and may unwinding calls, simplify346; conditions if possible.347define i1 @assume_same_bb_after_may_exiting_call(i8 %a, i8 %b, i1 %c) {348; CHECK-LABEL: @assume_same_bb_after_may_exiting_call(349; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1350; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]351; CHECK-NEXT: call void @may_unwind()352; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])353; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true354; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2355; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]356; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]357; CHECK-NEXT: br label [[EXIT:%.*]]358; CHECK: exit:359; CHECK-NEXT: ret i1 [[RES_2]]360;361 %add.1 = add nsw nuw i8 %a, 1362 %cmp.1 = icmp ule i8 %add.1, %b363 call void @may_unwind()364 call void @llvm.assume(i1 %cmp.1)365 %t.1 = icmp ule i8 %add.1, %b366 %t.2 = icmp ule i8 %a, %b367 %res.1 = xor i1 %t.1, %t.2368 %add.2 = add nsw nuw i8 %a, 2369 %c.1 = icmp ule i8 %add.2, %b370 %res.2 = xor i1 %res.1, %c.1371 br label %exit372 373exit:374 ret i1 %res.2375}376 377; TODO: Keep track of position of assume and may unwinding calls, simplify378; conditions if possible.379define i1 @assume_same_bb_before_may_exiting_call(i8 %a, i8 %b, i1 %c) {380; CHECK-LABEL: @assume_same_bb_before_may_exiting_call(381; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1382; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]383; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])384; CHECK-NEXT: call void @may_unwind()385; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true386; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2387; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]388; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]389; CHECK-NEXT: br label [[EXIT:%.*]]390; CHECK: exit:391; CHECK-NEXT: ret i1 [[RES_2]]392;393 %add.1 = add nsw nuw i8 %a, 1394 %cmp.1 = icmp ule i8 %add.1, %b395 call void @llvm.assume(i1 %cmp.1)396 call void @may_unwind()397 %t.1 = icmp ule i8 %add.1, %b398 %t.2 = icmp ule i8 %a, %b399 %res.1 = xor i1 %t.1, %t.2400 %add.2 = add nsw nuw i8 %a, 2401 %c.1 = icmp ule i8 %add.2, %b402 %res.2 = xor i1 %res.1, %c.1403 br label %exit404 405exit:406 ret i1 %res.2407}408 409define i1 @assume_same_bb_after_condition(i8 %a, i8 %b, i1 %c) {410; CHECK-LABEL: @assume_same_bb_after_condition(411; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1412; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true413; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2414; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B:%.*]]415; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]416; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]417; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])418; CHECK-NEXT: br label [[EXIT:%.*]]419; CHECK: exit:420; CHECK-NEXT: ret i1 [[RES_2]]421;422 %add.1 = add nsw nuw i8 %a, 1423 %t.1 = icmp ule i8 %add.1, %b424 %t.2 = icmp ule i8 %a, %b425 %res.1 = xor i1 %t.1, %t.2426 %add.2 = add nsw nuw i8 %a, 2427 %c.1 = icmp ule i8 %add.2, %b428 %res.2 = xor i1 %res.1, %c.1429 %cmp.1 = icmp ule i8 %add.1, %b430 call void @llvm.assume(i1 %cmp.1)431 br label %exit432 433exit:434 ret i1 %res.2435}436 437; The function may exit before the assume if @may_unwind unwinds. Conditions438; before the call cannot be simplified.439define i1 @assume_same_bb_after_condition_may_unwind_between(i8 %a, i8 %b, i1 %c) {440; CHECK-LABEL: @assume_same_bb_after_condition_may_unwind_between(441; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1442; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]443; CHECK-NEXT: call void @use(i1 [[C_1]])444; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[A]], [[B]]445; CHECK-NEXT: call void @use(i1 [[C_2]])446; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]447; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2448; CHECK-NEXT: [[C_3:%.*]] = icmp ule i8 [[ADD_2]], [[B]]449; CHECK-NEXT: call void @use(i1 [[C_3]])450; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_3]]451; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]452; CHECK-NEXT: call void @may_unwind()453; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])454; CHECK-NEXT: br label [[EXIT:%.*]]455; CHECK: exit:456; CHECK-NEXT: ret i1 [[RES_2]]457;458 %add.1 = add nsw nuw i8 %a, 1459 %c.1 = icmp ule i8 %add.1, %b460 call void @use(i1 %c.1)461 %c.2 = icmp ule i8 %a, %b462 call void @use(i1 %c.2)463 %res.1 = xor i1 %c.1, %c.2464 %add.2 = add nsw nuw i8 %a, 2465 %c.3 = icmp ule i8 %add.2, %b466 call void @use(i1 %c.3)467 %res.2 = xor i1 %res.1, %c.3468 %cmp.1 = icmp ule i8 %add.1, %b469 call void @may_unwind()470 call void @llvm.assume(i1 %cmp.1)471 br label %exit472 473exit:474 ret i1 %res.2475}476 477; The information of from the assume can be used to simplify %t.2.478define i1 @assume_single_bb_conditions_after_assume(i8 %a, i8 %b, i1 %c) {479; CHECK-LABEL: @assume_single_bb_conditions_after_assume(480; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1481; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]482; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]483; CHECK-NEXT: call void @use(i1 [[C_1]])484; CHECK-NEXT: call void @may_unwind()485; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])486; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true487; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2488; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]489; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]490; CHECK-NEXT: ret i1 [[RES_2]]491;492 %add.1 = add nsw nuw i8 %a, 1493 %cmp.1 = icmp ule i8 %add.1, %b494 %c.1 = icmp ule i8 %add.1, %b495 call void @use(i1 %c.1)496 497 call void @may_unwind()498 call void @llvm.assume(i1 %cmp.1)499 %t.2 = icmp ule i8 %a, %b500 %res.1 = xor i1 %c.1, %t.2501 %add.2 = add nsw nuw i8 %a, 2502 %c.2 = icmp ule i8 %add.2, %b503 %res.2 = xor i1 %res.1, %c.2504 ret i1 %res.2505}506 507; The information of from the assume can be used to simplify %t.2.508; TODO509define i1 @assume_single_bb_assume_at_end_after_may_unwind(i8 %a, i8 %b, i1 %c) {510; CHECK-LABEL: @assume_single_bb_assume_at_end_after_may_unwind(511; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1512; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]513; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]514; CHECK-NEXT: call void @use(i1 [[C_1]])515; CHECK-NEXT: call void @may_unwind()516; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]517; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[T_2]]518; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2519; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]520; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]521; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])522; CHECK-NEXT: ret i1 [[RES_2]]523;524 %add.1 = add nsw nuw i8 %a, 1525 %cmp.1 = icmp ule i8 %add.1, %b526 %c.1 = icmp ule i8 %add.1, %b527 call void @use(i1 %c.1)528 529 call void @may_unwind()530 %t.2 = icmp ule i8 %a, %b531 %res.1 = xor i1 %c.1, %t.2532 %add.2 = add nsw nuw i8 %a, 2533 %c.2 = icmp ule i8 %add.2, %b534 %res.2 = xor i1 %res.1, %c.2535 call void @llvm.assume(i1 %cmp.1)536 ret i1 %res.2537}538 539; The definition of %t.2 is before the @llvm.assume call, but all uses are540; after the call. %t.2 can be simplified.541; TODO542define i1 @all_uses_after_assume(i8 %a, i8 %b, i1 %c) {543; CHECK-LABEL: @all_uses_after_assume(544; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1545; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]546; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]547; CHECK-NEXT: call void @use(i1 [[C_1]])548; CHECK-NEXT: call void @may_unwind()549; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])550; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true551; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2552; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]553; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]554; CHECK-NEXT: ret i1 [[RES_2]]555;556 %add.1 = add nsw nuw i8 %a, 1557 %cmp.1 = icmp ule i8 %add.1, %b558 %c.1 = icmp ule i8 %add.1, %b559 %t.2 = icmp ule i8 %a, %b560 call void @use(i1 %c.1)561 562 call void @may_unwind()563 call void @llvm.assume(i1 %cmp.1)564 %res.1 = xor i1 %c.1, %t.2565 %add.2 = add nsw nuw i8 %a, 2566 %c.2 = icmp ule i8 %add.2, %b567 %res.2 = xor i1 %res.1, %c.2568 ret i1 %res.2569}570 571define i1 @test_order_assume_and_conds_in_different_bb(i16 %a, ptr %dst) {572; CHECK-LABEL: @test_order_assume_and_conds_in_different_bb(573; CHECK-NEXT: entry:574; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[A:%.*]], 10575; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]576; CHECK: then:577; CHECK-NEXT: ret i1 false578; CHECK: else:579; CHECK-NEXT: store volatile float 0.000000e+00, ptr [[DST:%.*]], align 4580; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[A]], 20581; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_2]])582; CHECK-NEXT: ret i1 true583;584entry:585 %c.1 = icmp ult i16 %a, 10586 br i1 %c.1, label %then, label %else587 588then:589 ret i1 0590 591else:592 store volatile float 0.000000e+00, ptr %dst593 %c.2 = icmp eq i16 %a, 20594 tail call void @llvm.assume(i1 %c.2)595 ret i1 %c.2596}597