1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4; Test cases where both the true and false successors reach the same block, 5; dominated by one of them. 6 7declare void @use(i1) 8 9define i1 @test1(i8 %x) { 10; CHECK-LABEL: @test1( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 13; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]] 14; CHECK: bb1: 15; CHECK-NEXT: call void @use(i1 true) 16; CHECK-NEXT: br label [[BB2]] 17; CHECK: bb2: 18; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[X]], 10 19; CHECK-NEXT: ret i1 [[C_3]] 20; 21entry: 22 %c.1 = icmp ule i8 %x, 10 23 br i1 %c.1, label %bb1, label %bb2 24 25bb1: 26 %c.2 = icmp ule i8 %x, 10 27 call void @use(i1 %c.2) 28 br label %bb2 29 30bb2: 31 %c.3 = icmp ugt i8 %x, 10 32 ret i1 %c.3 33} 34 35define i1 @test_chain_1(i8 %x) { 36; CHECK-LABEL: @test_chain_1( 37; CHECK-NEXT: entry: 38; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 39; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]] 40; CHECK: then: 41; CHECK-NEXT: call void @use(i1 true) 42; CHECK-NEXT: br label [[EXIT:%.*]] 43; CHECK: else: 44; CHECK-NEXT: br label [[EXIT]] 45; CHECK: exit: 46; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[X]], 10 47; CHECK-NEXT: ret i1 [[C_3]] 48; 49entry: 50 %c.1 = icmp ule i8 %x, 10 51 br i1 %c.1, label %then, label %else 52 53then: 54 %c.2 = icmp ule i8 %x, 10 55 call void @use(i1 %c.2) 56 br label %exit 57 58else: 59 br label %exit 60 61exit: 62 %c.3 = icmp ugt i8 %x, 10 63 ret i1 %c.3 64} 65 66define i1 @test_chain_2(i8 %x) { 67; CHECK-LABEL: @test_chain_2( 68; CHECK-NEXT: entry: 69; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 70; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]] 71; CHECK: then: 72; CHECK-NEXT: br label [[EXIT:%.*]] 73; CHECK: else: 74; CHECK-NEXT: call void @use(i1 false) 75; CHECK-NEXT: br label [[EXIT]] 76; CHECK: exit: 77; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[X]], 10 78; CHECK-NEXT: ret i1 [[C_3]] 79; 80entry: 81 %c.1 = icmp ule i8 %x, 10 82 br i1 %c.1, label %then, label %else 83 84then: 85 br label %exit 86 87else: 88 %c.2 = icmp ule i8 %x, 10 89 call void @use(i1 %c.2) 90 br label %exit 91 92exit: 93 %c.3 = icmp ugt i8 %x, 10 94 ret i1 %c.3 95} 96 97define i1 @test2(i8 %x) { 98; CHECK-LABEL: @test2( 99; CHECK-NEXT: entry: 100; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 101; CHECK-NEXT: br i1 [[C_1]], label [[BB2:%.*]], label [[BB1:%.*]] 102; CHECK: bb1: 103; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i8 [[X]], 10 104; CHECK-NEXT: ret i1 [[C_2]] 105; CHECK: bb2: 106; CHECK-NEXT: call void @use(i1 true) 107; CHECK-NEXT: br label [[BB1]] 108; 109entry: 110 %c.1 = icmp ule i8 %x, 10 111 br i1 %c.1, label %bb2, label %bb1 112 113bb1: 114 %c.2 = icmp ugt i8 %x, 10 115 ret i1 %c.2 116 117bb2: 118 %c.3 = icmp ule i8 %x, 10 119 call void @use(i1 %c.3) 120 br label %bb1 121} 122 123; Test cases where the true/false successors are not domianted by the conditional branching block. 124define i1 @test3(i8 %x, i1 %c) { 125; CHECK-LABEL: @test3( 126; CHECK-NEXT: entry: 127; CHECK-NEXT: br i1 [[C:%.*]], label [[BB_COND:%.*]], label [[BB1:%.*]] 128; CHECK: bb.cond: 129; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 130; CHECK-NEXT: br i1 [[C_1]], label [[BB1]], label [[BB2:%.*]] 131; CHECK: bb1: 132; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[X]], 10 133; CHECK-NEXT: ret i1 [[C_2]] 134; CHECK: bb2: 135; CHECK-NEXT: ret i1 true 136; 137entry: 138 br i1 %c, label %bb.cond, label %bb1 139 140bb.cond: 141 %c.1 = icmp ule i8 %x, 10 142 br i1 %c.1, label %bb1, label %bb2 143 144bb1: 145 %c.2 = icmp ule i8 %x, 10 146 ret i1 %c.2 147 148bb2: 149 %c.3 = icmp ugt i8 %x, 10 150 ret i1 %c.3 151} 152 153define i1 @test4(i8 %x, i1 %c) { 154; CHECK-LABEL: @test4( 155; CHECK-NEXT: entry: 156; CHECK-NEXT: br i1 [[C:%.*]], label [[BB_COND:%.*]], label [[BB2:%.*]] 157; CHECK: bb.cond: 158; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 159; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2]] 160; CHECK: bb1: 161; CHECK-NEXT: ret i1 true 162; CHECK: bb2: 163; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[X]], 10 164; CHECK-NEXT: ret i1 [[C_3]] 165; 166entry: 167 br i1 %c, label %bb.cond, label %bb2 168 169bb.cond: 170 %c.1 = icmp ule i8 %x, 10 171 br i1 %c.1, label %bb1, label %bb2 172 173bb1: 174 %c.2 = icmp ule i8 %x, 10 175 ret i1 %c.2 176 177bb2: 178 %c.3 = icmp ugt i8 %x, 10 179 ret i1 %c.3 180} 181 182 183define i1 @test_cond_from_preheader(i8 %x, i1 %c) { 184; CHECK-LABEL: @test_cond_from_preheader( 185; CHECK-NEXT: entry: 186; CHECK-NEXT: br i1 [[C:%.*]], label [[PRE:%.*]], label [[BB2:%.*]] 187; CHECK: pre: 188; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 189; CHECK-NEXT: br i1 [[C_1]], label [[LOOP:%.*]], label [[BB2]] 190; CHECK: loop: 191; CHECK-NEXT: call void @use(i1 true) 192; CHECK-NEXT: call void @use(i1 false) 193; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[X]], 9 194; CHECK-NEXT: call void @use(i1 [[C_2]]) 195; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[X]], 9 196; CHECK-NEXT: call void @use(i1 [[C_3]]) 197; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]] 198; CHECK: exit: 199; CHECK-NEXT: ret i1 true 200; CHECK: bb2: 201; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[X]], 10 202; CHECK-NEXT: ret i1 [[C_5]] 203; 204entry: 205 br i1 %c, label %pre, label %bb2 206 207pre: 208 %c.1 = icmp ule i8 %x, 10 209 br i1 %c.1, label %loop, label %bb2 210 211loop: 212 %t.1 = icmp ule i8 %x, 10 213 call void @use(i1 %t.1) 214 %f.1 = icmp ugt i8 %x, 10 215 call void @use(i1 %f.1) 216 217 %c.2 = icmp ule i8 %x, 9 218 call void @use(i1 %c.2) 219 %c.3 = icmp ugt i8 %x, 9 220 call void @use(i1 %c.3) 221 222 br i1 true, label %exit, label %loop 223 224exit: 225 %c.4 = icmp ule i8 %x, 10 226 ret i1 %c.4 227 228bb2: 229 %c.5 = icmp ugt i8 %x, 10 230 ret i1 %c.5 231} 232 233define i1 @test_cond_from_preheader_successors_flipped(i8 %x, i1 %c) { 234; CHECK-LABEL: @test_cond_from_preheader_successors_flipped( 235; CHECK-NEXT: entry: 236; CHECK-NEXT: br i1 [[C:%.*]], label [[PRE:%.*]], label [[BB2:%.*]] 237; CHECK: pre: 238; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 239; CHECK-NEXT: br i1 [[C_1]], label [[BB2]], label [[LOOP:%.*]] 240; CHECK: loop: 241; CHECK-NEXT: call void @use(i1 false) 242; CHECK-NEXT: call void @use(i1 true) 243; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[X]], 11 244; CHECK-NEXT: call void @use(i1 [[C_2]]) 245; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[X]], 11 246; CHECK-NEXT: call void @use(i1 [[C_3]]) 247; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]] 248; CHECK: exit: 249; CHECK-NEXT: ret i1 false 250; CHECK: bb2: 251; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[X]], 10 252; CHECK-NEXT: ret i1 [[C_5]] 253; 254entry: 255 br i1 %c, label %pre, label %bb2 256 257pre: 258 %c.1 = icmp ule i8 %x, 10 259 br i1 %c.1, label %bb2, label %loop 260 261loop: 262 %f.1 = icmp ule i8 %x, 10 263 call void @use(i1 %f.1) 264 %t.1 = icmp ugt i8 %x, 10 265 call void @use(i1 %t.1) 266 267 %c.2 = icmp ule i8 %x, 11 268 call void @use(i1 %c.2) 269 %c.3 = icmp ugt i8 %x, 11 270 call void @use(i1 %c.3) 271 272 br i1 true, label %exit, label %loop 273 274exit: 275 %f.2 = icmp ule i8 %x, 10 276 ret i1 %f.2 277 278bb2: 279 %c.5 = icmp ugt i8 %x, 10 280 ret i1 %c.5 281} 282 283define i1 @test_cond_from_preheader_and(i8 %x, i8 %y, i1 %c) { 284; CHECK-LABEL: @test_cond_from_preheader_and( 285; CHECK-NEXT: entry: 286; CHECK-NEXT: br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]] 287; CHECK: exit: 288; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[Y:%.*]], 10 289; CHECK-NEXT: ret i1 [[C_5]] 290; CHECK: pre: 291; CHECK-NEXT: [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10 292; CHECK-NEXT: [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99 293; CHECK-NEXT: [[AND:%.*]] = and i1 [[X_1]], [[Y_1]] 294; CHECK-NEXT: br i1 [[AND]], label [[LOOP:%.*]], label [[EXIT_1:%.*]] 295; CHECK: loop: 296; CHECK-NEXT: [[R_1:%.*]] = xor i1 true, false 297; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X]], 9 298; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]] 299; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i8 [[X]], 9 300; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_2]] 301; CHECK-NEXT: [[R_4:%.*]] = xor i1 [[R_3]], true 302; CHECK-NEXT: [[R_5:%.*]] = xor i1 [[R_4]], false 303; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[Y]], 100 304; CHECK-NEXT: [[R_6:%.*]] = xor i1 [[R_5]], [[C_3]] 305; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i8 [[Y]], 100 306; CHECK-NEXT: [[R_7:%.*]] = xor i1 [[R_6]], [[C_4]] 307; CHECK-NEXT: call void @use(i1 [[R_7]]) 308; CHECK-NEXT: br i1 true, label [[EXIT]], label [[LOOP]] 309; CHECK: exit.1: 310; CHECK-NEXT: [[C_6:%.*]] = icmp ugt i8 [[Y]], 10 311; CHECK-NEXT: ret i1 [[C_6]] 312; 313entry: 314 br i1 %c, label %pre, label %exit 315 316exit: 317 %c.5 = icmp ugt i8 %y, 10 318 ret i1 %c.5 319 320pre: 321 %x.1 = icmp ule i8 %x, 10 322 %y.1 = icmp ugt i8 %y, 99 323 %and = and i1 %x.1, %y.1 324 br i1 %and, label %loop, label %exit.1 325 326loop: 327 %t.1 = icmp ule i8 %x, 10 328 %f.1 = icmp ugt i8 %x, 10 329 %r.1 = xor i1 %t.1, %f.1 330 331 %c.1 = icmp ule i8 %x, 9 332 %r.2 = xor i1 %r.1, %c.1 333 334 %c.2 = icmp ugt i8 %x, 9 335 %r.3 = xor i1 %r.2, %c.2 336 337 %t.2 = icmp ugt i8 %y, 99 338 %r.4 = xor i1 %r.3, %t.2 339 340 %f.2 = icmp ule i8 %y, 99 341 %r.5 = xor i1 %r.4, %f.2 342 343 %c.3 = icmp ugt i8 %y, 100 344 %r.6 = xor i1 %r.5, %c.3 345 346 %c.4 = icmp ugt i8 %y, 100 347 %r.7 = xor i1 %r.6, %c.4 348 call void @use(i1 %r.7) 349 350 br i1 true, label %exit, label %loop 351 352exit.1: 353 %c.6 = icmp ugt i8 %y, 10 354 ret i1 %c.6 355} 356 357 358define i1 @test_cond_from_preheader_and_successors_flipped(i8 %x, i8 %y, i1 %c) { 359; CHECK-LABEL: @test_cond_from_preheader_and_successors_flipped( 360; CHECK-NEXT: entry: 361; CHECK-NEXT: br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]] 362; CHECK: exit: 363; CHECK-NEXT: [[C_9:%.*]] = icmp ugt i8 [[Y:%.*]], 10 364; CHECK-NEXT: ret i1 [[C_9]] 365; CHECK: pre: 366; CHECK-NEXT: [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10 367; CHECK-NEXT: [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99 368; CHECK-NEXT: [[AND:%.*]] = and i1 [[X_1]], [[Y_1]] 369; CHECK-NEXT: br i1 [[AND]], label [[EXIT_1:%.*]], label [[LOOP:%.*]] 370; CHECK: loop: 371; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X]], 10 372; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i8 [[X]], 10 373; CHECK-NEXT: [[R_1:%.*]] = xor i1 [[C_1]], [[C_2]] 374; CHECK-NEXT: [[C_3:%.*]] = icmp ule i8 [[X]], 9 375; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]] 376; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i8 [[X]], 9 377; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]] 378; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[Y]], 99 379; CHECK-NEXT: [[R_4:%.*]] = xor i1 [[R_3]], [[C_5]] 380; CHECK-NEXT: [[C_6:%.*]] = icmp ule i8 [[Y]], 99 381; CHECK-NEXT: [[R_5:%.*]] = xor i1 [[R_4]], [[C_6]] 382; CHECK-NEXT: [[C_7:%.*]] = icmp ugt i8 [[Y]], 100 383; CHECK-NEXT: [[R_6:%.*]] = xor i1 [[R_5]], [[C_7]] 384; CHECK-NEXT: [[C_8:%.*]] = icmp ugt i8 [[Y]], 100 385; CHECK-NEXT: [[R_7:%.*]] = xor i1 [[R_6]], [[C_8]] 386; CHECK-NEXT: call void @use(i1 [[R_7]]) 387; CHECK-NEXT: br i1 true, label [[EXIT]], label [[LOOP]] 388; CHECK: exit.1: 389; CHECK-NEXT: ret i1 true 390; 391entry: 392 br i1 %c, label %pre, label %exit 393 394exit: 395 %c.9 = icmp ugt i8 %y, 10 396 ret i1 %c.9 397 398pre: 399 %x.1 = icmp ule i8 %x, 10 400 %y.1 = icmp ugt i8 %y, 99 401 %and = and i1 %x.1, %y.1 402 br i1 %and, label %exit.1, label %loop 403 404loop: 405 %c.1 = icmp ule i8 %x, 10 406 %c.2 = icmp ugt i8 %x, 10 407 %r.1 = xor i1 %c.1, %c.2 408 %c.3 = icmp ule i8 %x, 9 409 %r.2 = xor i1 %r.1, %c.3 410 %c.4 = icmp ugt i8 %x, 9 411 %r.3 = xor i1 %r.2, %c.4 412 413 %c.5 = icmp ugt i8 %y, 99 414 %r.4 = xor i1 %r.3, %c.5 415 %c.6 = icmp ule i8 %y, 99 416 %r.5 = xor i1 %r.4, %c.6 417 418 %c.7 = icmp ugt i8 %y, 100 419 %r.6 = xor i1 %r.5, %c.7 420 %c.8 = icmp ugt i8 %y, 100 421 %r.7 = xor i1 %r.6, %c.8 422 call void @use(i1 %r.7) 423 424 br i1 true, label %exit, label %loop 425 426exit.1: 427 %t.1 = icmp ugt i8 %y, 10 428 ret i1 %t.1 429} 430 431define i1 @test_cond_from_preheader_or(i8 %x, i8 %y, i1 %c) { 432; CHECK-LABEL: @test_cond_from_preheader_or( 433; CHECK-NEXT: entry: 434; CHECK-NEXT: br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]] 435; CHECK: exit: 436; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[Y:%.*]], 10 437; CHECK-NEXT: ret i1 [[C_5]] 438; CHECK: pre: 439; CHECK-NEXT: [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10 440; CHECK-NEXT: [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99 441; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_1]], [[Y_1]] 442; CHECK-NEXT: br i1 [[OR]], label [[EXIT_1:%.*]], label [[LOOP:%.*]] 443; CHECK: loop: 444; CHECK-NEXT: [[R_1:%.*]] = xor i1 true, false 445; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], 11 446; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]] 447; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[X]], 11 448; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_2]] 449; CHECK-NEXT: [[R_4:%.*]] = xor i1 [[R_3]], true 450; CHECK-NEXT: [[R_5:%.*]] = xor i1 [[R_4]], false 451; CHECK-NEXT: [[C_3:%.*]] = icmp ule i8 [[Y]], 98 452; CHECK-NEXT: [[R_6:%.*]] = xor i1 [[R_5]], [[C_3]] 453; CHECK-NEXT: [[C_4:%.*]] = icmp ule i8 [[Y]], 98 454; CHECK-NEXT: [[R_7:%.*]] = xor i1 [[R_6]], [[C_4]] 455; CHECK-NEXT: call void @use(i1 [[R_7]]) 456; CHECK-NEXT: br i1 true, label [[EXIT]], label [[LOOP]] 457; CHECK: exit.1: 458; CHECK-NEXT: [[C_6:%.*]] = icmp ule i8 [[Y]], 100 459; CHECK-NEXT: ret i1 [[C_6]] 460; 461entry: 462 br i1 %c, label %pre, label %exit 463 464exit: 465 %c.5 = icmp ugt i8 %y, 10 466 ret i1 %c.5 467 468pre: 469 %x.1 = icmp ule i8 %x, 10 470 %y.1 = icmp ugt i8 %y, 99 471 %or = or i1 %x.1, %y.1 472 br i1 %or, label %exit.1, label %loop 473 474loop: 475 %t.1 = icmp ugt i8 %x, 10 476 %f.1 = icmp ule i8 %x, 10 477 %r.1 = xor i1 %t.1, %f.1 478 %c.1 = icmp ugt i8 %x, 11 479 %r.2 = xor i1 %r.1, %c.1 480 %c.2 = icmp ule i8 %x, 11 481 %r.3 = xor i1 %r.2, %c.2 482 483 %t.2 = icmp ule i8 %y, 99 484 %r.4 = xor i1 %r.3, %t.2 485 %f.2 = icmp ugt i8 %y, 99 486 %r.5 = xor i1 %r.4, %f.2 487 488 %c.3 = icmp ule i8 %y, 98 489 %r.6 = xor i1 %r.5, %c.3 490 %c.4 = icmp ule i8 %y, 98 491 %r.7 = xor i1 %r.6, %c.4 492 call void @use(i1 %r.7) 493 494 br i1 true, label %exit, label %loop 495 496exit.1: 497 %c.6 = icmp ule i8 %y, 100 498 ret i1 %c.6 499} 500 501define i1 @test_cond_from_preheader_or_successor_flipped(i8 %x, i8 %y, i1 %c) { 502; CHECK-LABEL: @test_cond_from_preheader_or_successor_flipped( 503; CHECK-NEXT: entry: 504; CHECK-NEXT: br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]] 505; CHECK: exit: 506; CHECK-NEXT: [[C_9:%.*]] = icmp ugt i8 [[Y:%.*]], 10 507; CHECK-NEXT: ret i1 [[C_9]] 508; CHECK: pre: 509; CHECK-NEXT: [[X_1:%.*]] = icmp ule i8 [[X:%.*]], 10 510; CHECK-NEXT: [[Y_1:%.*]] = icmp ugt i8 [[Y]], 99 511; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_1]], [[Y_1]] 512; CHECK-NEXT: br i1 [[OR]], label [[LOOP:%.*]], label [[EXIT_1:%.*]] 513; CHECK: loop: 514; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X]], 10 515; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i8 [[X]], 10 516; CHECK-NEXT: [[R_1:%.*]] = xor i1 [[C_1]], [[C_2]] 517; CHECK-NEXT: [[C_3:%.*]] = icmp ule i8 [[X]], 9 518; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]] 519; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i8 [[X]], 9 520; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]] 521; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[Y]], 99 522; CHECK-NEXT: [[R_4:%.*]] = xor i1 [[R_3]], [[C_5]] 523; CHECK-NEXT: [[C_6:%.*]] = icmp ule i8 [[Y]], 99 524; CHECK-NEXT: [[R_5:%.*]] = xor i1 [[R_4]], [[C_6]] 525; CHECK-NEXT: [[C_7:%.*]] = icmp ugt i8 [[Y]], 100 526; CHECK-NEXT: [[R_6:%.*]] = xor i1 [[R_5]], [[C_7]] 527; CHECK-NEXT: [[C_8:%.*]] = icmp ugt i8 [[Y]], 100 528; CHECK-NEXT: [[R_7:%.*]] = xor i1 [[R_6]], [[C_8]] 529; CHECK-NEXT: call void @use(i1 [[R_7]]) 530; CHECK-NEXT: br i1 true, label [[EXIT]], label [[LOOP]] 531; CHECK: exit.1: 532; CHECK-NEXT: ret i1 true 533; 534entry: 535 br i1 %c, label %pre, label %exit 536 537exit: 538 %c.9 = icmp ugt i8 %y, 10 539 ret i1 %c.9 540 541pre: 542 %x.1 = icmp ule i8 %x, 10 543 %y.1 = icmp ugt i8 %y, 99 544 %or = or i1 %x.1, %y.1 545 br i1 %or, label %loop, label %exit.1 546 547loop: 548 %c.1 = icmp ule i8 %x, 10 549 %c.2 = icmp ugt i8 %x, 10 550 %r.1 = xor i1 %c.1, %c.2 551 %c.3 = icmp ule i8 %x, 9 552 %r.2 = xor i1 %r.1, %c.3 553 %c.4 = icmp ugt i8 %x, 9 554 %r.3 = xor i1 %r.2, %c.4 555 556 %c.5 = icmp ugt i8 %y, 99 557 %r.4 = xor i1 %r.3, %c.5 558 %c.6 = icmp ule i8 %y, 99 559 %r.5 = xor i1 %r.4, %c.6 560 561 %c.7 = icmp ugt i8 %y, 100 562 %r.6 = xor i1 %r.5, %c.7 563 %c.8 = icmp ugt i8 %y, 100 564 %r.7 = xor i1 %r.6, %c.8 565 call void @use(i1 %r.7) 566 567 br i1 true, label %exit, label %loop 568 569exit.1: 570 %t.1 = icmp ule i8 %y, 100 571 ret i1 %t.1 572} 573 574; Test case from PR49819. 575define i1 @both_branch_to_same_block(i4 %x) { 576; CHECK-LABEL: @both_branch_to_same_block( 577; CHECK-NEXT: entry: 578; CHECK-NEXT: [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0 579; CHECK-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[EXIT]] 580; CHECK: exit: 581; CHECK-NEXT: [[C_2:%.*]] = icmp ne i4 [[X]], 0 582; CHECK-NEXT: [[C_3:%.*]] = icmp eq i4 [[X]], 0 583; CHECK-NEXT: [[RES:%.*]] = xor i1 [[C_2]], [[C_3]] 584; CHECK-NEXT: ret i1 [[RES]] 585; 586entry: 587 %c.1 = icmp ne i4 %x, 0 588 br i1 %c.1, label %exit, label %exit 589 590exit: 591 %c.2 = icmp ne i4 %x, 0 592 %c.3 = icmp eq i4 %x, 0 593 %res = xor i1 %c.2, %c.3 594 ret i1 %res 595} 596 597define i1 @both_branch_to_same_block_and(i4 %x, i4 %y) { 598; CHECK-LABEL: @both_branch_to_same_block_and( 599; CHECK-NEXT: entry: 600; CHECK-NEXT: [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0 601; CHECK-NEXT: [[C_2:%.*]] = icmp ne i4 [[Y:%.*]], -6 602; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], [[C_2]] 603; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[EXIT]] 604; CHECK: exit: 605; CHECK-NEXT: [[C_3:%.*]] = icmp ne i4 [[X]], 0 606; CHECK-NEXT: [[C_4:%.*]] = icmp eq i4 [[X]], 0 607; CHECK-NEXT: [[RES:%.*]] = xor i1 [[C_3]], [[C_4]] 608; CHECK-NEXT: ret i1 [[RES]] 609; 610entry: 611 %c.1 = icmp ne i4 %x, 0 612 %c.2 = icmp ne i4 %y, 10 613 %and = and i1 %c.1, %c.2 614 br i1 %and, label %exit, label %exit 615 616exit: 617 %c.3 = icmp ne i4 %x, 0 618 %c.4 = icmp eq i4 %x, 0 619 %res = xor i1 %c.3, %c.4 620 ret i1 %res 621} 622 623 624define i1 @both_branch_to_same_block_or(i4 %x, i4 %y) { 625; CHECK-LABEL: @both_branch_to_same_block_or( 626; CHECK-NEXT: entry: 627; CHECK-NEXT: [[C_1:%.*]] = icmp ne i4 [[X:%.*]], 0 628; CHECK-NEXT: [[C_2:%.*]] = icmp ne i4 [[Y:%.*]], -6 629; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_1]], [[C_2]] 630; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[EXIT]] 631; CHECK: exit: 632; CHECK-NEXT: [[C_3:%.*]] = icmp ne i4 [[X]], 0 633; CHECK-NEXT: [[C_4:%.*]] = icmp eq i4 [[X]], 0 634; CHECK-NEXT: [[RES:%.*]] = xor i1 [[C_3]], [[C_4]] 635; CHECK-NEXT: ret i1 [[RES]] 636; 637entry: 638 %c.1 = icmp ne i4 %x, 0 639 %c.2 = icmp ne i4 %y, 10 640 %or = or i1 %c.1, %c.2 641 br i1 %or, label %exit, label %exit 642 643exit: 644 %c.3 = icmp ne i4 %x, 0 645 %c.4 = icmp eq i4 %x, 0 646 %res = xor i1 %c.3, %c.4 647 ret i1 %res 648} 649