810 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 @use(i1)5 6define void @test_or_ule(i4 %x, i4 %y, i4 %z, i4 %a) {7; CHECK-LABEL: @test_or_ule(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[C_1:%.*]] = icmp ule i4 [[X:%.*]], [[Y:%.*]]10; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z:%.*]]11; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_1]], [[C_2]]12; CHECK-NEXT: br i1 [[OR]], label [[BB1:%.*]], label [[EXIT:%.*]]13; CHECK: bb1:14; CHECK-NEXT: [[C_3:%.*]] = icmp ule i4 [[X]], [[Z]]15; CHECK-NEXT: call void @use(i1 [[C_3]])16; CHECK-NEXT: [[C_4:%.*]] = icmp ule i4 [[X]], [[A:%.*]]17; CHECK-NEXT: call void @use(i1 [[C_4]])18; CHECK-NEXT: ret void19; CHECK: exit:20; CHECK-NEXT: call void @use(i1 false)21; CHECK-NEXT: [[C_5:%.*]] = icmp ule i4 [[X]], [[A]]22; CHECK-NEXT: call void @use(i1 [[C_5]])23; CHECK-NEXT: call void @use(i1 true)24; CHECK-NEXT: call void @use(i1 true)25; CHECK-NEXT: call void @use(i1 true)26; CHECK-NEXT: ret void27;28entry:29 %c.1 = icmp ule i4 %x, %y30 %c.2 = icmp ule i4 %y, %z31 %or = or i1 %c.1, %c.232 br i1 %or, label %bb1, label %exit33 34bb1:35 %c.3 = icmp ule i4 %x, %z36 call void @use(i1 %c.3)37 38 %c.4 = icmp ule i4 %x, %a39 call void @use(i1 %c.4)40 41 ret void42 43exit:44 %f.1 = icmp ule i4 %x, %z45 call void @use(i1 %f.1)46 47 %c.5 = icmp ule i4 %x, %a48 call void @use(i1 %c.5)49 50 %t.1 = icmp ugt i4 %y, %z51 call void @use(i1 %t.1)52 53 %t.2 = icmp ugt i4 %x, %y54 call void @use(i1 %t.2)55 56 %t.3 = icmp ugt i4 %x, %z57 call void @use(i1 %t.3)58 59 ret void60}61 62; The result of test_or_ule and test_or_select_ule should be same63define void @test_or_select_ule(i4 %x, i4 %y, i4 %z, i4 %a) {64; CHECK-LABEL: @test_or_select_ule(65; CHECK-NEXT: entry:66; CHECK-NEXT: [[C_1:%.*]] = icmp ule i4 [[X:%.*]], [[Y:%.*]]67; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z:%.*]]68; CHECK-NEXT: [[OR:%.*]] = select i1 [[C_1]], i1 true, i1 [[C_2]]69; CHECK-NEXT: br i1 [[OR]], label [[BB1:%.*]], label [[EXIT:%.*]]70; CHECK: bb1:71; CHECK-NEXT: [[C_3:%.*]] = icmp ule i4 [[X]], [[Z]]72; CHECK-NEXT: call void @use(i1 [[C_3]])73; CHECK-NEXT: [[C_4:%.*]] = icmp ule i4 [[X]], [[A:%.*]]74; CHECK-NEXT: call void @use(i1 [[C_4]])75; CHECK-NEXT: ret void76; CHECK: exit:77; CHECK-NEXT: call void @use(i1 false)78; CHECK-NEXT: [[C_5:%.*]] = icmp ule i4 [[X]], [[A]]79; CHECK-NEXT: call void @use(i1 [[C_5]])80; CHECK-NEXT: call void @use(i1 true)81; CHECK-NEXT: call void @use(i1 true)82; CHECK-NEXT: call void @use(i1 true)83; CHECK-NEXT: ret void84;85entry:86 %c.1 = icmp ule i4 %x, %y87 %c.2 = icmp ule i4 %y, %z88 %or = select i1 %c.1, i1 true, i1 %c.289 br i1 %or, label %bb1, label %exit90 91bb1:92 %c.3 = icmp ule i4 %x, %z93 call void @use(i1 %c.3)94 95 %c.4 = icmp ule i4 %x, %a96 call void @use(i1 %c.4)97 98 ret void99 100exit:101 %f.1 = icmp ule i4 %x, %z102 call void @use(i1 %f.1)103 104 %c.5 = icmp ule i4 %x, %a105 call void @use(i1 %c.5)106 107 %t.1 = icmp ugt i4 %y, %z108 call void @use(i1 %t.1)109 110 %t.2 = icmp ugt i4 %x, %y111 call void @use(i1 %t.2)112 113 %t.3 = icmp ugt i4 %x, %z114 call void @use(i1 %t.3)115 116 ret void117}118 119define i1 @test_or_chain_ule_1(i4 %x, i4 %y, i4 %z, i4 %a, i4 %b) {120; CHECK-LABEL: @test_or_chain_ule_1(121; CHECK-NEXT: entry:122; CHECK-NEXT: [[C_1:%.*]] = icmp ule i4 [[X:%.*]], [[Y:%.*]]123; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z:%.*]]124; CHECK-NEXT: [[C_3:%.*]] = icmp ule i4 2, [[X]]125; CHECK-NEXT: [[C_4:%.*]] = icmp ule i4 2, [[A:%.*]]126; CHECK-NEXT: [[OR_1:%.*]] = or i1 [[C_1]], [[C_2]]127; CHECK-NEXT: [[OR_3:%.*]] = or i1 [[C_4]], true128; CHECK-NEXT: br i1 [[OR_3]], label [[BB1:%.*]], label [[EXIT:%.*]]129; CHECK: bb1:130; CHECK-NEXT: [[C_5:%.*]] = icmp ule i4 [[X]], [[Z]]131; CHECK-NEXT: [[C_6:%.*]] = icmp ule i4 [[X]], [[A]]132; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_5]], [[C_6]]133; CHECK-NEXT: [[C_7:%.*]] = icmp ule i4 2, [[X]]134; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_7]]135; CHECK-NEXT: ret i1 [[RES_2]]136; CHECK: exit:137; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, true138; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true139; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true140; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], true141; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], true142; CHECK-NEXT: [[RES_8:%.*]] = xor i1 [[RES_7]], true143; CHECK-NEXT: [[RES_9:%.*]] = xor i1 [[RES_8]], true144; CHECK-NEXT: ret i1 [[RES_9]]145;146entry:147 %c.1 = icmp ule i4 %x, %y148 %c.2 = icmp ule i4 %y, %z149 %c.3 = icmp ule i4 2, %x150 %c.4 = icmp ule i4 2, %a151 %or.1 = or i1 %c.1, %c.2152 %or.2 = or i1 %or.1, %c.3153 %or.3 = or i1 %c.4, %or.2154 br i1 %or.3, label %bb1, label %exit155 156bb1:157 %c.5 = icmp ule i4 %x, %z158 %c.6 = icmp ule i4 %x, %a159 %res.1 = xor i1 %c.5, %c.6160 %c.7 = icmp ule i4 2, %x161 %res.2 = xor i1 %res.1, %c.7162 ret i1 %res.2163 164exit:165 %f.1 = icmp ule i4 %x, %z166 %f.2 = icmp ule i4 2, %x167 %res.3 = xor i1 %f.1, %f.2168 169 %t.1 = icmp ugt i4 %y, %z170 %res.4 = xor i1 %res.3, %t.1171 172 %t.2 = icmp ugt i4 %x, %y173 %res.5 = xor i1 %res.4, %t.2174 175 %t.3 = icmp ugt i4 %x, %z176 %res.6 = xor i1 %res.5, %t.3177 178 %t.4 = icmp ugt i4 2, %a179 %res.7 = xor i1 %res.6, %t.4180 181 %c.8 = icmp ule i4 %x, %a182 %res.8 = xor i1 %res.7, %c.8183 184 %c.9 = icmp ule i4 %x, %b185 %res.9 = xor i1 %res.8, %c.9186 187 ret i1 %res.9188}189 190; Same as @test_or_chain_ule_1, but with the `or`s ordered differently.191define i1 @test_or_chain_ule_2(i4 %x, i4 %y, i4 %z, i4 %a, i4 %b) {192; CHECK-LABEL: @test_or_chain_ule_2(193; CHECK-NEXT: entry:194; CHECK-NEXT: [[C_1:%.*]] = icmp ule i4 [[X:%.*]], [[Y:%.*]]195; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z:%.*]]196; CHECK-NEXT: [[C_3:%.*]] = icmp ule i4 2, [[X]]197; CHECK-NEXT: [[C_4:%.*]] = icmp ule i4 2, [[A:%.*]]198; CHECK-NEXT: [[OR_1:%.*]] = or i1 [[C_1]], [[C_2]]199; CHECK-NEXT: [[OR_2:%.*]] = or i1 [[C_3]], [[C_4]]200; CHECK-NEXT: [[OR_3:%.*]] = or i1 [[OR_1]], [[OR_2]]201; CHECK-NEXT: br i1 [[OR_3]], label [[BB1:%.*]], label [[EXIT:%.*]]202; CHECK: bb1:203; CHECK-NEXT: [[C_5:%.*]] = icmp ule i4 [[X]], [[Z]]204; CHECK-NEXT: [[C_6:%.*]] = icmp ule i4 [[X]], [[A]]205; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_5]], [[C_6]]206; CHECK-NEXT: [[C_7:%.*]] = icmp ule i4 2, [[X]]207; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_7]]208; CHECK-NEXT: ret i1 [[RES_2]]209; CHECK: exit:210; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, true211; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true212; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true213; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], true214; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], true215; CHECK-NEXT: [[RES_8:%.*]] = xor i1 [[RES_7]], true216; CHECK-NEXT: [[RES_9:%.*]] = xor i1 [[RES_8]], true217; CHECK-NEXT: ret i1 [[RES_9]]218;219entry:220 %c.1 = icmp ule i4 %x, %y221 %c.2 = icmp ule i4 %y, %z222 %c.3 = icmp ule i4 2, %x223 %c.4 = icmp ule i4 2, %a224 %or.1 = or i1 %c.1, %c.2225 %or.2 = or i1 %c.3, %c.4226 %or.3 = or i1 %or.1, %or.2227 br i1 %or.3, label %bb1, label %exit228 229bb1:230 %c.5 = icmp ule i4 %x, %z231 %c.6 = icmp ule i4 %x, %a232 %res.1 = xor i1 %c.5, %c.6233 %c.7 = icmp ule i4 2, %x234 %res.2 = xor i1 %res.1, %c.7235 ret i1 %res.2236 237exit:238 %f.1 = icmp ule i4 %x, %z239 %f.2 = icmp ule i4 2, %x240 %res.3 = xor i1 %f.1, %f.2241 242 %t.1 = icmp ugt i4 %y, %z243 %res.4 = xor i1 %res.3, %t.1244 245 %t.2 = icmp ugt i4 %x, %y246 %res.5 = xor i1 %res.4, %t.2247 248 %t.3 = icmp ugt i4 %x, %z249 %res.6 = xor i1 %res.5, %t.3250 251 %t.4 = icmp ugt i4 2, %a252 %res.7 = xor i1 %res.6, %t.4253 254 %c.8 = icmp ule i4 %x, %a255 %res.8 = xor i1 %res.7, %c.8256 257 %c.9 = icmp ule i4 %x, %b258 %res.9 = xor i1 %res.8, %c.9259 260 ret i1 %res.9261}262 263declare i1 @cond() readnone264 265; Test with `or` chain that also contains instructions other than `or` and `icmp`.266define i1 @test_or_chain_with_other_conds_ule(i4 %x, i4 %y, i4 %z, i4 %a, i1 %arg.c) {267; CHECK-LABEL: @test_or_chain_with_other_conds_ule(268; CHECK-NEXT: entry:269; CHECK-NEXT: [[C_1:%.*]] = icmp ule i4 [[X:%.*]], [[Y:%.*]]270; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z:%.*]]271; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()272; CHECK-NEXT: [[OR_1:%.*]] = or i1 [[C_1]], [[C_2]]273; CHECK-NEXT: [[OR_2:%.*]] = or i1 [[C_3]], [[OR_1]]274; CHECK-NEXT: [[OR_3:%.*]] = or i1 [[OR_2]], [[ARG_C:%.*]]275; CHECK-NEXT: br i1 [[OR_3]], label [[BB1:%.*]], label [[EXIT:%.*]]276; CHECK: bb1:277; CHECK-NEXT: [[C_5:%.*]] = icmp ule i4 [[X]], [[Z]]278; CHECK-NEXT: [[C_6:%.*]] = icmp ule i4 [[X]], [[A:%.*]]279; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_5]], [[C_6]]280; CHECK-NEXT: [[C_7:%.*]] = icmp ule i4 2, [[X]]281; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_7]]282; CHECK-NEXT: ret i1 [[RES_2]]283; CHECK: exit:284; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true285; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true286; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true287; CHECK-NEXT: [[C_8:%.*]] = icmp ule i4 [[X]], [[A]]288; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[C_8]]289; CHECK-NEXT: ret i1 [[RES_6]]290;291entry:292 %c.1 = icmp ule i4 %x, %y293 %c.2 = icmp ule i4 %y, %z294 %c.3 = call i1 @cond()295 %or.1 = or i1 %c.1, %c.2296 %or.2 = or i1 %c.3, %or.1297 %or.3 = or i1 %or.2, %arg.c298 br i1 %or.3, label %bb1, label %exit299 300bb1:301 %c.5 = icmp ule i4 %x, %z302 %c.6 = icmp ule i4 %x, %a303 %res.1 = xor i1 %c.5, %c.6304 %c.7 = icmp ule i4 2, %x305 %res.2 = xor i1 %res.1, %c.7306 ret i1 %res.2307 308exit:309 %f.1 = icmp ule i4 %x, %z310 311 %t.1 = icmp ugt i4 %y, %z312 %res.3 = xor i1 %f.1, %t.1313 314 %t.2 = icmp ugt i4 %x, %y315 %res.4 = xor i1 %res.3, %t.2316 317 %t.3 = icmp ugt i4 %x, %z318 %res.5 = xor i1 %res.4, %t.3319 320 %c.8 = icmp ule i4 %x, %a321 %res.6 = xor i1 %res.5, %c.8322 323 ret i1 %res.6324}325 326define i1 @test_or_chain_with_and_ule(i4 %x, i4 %y, i4 %z, i4 %a, i4 %b) {327; CHECK-LABEL: @test_or_chain_with_and_ule(328; CHECK-NEXT: entry:329; CHECK-NEXT: [[C_1:%.*]] = icmp ule i4 [[X:%.*]], [[Y:%.*]]330; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z:%.*]]331; CHECK-NEXT: [[C_3:%.*]] = icmp ule i4 2, [[X]]332; CHECK-NEXT: [[C_4:%.*]] = icmp ule i4 2, [[A:%.*]]333; CHECK-NEXT: [[OR_1:%.*]] = or i1 [[C_1]], [[C_2]]334; CHECK-NEXT: [[AND_2:%.*]] = and i1 [[C_3]], [[C_4]]335; CHECK-NEXT: [[OR_3:%.*]] = or i1 [[OR_1]], [[AND_2]]336; CHECK-NEXT: br i1 [[OR_3]], label [[BB1:%.*]], label [[EXIT:%.*]]337; CHECK: bb1:338; CHECK-NEXT: [[C_5:%.*]] = icmp ule i4 [[X]], [[Z]]339; CHECK-NEXT: [[C_6:%.*]] = icmp ule i4 [[X]], [[A]]340; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_5]], [[C_6]]341; CHECK-NEXT: [[C_7:%.*]] = icmp ule i4 2, [[X]]342; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_7]]343; CHECK-NEXT: ret i1 [[RES_2]]344; CHECK: exit:345; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true346; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true347; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true348; CHECK-NEXT: [[C_8:%.*]] = icmp ule i4 [[X]], [[A]]349; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[C_8]]350; CHECK-NEXT: [[C_9:%.*]] = icmp ule i4 [[X]], [[B:%.*]]351; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[C_9]]352; CHECK-NEXT: [[RES_8:%.*]] = xor i1 [[RES_7]], true353; CHECK-NEXT: [[C_11:%.*]] = icmp ugt i4 2, [[A]]354; CHECK-NEXT: [[RES_9:%.*]] = xor i1 [[RES_8]], [[C_11]]355; CHECK-NEXT: ret i1 [[RES_9]]356;357entry:358 %c.1 = icmp ule i4 %x, %y359 %c.2 = icmp ule i4 %y, %z360 %c.3 = icmp ule i4 2, %x361 %c.4 = icmp ule i4 2, %a362 %or.1 = or i1 %c.1, %c.2363 %and.2 = and i1 %c.3, %c.4364 %or.3 = or i1 %or.1, %and.2365 br i1 %or.3, label %bb1, label %exit366 367bb1:368 %c.5 = icmp ule i4 %x, %z369 %c.6 = icmp ule i4 %x, %a370 %res.1 = xor i1 %c.5, %c.6371 %c.7 = icmp ule i4 2, %x372 %res.2 = xor i1 %res.1, %c.7373 ret i1 %res.2374 375exit:376 %f.1 = icmp ule i4 %x, %z377 %t.1 = icmp ugt i4 %y, %z378 %res.3 = xor i1 %f.1, %t.1379 380 %t.2 = icmp ugt i4 %x, %y381 %res.4 = xor i1 %res.3, %t.2382 383 %t.3 = icmp ugt i4 %x, %z384 %res.5 = xor i1 %res.4, %t.3385 386 %c.8 = icmp ule i4 %x, %a387 %res.6 = xor i1 %res.5, %c.8388 389 %c.9 = icmp ule i4 %x, %b390 %res.7 = xor i1 %res.6, %c.9391 392 %c.10 = icmp ule i4 2, %x393 %res.8 = xor i1 %res.7, %c.10394 395 %c.11 = icmp ugt i4 2, %a396 %res.9 = xor i1 %res.8, %c.11397 398 ret i1 %res.9399}400 401define void @test_or_as_add_ult(i8 %init_val, i8 %high) {402; CHECK-LABEL: @test_or_as_add_ult(403; CHECK-NEXT: entry:404; CHECK-NEXT: [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2405; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3406; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]407; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]408; CHECK: then:409; CHECK-NEXT: [[F_0:%.*]] = icmp ult i8 [[START]], [[HIGH]]410; CHECK-NEXT: call void @use(i1 [[F_0]])411; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1412; CHECK-NEXT: [[F_1:%.*]] = icmp ult i8 [[I_1]], [[HIGH]]413; CHECK-NEXT: call void @use(i1 [[F_1]])414; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2415; CHECK-NEXT: [[F_2:%.*]] = icmp ult i8 [[I_2]], [[HIGH]]416; CHECK-NEXT: call void @use(i1 [[F_2]])417; CHECK-NEXT: ret void418; CHECK: end:419; CHECK-NEXT: call void @use(i1 true)420; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1421; CHECK-NEXT: call void @use(i1 true)422; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2423; CHECK-NEXT: call void @use(i1 true)424; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3425; CHECK-NEXT: call void @use(i1 true)426; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4427; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]]428; CHECK-NEXT: call void @use(i1 [[C_4]])429; CHECK-NEXT: ret void430;431entry:432 %start = shl nuw nsw i8 %init_val, 2433 %start.plus.3 = add nuw i8 %start, 3434 %c.1 = icmp uge i8 %start.plus.3, %high435 br i1 %c.1, label %then, label %end436 437then: ; preds = %entry438 %f.0 = icmp ult i8 %start, %high439 call void @use(i1 %f.0)440 %i.1 = or disjoint i8 %start, 1441 %f.1 = icmp ult i8 %i.1, %high442 call void @use(i1 %f.1)443 %i.2 = or disjoint i8 %start, 2444 %f.2 = icmp ult i8 %i.2, %high445 call void @use(i1 %f.2)446 ret void447 448end: ; preds = %entry449 %t.0 = icmp ult i8 %start, %high450 call void @use(i1 %t.0)451 %start.1 = or disjoint i8 %start, 1452 %t.1 = icmp ult i8 %start.1, %high453 call void @use(i1 %t.1)454 %start.2 = or disjoint i8 %start, 2455 %t.2 = icmp ult i8 %start.2, %high456 call void @use(i1 %t.2)457 %start.3 = or disjoint i8 %start, 3458 %t.3 = icmp ult i8 %start.3, %high459 call void @use(i1 %t.3)460 %start.4 = or i8 %start, 4461 %c.4 = icmp ult i8 %start.4, %high462 call void @use(i1 %c.4)463 ret void464}465 466define void @test_or_as_add_ule(i8 %init_val, i8 %high) {467; CHECK-LABEL: @test_or_as_add_ule(468; CHECK-NEXT: entry:469; CHECK-NEXT: [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2470; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3471; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]472; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]473; CHECK: then:474; CHECK-NEXT: [[F_0:%.*]] = icmp ule i8 [[START]], [[HIGH]]475; CHECK-NEXT: call void @use(i1 [[F_0]])476; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1477; CHECK-NEXT: [[F_1:%.*]] = icmp ule i8 [[I_1]], [[HIGH]]478; CHECK-NEXT: call void @use(i1 [[F_1]])479; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2480; CHECK-NEXT: [[F_2:%.*]] = icmp ule i8 [[I_2]], [[HIGH]]481; CHECK-NEXT: call void @use(i1 [[F_2]])482; CHECK-NEXT: ret void483; CHECK: end:484; CHECK-NEXT: call void @use(i1 true)485; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1486; CHECK-NEXT: call void @use(i1 true)487; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2488; CHECK-NEXT: call void @use(i1 true)489; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3490; CHECK-NEXT: call void @use(i1 true)491; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4492; CHECK-NEXT: [[T_4:%.*]] = icmp ule i8 [[START_4]], [[HIGH]]493; CHECK-NEXT: call void @use(i1 [[T_4]])494; CHECK-NEXT: [[START_5:%.*]] = or i8 [[START]], 5495; CHECK-NEXT: [[C_5:%.*]] = icmp ule i8 [[START_5]], [[HIGH]]496; CHECK-NEXT: call void @use(i1 [[C_5]])497; CHECK-NEXT: ret void498;499entry:500 %start = shl nuw nsw i8 %init_val, 2501 %start.plus.3 = add nuw i8 %start, 3502 %c.1 = icmp uge i8 %start.plus.3, %high503 br i1 %c.1, label %then, label %end504 505then: ; preds = %entry506 %f.0 = icmp ule i8 %start, %high507 call void @use(i1 %f.0)508 %i.1 = or disjoint i8 %start, 1509 %f.1 = icmp ule i8 %i.1, %high510 call void @use(i1 %f.1)511 %i.2 = or disjoint i8 %start, 2512 %f.2 = icmp ule i8 %i.2, %high513 call void @use(i1 %f.2)514 ret void515 516end: ; preds = %entry517 %t.0 = icmp ule i8 %start, %high518 call void @use(i1 %t.0)519 %start.1 = or disjoint i8 %start, 1520 %t.1 = icmp ule i8 %start.1, %high521 call void @use(i1 %t.1)522 %start.2 = or disjoint i8 %start, 2523 %t.2 = icmp ule i8 %start.2, %high524 call void @use(i1 %t.2)525 %start.3 = or disjoint i8 %start, 3526 %t.3 = icmp ule i8 %start.3, %high527 call void @use(i1 %t.3)528 %start.4 = or i8 %start, 4529 %t.4 = icmp ule i8 %start.4, %high530 call void @use(i1 %t.4)531 %start.5 = or i8 %start, 5532 %c.5 = icmp ule i8 %start.5, %high533 call void @use(i1 %c.5)534 535 ret void536}537 538define void @test_or_as_add_ugt(i8 %init_val, i8 %high) {539; CHECK-LABEL: @test_or_as_add_ugt(540; CHECK-NEXT: entry:541; CHECK-NEXT: [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2542; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3543; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]544; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]545; CHECK: then:546; CHECK-NEXT: [[T_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]547; CHECK-NEXT: call void @use(i1 [[T_0]])548; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1549; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[I_1]], [[HIGH]]550; CHECK-NEXT: call void @use(i1 [[T_1]])551; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2552; CHECK-NEXT: [[T_2:%.*]] = icmp ugt i8 [[I_2]], [[HIGH]]553; CHECK-NEXT: call void @use(i1 [[T_2]])554; CHECK-NEXT: ret void555; CHECK: end:556; CHECK-NEXT: call void @use(i1 false)557; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1558; CHECK-NEXT: call void @use(i1 false)559; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2560; CHECK-NEXT: call void @use(i1 false)561; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3562; CHECK-NEXT: call void @use(i1 false)563; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4564; CHECK-NEXT: [[F_4:%.*]] = icmp ugt i8 [[START_4]], [[HIGH]]565; CHECK-NEXT: call void @use(i1 [[F_4]])566; CHECK-NEXT: [[START_5:%.*]] = or i8 [[START]], 5567; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[START_5]], [[HIGH]]568; CHECK-NEXT: call void @use(i1 [[C_5]])569; CHECK-NEXT: ret void570;571entry:572 %start = shl nuw nsw i8 %init_val, 2573 %start.plus.3 = add nuw i8 %start, 3574 %c.1 = icmp uge i8 %start.plus.3, %high575 br i1 %c.1, label %then, label %end576 577then: ; preds = %entry578 %t.0 = icmp ugt i8 %start, %high579 call void @use(i1 %t.0)580 %i.1 = or disjoint i8 %start, 1581 %t.1 = icmp ugt i8 %i.1, %high582 call void @use(i1 %t.1)583 %i.2 = or disjoint i8 %start, 2584 %t.2 = icmp ugt i8 %i.2, %high585 call void @use(i1 %t.2)586 ret void587 588end: ; preds = %entry589 %f.0 = icmp ugt i8 %start, %high590 call void @use(i1 %f.0)591 %start.1 = or disjoint i8 %start, 1592 %f.1 = icmp ugt i8 %start.1, %high593 call void @use(i1 %f.1)594 %start.2 = or disjoint i8 %start, 2595 %f.2 = icmp ugt i8 %start.2, %high596 call void @use(i1 %f.2)597 %start.3 = or disjoint i8 %start, 3598 %f.3 = icmp ugt i8 %start.3, %high599 call void @use(i1 %f.3)600 %start.4 = or i8 %start, 4601 %f.4 = icmp ugt i8 %start.4, %high602 call void @use(i1 %f.4)603 %start.5 = or i8 %start, 5604 %c.5 = icmp ugt i8 %start.5, %high605 call void @use(i1 %c.5)606 ret void607}608 609define void @test_or_as_add_uge(i8 %init_val, i8 %high) {610; CHECK-LABEL: @test_or_as_add_uge(611; CHECK-NEXT: entry:612; CHECK-NEXT: [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2613; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3614; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]615; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]616; CHECK: then:617; CHECK-NEXT: [[T_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]618; CHECK-NEXT: call void @use(i1 [[T_0]])619; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1620; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]]621; CHECK-NEXT: call void @use(i1 [[T_1]])622; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2623; CHECK-NEXT: [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]]624; CHECK-NEXT: call void @use(i1 [[T_2]])625; CHECK-NEXT: ret void626; CHECK: end:627; CHECK-NEXT: call void @use(i1 false)628; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1629; CHECK-NEXT: call void @use(i1 false)630; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2631; CHECK-NEXT: call void @use(i1 false)632; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3633; CHECK-NEXT: call void @use(i1 false)634; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4635; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]]636; CHECK-NEXT: call void @use(i1 [[C_4]])637; CHECK-NEXT: [[START_5:%.*]] = or i8 [[START]], 5638; CHECK-NEXT: [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]]639; CHECK-NEXT: call void @use(i1 [[C_5]])640; CHECK-NEXT: ret void641;642entry:643 %start = shl nuw nsw i8 %init_val, 2644 %start.plus.3 = add nuw i8 %start, 3645 %c.1 = icmp uge i8 %start.plus.3, %high646 br i1 %c.1, label %then, label %end647 648then: ; preds = %entry649 %t.0 = icmp ugt i8 %start, %high650 call void @use(i1 %t.0)651 %i.1 = or disjoint i8 %start, 1652 %t.1 = icmp uge i8 %i.1, %high653 call void @use(i1 %t.1)654 %i.2 = or disjoint i8 %start, 2655 %t.2 = icmp uge i8 %i.2, %high656 call void @use(i1 %t.2)657 ret void658 659end: ; preds = %entry660 %f.0 = icmp ugt i8 %start, %high661 call void @use(i1 %f.0)662 %start.1 = or disjoint i8 %start, 1663 %f.1 = icmp uge i8 %start.1, %high664 call void @use(i1 %f.1)665 %start.2 = or disjoint i8 %start, 2666 %f.2 = icmp uge i8 %start.2, %high667 call void @use(i1 %f.2)668 %start.3 = or disjoint i8 %start, 3669 %f.3 = icmp uge i8 %start.3, %high670 call void @use(i1 %f.3)671 %start.4 = or i8 %start, 4672 %c.4 = icmp uge i8 %start.4, %high673 call void @use(i1 %c.4)674 %start.5 = or i8 %start, 5675 %c.5 = icmp uge i8 %start.5, %high676 call void @use(i1 %c.5)677 ret void678}679 680define void @test_not_decompose(i8 %start, i8 %high) {681; CHECK-LABEL: @test_not_decompose(682; CHECK-NEXT: entry:683; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START:%.*]], 3684; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]685; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]686; CHECK: then:687; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1688; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]]689; CHECK-NEXT: call void @use(i1 [[T_1]])690; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2691; CHECK-NEXT: [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]]692; CHECK-NEXT: call void @use(i1 [[T_2]])693; CHECK-NEXT: ret void694; CHECK: end:695; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1696; CHECK-NEXT: [[F_1:%.*]] = icmp uge i8 [[START_1]], [[HIGH]]697; CHECK-NEXT: call void @use(i1 [[F_1]])698; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2699; CHECK-NEXT: [[F_2:%.*]] = icmp uge i8 [[START_2]], [[HIGH]]700; CHECK-NEXT: call void @use(i1 [[F_2]])701; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3702; CHECK-NEXT: [[F_3:%.*]] = icmp uge i8 [[START_3]], [[HIGH]]703; CHECK-NEXT: call void @use(i1 [[F_3]])704; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4705; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]]706; CHECK-NEXT: call void @use(i1 [[C_4]])707; CHECK-NEXT: [[START_5:%.*]] = or i8 [[START]], 5708; CHECK-NEXT: [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]]709; CHECK-NEXT: call void @use(i1 [[C_5]])710; CHECK-NEXT: ret void711;712entry:713 %start.plus.3 = add nuw i8 %start, 3714 %c.1 = icmp uge i8 %start.plus.3, %high715 br i1 %c.1, label %then, label %end716 717then: ; preds = %entry718 %i.1 = or i8 %start, 1719 %t.1 = icmp uge i8 %i.1, %high720 call void @use(i1 %t.1)721 %i.2 = or i8 %start, 2722 %t.2 = icmp uge i8 %i.2, %high723 call void @use(i1 %t.2)724 ret void725 726end: ; preds = %entry727 %start.1 = or i8 %start, 1728 %f.1 = icmp uge i8 %start.1, %high729 call void @use(i1 %f.1)730 %start.2 = or i8 %start, 2731 %f.2 = icmp uge i8 %start.2, %high732 call void @use(i1 %f.2)733 %start.3 = or i8 %start, 3734 %f.3 = icmp uge i8 %start.3, %high735 call void @use(i1 %f.3)736 %start.4 = or i8 %start, 4737 %c.4 = icmp uge i8 %start.4, %high738 call void @use(i1 %c.4)739 %start.5 = or i8 %start, 5740 %c.5 = icmp uge i8 %start.5, %high741 call void @use(i1 %c.5)742 743 ret void744}745 746; Nothing in the IR implies the disjoint flag, but we can still use it747; to decompose into an add.748define void @test_decompose_explicit_disjoint(i8 %start, i8 %high) {749; CHECK-LABEL: @test_decompose_explicit_disjoint(750; CHECK-NEXT: entry:751; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START:%.*]], 3752; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]753; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]754; CHECK: then:755; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1756; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]]757; CHECK-NEXT: call void @use(i1 [[T_1]])758; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2759; CHECK-NEXT: [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]]760; CHECK-NEXT: call void @use(i1 [[T_2]])761; CHECK-NEXT: ret void762; CHECK: end:763; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1764; CHECK-NEXT: call void @use(i1 false)765; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2766; CHECK-NEXT: call void @use(i1 false)767; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3768; CHECK-NEXT: call void @use(i1 false)769; CHECK-NEXT: [[START_4:%.*]] = or disjoint i8 [[START]], 4770; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]]771; CHECK-NEXT: call void @use(i1 [[C_4]])772; CHECK-NEXT: [[START_5:%.*]] = or disjoint i8 [[START]], 5773; CHECK-NEXT: [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]]774; CHECK-NEXT: call void @use(i1 [[C_5]])775; CHECK-NEXT: ret void776;777entry:778 %start.plus.3 = add nuw i8 %start, 3779 %c.1 = icmp uge i8 %start.plus.3, %high780 br i1 %c.1, label %then, label %end781 782then: ; preds = %entry783 %i.1 = or disjoint i8 %start, 1784 %t.1 = icmp uge i8 %i.1, %high785 call void @use(i1 %t.1)786 %i.2 = or disjoint i8 %start, 2787 %t.2 = icmp uge i8 %i.2, %high788 call void @use(i1 %t.2)789 ret void790 791end: ; preds = %entry792 %start.1 = or disjoint i8 %start, 1793 %f.1 = icmp uge i8 %start.1, %high794 call void @use(i1 %f.1)795 %start.2 = or disjoint i8 %start, 2796 %f.2 = icmp uge i8 %start.2, %high797 call void @use(i1 %f.2)798 %start.3 = or disjoint i8 %start, 3799 %f.3 = icmp uge i8 %start.3, %high800 call void @use(i1 %f.3)801 %start.4 = or disjoint i8 %start, 4802 %c.4 = icmp uge i8 %start.4, %high803 call void @use(i1 %c.4)804 %start.5 = or disjoint i8 %start, 5805 %c.5 = icmp uge i8 %start.5, %high806 call void @use(i1 %c.5)807 808 ret void809}810