1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -correlated-propagation -S | FileCheck %s 3; PR2581 4 5define i32 @test1(i1 %C) { 6; CHECK-LABEL: @test1( 7; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[BODY:%.*]] 8; CHECK: body: 9; CHECK-NEXT: ret i32 11 10; CHECK: exit: 11; CHECK-NEXT: ret i32 10 12; 13 br i1 %C, label %exit, label %body 14 15body: ; preds = %0 16 %A = select i1 %C, i32 10, i32 11 17 ret i32 %A 18 19exit: ; preds = %0 20 ret i32 10 21} 22 23; PR4420 24declare i1 @ext() 25define i1 @test2() { 26; CHECK-LABEL: @test2( 27; CHECK-NEXT: entry: 28; CHECK-NEXT: [[COND:%.*]] = tail call i1 @ext() 29; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]] 30; CHECK: bb1: 31; CHECK-NEXT: [[COND2:%.*]] = tail call i1 @ext() 32; CHECK-NEXT: br i1 [[COND2]], label [[BB3:%.*]], label [[BB2]] 33; CHECK: bb2: 34; CHECK-NEXT: ret i1 false 35; CHECK: bb3: 36; CHECK-NEXT: [[RES:%.*]] = tail call i1 @ext() 37; CHECK-NEXT: ret i1 [[RES]] 38; 39entry: 40 %cond = tail call i1 @ext() 41 br i1 %cond, label %bb1, label %bb2 42 43bb1: 44 %cond2 = tail call i1 @ext() 45 br i1 %cond2, label %bb3, label %bb2 46 47bb2: 48 %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ] 49 ret i1 %cond_merge 50 51bb3: 52 %res = tail call i1 @ext() 53 ret i1 %res 54} 55 56; PR4855 57@gv = internal constant i8 7 58define i8 @test3(i8* %a) nounwind { 59; CHECK-LABEL: @test3( 60; CHECK-NEXT: entry: 61; CHECK-NEXT: [[COND:%.*]] = icmp eq i8* [[A:%.*]], @gv 62; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB:%.*]] 63; CHECK: bb: 64; CHECK-NEXT: ret i8 0 65; CHECK: bb2: 66; CHECK-NEXT: [[SHOULD_BE_CONST:%.*]] = load i8, i8* @gv, align 1 67; CHECK-NEXT: ret i8 [[SHOULD_BE_CONST]] 68; 69entry: 70 %cond = icmp eq i8* %a, @gv 71 br i1 %cond, label %bb2, label %bb 72 73bb: 74 ret i8 0 75 76bb2: 77 %should_be_const = load i8, i8* %a 78 ret i8 %should_be_const 79} 80 81; PR1757 82define i32 @test4(i32) { 83; CHECK-LABEL: @test4( 84; CHECK-NEXT: EntryBlock: 85; CHECK-NEXT: [[DOTDEMORGAN:%.*]] = icmp sgt i32 [[TMP0:%.*]], 2 86; CHECK-NEXT: br i1 [[DOTDEMORGAN]], label [[GREATERTHANTWO:%.*]], label [[LESSTHANOREQUALTOTWO:%.*]] 87; CHECK: GreaterThanTwo: 88; CHECK-NEXT: br i1 false, label [[IMPOSSIBLE:%.*]], label [[NOTTWOANDGREATERTHANTWO:%.*]] 89; CHECK: NotTwoAndGreaterThanTwo: 90; CHECK-NEXT: ret i32 2 91; CHECK: Impossible: 92; CHECK-NEXT: ret i32 1 93; CHECK: LessThanOrEqualToTwo: 94; CHECK-NEXT: ret i32 0 95; 96EntryBlock: 97 %.demorgan = icmp sgt i32 %0, 2 98 br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo 99 100GreaterThanTwo: 101 icmp eq i32 %0, 2 102 br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo 103 104NotTwoAndGreaterThanTwo: 105 ret i32 2 106 107Impossible: 108 ret i32 1 109 110LessThanOrEqualToTwo: 111 ret i32 0 112} 113 114declare i32* @f(i32*) 115define void @test5(i32* %x, i32* %y) { 116; CHECK-LABEL: @test5( 117; CHECK-NEXT: entry: 118; CHECK-NEXT: [[PRE:%.*]] = icmp eq i32* [[X:%.*]], null 119; CHECK-NEXT: br i1 [[PRE]], label [[RETURN:%.*]], label [[LOOP:%.*]] 120; CHECK: loop: 121; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ] 122; CHECK-NEXT: [[F]] = tail call i32* @f(i32* [[PHI]]) 123; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32* [[F]], [[Y:%.*]] 124; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32* [[F]], i32* null 125; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32* [[SEL]], null 126; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN]], label [[LOOP]] 127; CHECK: return: 128; CHECK-NEXT: ret void 129; 130entry: 131 %pre = icmp eq i32* %x, null 132 br i1 %pre, label %return, label %loop 133 134loop: 135 %phi = phi i32* [ %sel, %loop ], [ %x, %entry ] 136 %f = tail call i32* @f(i32* %phi) 137 %cmp1 = icmp ne i32* %f, %y 138 %sel = select i1 %cmp1, i32* %f, i32* null 139 %cmp2 = icmp eq i32* %sel, null 140 br i1 %cmp2, label %return, label %loop 141 142return: 143 ret void 144} 145 146define i32 @switch1(i32 %s) { 147; CHECK-LABEL: @switch1( 148; CHECK-NEXT: entry: 149; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[S:%.*]], 0 150; CHECK-NEXT: br i1 [[CMP]], label [[NEGATIVE:%.*]], label [[OUT:%.*]] 151; CHECK: negative: 152; CHECK-NEXT: switch i32 [[S]], label [[OUT]] [ 153; CHECK-NEXT: i32 -2, label [[NEXT:%.*]] 154; CHECK-NEXT: i32 -1, label [[NEXT]] 155; CHECK-NEXT: ] 156; CHECK: out: 157; CHECK-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ -1, [[NEGATIVE]] ] 158; CHECK-NEXT: ret i32 [[P]] 159; CHECK: next: 160; CHECK-NEXT: ret i32 0 161; 162entry: 163 %cmp = icmp slt i32 %s, 0 164 br i1 %cmp, label %negative, label %out 165 166negative: 167 switch i32 %s, label %out [ 168 i32 0, label %out 169 i32 1, label %out 170 i32 -1, label %next 171 i32 -2, label %next 172 i32 2, label %out 173 i32 3, label %out 174 ] 175 176out: 177 %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ] 178 ret i32 %p 179 180next: 181 %q = phi i32 [ 0, %negative ], [ 0, %negative ] 182 ret i32 %q 183} 184 185define i32 @switch2(i32 %s) { 186; CHECK-LABEL: @switch2( 187; CHECK-NEXT: entry: 188; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S:%.*]], 0 189; CHECK-NEXT: br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]] 190; CHECK: positive: 191; CHECK-NEXT: br label [[OUT]] 192; CHECK: out: 193; CHECK-NEXT: [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ] 194; CHECK-NEXT: ret i32 [[P]] 195; CHECK: next: 196; CHECK-NEXT: ret i32 0 197; 198entry: 199 %cmp = icmp sgt i32 %s, 0 200 br i1 %cmp, label %positive, label %out 201 202positive: 203 switch i32 %s, label %out [ 204 i32 0, label %out 205 i32 -1, label %next 206 i32 -2, label %next 207 ] 208 209out: 210 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ] 211 ret i32 %p 212 213next: 214 %q = phi i32 [ 0, %positive ], [ 0, %positive ] 215 ret i32 %q 216} 217 218define i32 @switch3(i32 %s) { 219; CHECK-LABEL: @switch3( 220; CHECK-NEXT: entry: 221; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S:%.*]], 0 222; CHECK-NEXT: br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]] 223; CHECK: positive: 224; CHECK-NEXT: br label [[OUT]] 225; CHECK: out: 226; CHECK-NEXT: [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ] 227; CHECK-NEXT: ret i32 [[P]] 228; CHECK: next: 229; CHECK-NEXT: ret i32 0 230; 231entry: 232 %cmp = icmp sgt i32 %s, 0 233 br i1 %cmp, label %positive, label %out 234 235positive: 236 switch i32 %s, label %out [ 237 i32 -1, label %out 238 i32 -2, label %next 239 i32 -3, label %next 240 ] 241 242out: 243 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ] 244 ret i32 %p 245 246next: 247 %q = phi i32 [ 0, %positive ], [ 0, %positive ] 248 ret i32 %q 249} 250 251define void @switch4(i32 %s) { 252; CHECK-LABEL: @switch4( 253; CHECK-NEXT: entry: 254; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[S:%.*]], 0 255; CHECK-NEXT: br i1 [[CMP]], label [[ZERO:%.*]], label [[OUT:%.*]] 256; CHECK: zero: 257; CHECK-NEXT: br label [[NEXT:%.*]] 258; CHECK: out: 259; CHECK-NEXT: ret void 260; CHECK: next: 261; CHECK-NEXT: ret void 262; 263entry: 264 %cmp = icmp eq i32 %s, 0 265 br i1 %cmp, label %zero, label %out 266 267zero: 268 switch i32 %s, label %out [ 269 i32 0, label %next 270 i32 1, label %out 271 i32 -1, label %out 272 ] 273 274out: 275 ret void 276 277next: 278 ret void 279} 280 281define void @switch_nonzero_zext(i8 %s) { 282; CHECK-LABEL: @switch_nonzero_zext( 283; CHECK-NEXT: entry: 284; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[S:%.*]], 0 285; CHECK-NEXT: br i1 [[CMP]], label [[SWITCH:%.*]], label [[EXIT:%.*]] 286; CHECK: switch: 287; CHECK-NEXT: [[S_EXT:%.*]] = zext i8 [[S]] to i32 288; CHECK-NEXT: br label [[EXIT]] 289; CHECK: exit: 290; CHECK-NEXT: ret void 291; CHECK: unreachable: 292; CHECK-NEXT: ret void 293; 294entry: 295 %cmp = icmp ne i8 %s, 0 296 br i1 %cmp, label %switch, label %exit 297 298switch: 299 %s.ext = zext i8 %s to i32 300 switch i32 %s.ext, label %exit [ 301 i32 0, label %unreachable 302 i32 1, label %exit 303 i32 -1, label %exit 304 ] 305 306exit: 307 ret void 308 309unreachable: 310 ret void 311} 312 313define void @switch_assume_nonzero(i32 %s) { 314; CHECK-LABEL: @switch_assume_nonzero( 315; CHECK-NEXT: entry: 316; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[S:%.*]], 0 317; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 318; CHECK-NEXT: br label [[EXIT:%.*]] 319; CHECK: exit: 320; CHECK-NEXT: ret void 321; CHECK: unreachable: 322; CHECK-NEXT: ret void 323; 324entry: 325 %cmp = icmp ne i32 %s, 0 326 call void @llvm.assume(i1 %cmp) 327 switch i32 %s, label %exit [ 328 i32 0, label %unreachable 329 i32 1, label %exit 330 i32 -1, label %exit 331 ] 332 333exit: 334 ret void 335 336unreachable: 337 ret void 338} 339 340define void @switch_nonzero_phi(i1 %cond) { 341; CHECK-LABEL: @switch_nonzero_phi( 342; CHECK-NEXT: entry: 343; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 344; CHECK: if: 345; CHECK-NEXT: br label [[SWITCH:%.*]] 346; CHECK: else: 347; CHECK-NEXT: br label [[SWITCH]] 348; CHECK: switch: 349; CHECK-NEXT: [[S:%.*]] = phi i32 [ 1, [[IF]] ], [ -1, [[ELSE]] ] 350; CHECK-NEXT: br label [[EXIT:%.*]] 351; CHECK: exit: 352; CHECK-NEXT: ret void 353; CHECK: unreachable: 354; CHECK-NEXT: ret void 355; 356entry: 357 br i1 %cond, label %if, label %else 358 359if: 360 br label %switch 361 362else: 363 br label %switch 364 365switch: 366 %s = phi i32 [ 1, %if ], [ -1, %else ] 367 switch i32 %s, label %exit [ 368 i32 0, label %unreachable 369 i32 1, label %exit 370 i32 -1, label %exit 371 ] 372 373exit: 374 ret void 375 376unreachable: 377 ret void 378} 379 380define i32 @switch_range(i32 %cond) { 381; CHECK-LABEL: @switch_range( 382; CHECK-NEXT: entry: 383; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND:%.*]], 3 384; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1 385; CHECK-NEXT: switch i32 [[S1]], label [[ENTRY_UNREACHABLEDEFAULT:%.*]] [ 386; CHECK-NEXT: i32 1, label [[EXIT1:%.*]] 387; CHECK-NEXT: i32 2, label [[EXIT2:%.*]] 388; CHECK-NEXT: i32 3, label [[EXIT1]] 389; CHECK-NEXT: ] 390; CHECK: exit1: 391; CHECK-NEXT: ret i32 1 392; CHECK: exit2: 393; CHECK-NEXT: ret i32 2 394; CHECK: entry.unreachabledefault: 395; CHECK-NEXT: unreachable 396; CHECK: unreachable: 397; CHECK-NEXT: ret i32 0 398; 399entry: 400 %s = urem i32 %cond, 3 401 %s1 = add i32 %s, 1 402 switch i32 %s1, label %unreachable [ 403 i32 1, label %exit1 404 i32 2, label %exit2 405 i32 3, label %exit1 406 ] 407 408exit1: 409 ret i32 1 410exit2: 411 ret i32 2 412unreachable: 413 ret i32 0 414} 415 416; If the cases do not cover the entire range of the 417; switch condition, we should not change the default. 418 419define i32 @switch_range_not_full(i32 %cond) { 420; CHECK-LABEL: @switch_range_not_full( 421; CHECK-NEXT: entry: 422; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND:%.*]], 3 423; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1 424; CHECK-NEXT: switch i32 [[S1]], label [[UNREACHABLE:%.*]] [ 425; CHECK-NEXT: i32 1, label [[EXIT1:%.*]] 426; CHECK-NEXT: i32 3, label [[EXIT2:%.*]] 427; CHECK-NEXT: ] 428; CHECK: exit1: 429; CHECK-NEXT: ret i32 1 430; CHECK: exit2: 431; CHECK-NEXT: ret i32 2 432; CHECK: unreachable: 433; CHECK-NEXT: ret i32 0 434; 435entry: 436 %s = urem i32 %cond, 3 437 %s1 = add i32 %s, 1 438 switch i32 %s1, label %unreachable [ 439 i32 1, label %exit1 440 i32 3, label %exit2 441 ] 442 443exit1: 444 ret i32 1 445exit2: 446 ret i32 2 447unreachable: 448 ret i32 0 449} 450 451; PR51531 452 453define i8 @switch_defaultdest_multipleuse(i8 %t0) { 454; CHECK-LABEL: @switch_defaultdest_multipleuse( 455; CHECK-NEXT: entry: 456; CHECK-NEXT: [[O:%.*]] = or i8 [[T0:%.*]], 1 457; CHECK-NEXT: [[R:%.*]] = srem i8 1, [[O]] 458; CHECK-NEXT: br label [[EXIT:%.*]] 459; CHECK: entry.unreachabledefault: 460; CHECK-NEXT: unreachable 461; CHECK: exit: 462; CHECK-NEXT: ret i8 0 463; 464entry: 465 %o = or i8 %t0, 1 466 %r = srem i8 1, %o 467 switch i8 %r, label %exit [ 468 i8 0, label %exit 469 i8 1, label %exit 470 ] 471 472exit: 473 ret i8 0 474} 475 476define i1 @arg_attribute(i8* nonnull %a) { 477; CHECK-LABEL: @arg_attribute( 478; CHECK-NEXT: ret i1 false 479; 480 %cmp = icmp eq i8* %a, null 481 ret i1 %cmp 482} 483 484declare nonnull i8* @return_nonnull() 485define i1 @call_attribute() { 486; CHECK-LABEL: @call_attribute( 487; CHECK-NEXT: [[A:%.*]] = call i8* @return_nonnull() 488; CHECK-NEXT: ret i1 false 489; 490 %a = call i8* @return_nonnull() 491 %cmp = icmp eq i8* %a, null 492 ret i1 %cmp 493} 494 495define i1 @umin(i32 %a, i32 %b) { 496; CHECK-LABEL: @umin( 497; CHECK-NEXT: entry: 498; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5 499; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 500; CHECK: a_guard: 501; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20 502; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 503; CHECK: b_guard: 504; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]] 505; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 506; CHECK-NEXT: ret i1 false 507; CHECK: out: 508; CHECK-NEXT: ret i1 false 509; 510entry: 511 %cmp = icmp ult i32 %a, 5 512 br i1 %cmp, label %a_guard, label %out 513 514a_guard: 515 %cmp2 = icmp ult i32 %b, 20 516 br i1 %cmp2, label %b_guard, label %out 517 518b_guard: 519 %sel_cmp = icmp ult i32 %a, %b 520 %min = select i1 %sel_cmp, i32 %a, i32 %b 521 %res = icmp eq i32 %min, 7 522 ret i1 %res 523out: 524 ret i1 false 525} 526 527define i1 @smin(i32 %a, i32 %b) { 528; CHECK-LABEL: @smin( 529; CHECK-NEXT: entry: 530; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5 531; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 532; CHECK: a_guard: 533; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20 534; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 535; CHECK: b_guard: 536; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sle i32 [[A]], [[B]] 537; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 538; CHECK-NEXT: ret i1 false 539; CHECK: out: 540; CHECK-NEXT: ret i1 false 541; 542entry: 543 %cmp = icmp ult i32 %a, 5 544 br i1 %cmp, label %a_guard, label %out 545 546a_guard: 547 %cmp2 = icmp ult i32 %b, 20 548 br i1 %cmp2, label %b_guard, label %out 549 550b_guard: 551 %sel_cmp = icmp sle i32 %a, %b 552 %min = select i1 %sel_cmp, i32 %a, i32 %b 553 %res = icmp eq i32 %min, 7 554 ret i1 %res 555out: 556 ret i1 false 557} 558 559define i1 @smax(i32 %a, i32 %b) { 560; CHECK-LABEL: @smax( 561; CHECK-NEXT: entry: 562; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 563; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 564; CHECK: a_guard: 565; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20 566; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 567; CHECK: b_guard: 568; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], [[B]] 569; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 570; CHECK-NEXT: ret i1 false 571; CHECK: out: 572; CHECK-NEXT: ret i1 false 573; 574entry: 575 %cmp = icmp sgt i32 %a, 5 576 br i1 %cmp, label %a_guard, label %out 577 578a_guard: 579 %cmp2 = icmp sgt i32 %b, 20 580 br i1 %cmp2, label %b_guard, label %out 581 582b_guard: 583 %sel_cmp = icmp sge i32 %a, %b 584 %max = select i1 %sel_cmp, i32 %a, i32 %b 585 %res = icmp eq i32 %max, 7 586 ret i1 %res 587out: 588 ret i1 false 589} 590 591define i1 @umax(i32 %a, i32 %b) { 592; CHECK-LABEL: @umax( 593; CHECK-NEXT: entry: 594; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 595; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 596; CHECK: a_guard: 597; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20 598; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 599; CHECK: b_guard: 600; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]] 601; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 602; CHECK-NEXT: ret i1 false 603; CHECK: out: 604; CHECK-NEXT: ret i1 false 605; 606entry: 607 %cmp = icmp sgt i32 %a, 5 608 br i1 %cmp, label %a_guard, label %out 609 610a_guard: 611 %cmp2 = icmp sgt i32 %b, 20 612 br i1 %cmp2, label %b_guard, label %out 613 614b_guard: 615 %sel_cmp = icmp uge i32 %a, %b 616 %max = select i1 %sel_cmp, i32 %a, i32 %b 617 %res = icmp eq i32 %max, 7 618 ret i1 %res 619out: 620 ret i1 false 621} 622 623define i1 @umin_lhs_overdefined_rhs_const(i32 %a) { 624; CHECK-LABEL: @umin_lhs_overdefined_rhs_const( 625; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 42 626; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42 627; CHECK-NEXT: ret i1 true 628; 629 %cmp = icmp ult i32 %a, 42 630 %sel = select i1 %cmp, i32 %a, i32 42 631 %cmp2 = icmp ule i32 %sel, 42 632 ret i1 %cmp2 633} 634 635define i1 @umin_rhs_overdefined_lhs_const(i32 %a) { 636; CHECK-LABEL: @umin_rhs_overdefined_lhs_const( 637; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], 42 638; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]] 639; CHECK-NEXT: ret i1 true 640; 641 %cmp = icmp uge i32 %a, 42 642 %sel = select i1 %cmp, i32 42, i32 %a 643 %cmp2 = icmp ule i32 %sel, 42 644 ret i1 %cmp2 645} 646 647define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) { 648; CHECK-LABEL: @umin_lhs_overdefined_rhs_range( 649; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42 650; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]]) 651; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B]] 652; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]] 653; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[SEL]], 42 654; CHECK-NEXT: ret i1 [[CMP2]] 655; 656 %assume = icmp ult i32 %b, 42 657 call void @llvm.assume(i1 %assume) 658 %cmp = icmp ult i32 %a, %b 659 %sel = select i1 %cmp, i32 %a, i32 %b 660 %cmp2 = icmp ult i32 %sel, 42 661 ret i1 %cmp2 662} 663 664define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) { 665; CHECK-LABEL: @umin_rhs_overdefined_lhs_range( 666; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42 667; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]]) 668; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], [[B]] 669; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]] 670; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[SEL]], 42 671; CHECK-NEXT: ret i1 [[CMP2]] 672; 673 %assume = icmp ult i32 %b, 42 674 call void @llvm.assume(i1 %assume) 675 %cmp = icmp uge i32 %a, %b 676 %sel = select i1 %cmp, i32 %b, i32 %a 677 %cmp2 = icmp ult i32 %sel, 42 678 ret i1 %cmp2 679} 680 681define i1 @clamp_low1(i32 %a) { 682; CHECK-LABEL: @clamp_low1( 683; CHECK-NEXT: entry: 684; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 685; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 686; CHECK: a_guard: 687; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5 688; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 689; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] 690; CHECK-NEXT: ret i1 false 691; CHECK: out: 692; CHECK-NEXT: ret i1 false 693; 694entry: 695 %cmp = icmp sge i32 %a, 5 696 br i1 %cmp, label %a_guard, label %out 697 698a_guard: 699 %sel_cmp = icmp eq i32 %a, 5 700 %add = add i32 %a, -1 701 %sel = select i1 %sel_cmp, i32 5, i32 %add 702 %res = icmp eq i32 %sel, 4 703 ret i1 %res 704out: 705 ret i1 false 706} 707 708define i1 @clamp_low2(i32 %a) { 709; CHECK-LABEL: @clamp_low2( 710; CHECK-NEXT: entry: 711; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 712; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 713; CHECK: a_guard: 714; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 715; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 716; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 717; CHECK-NEXT: ret i1 false 718; CHECK: out: 719; CHECK-NEXT: ret i1 false 720; 721entry: 722 %cmp = icmp sge i32 %a, 5 723 br i1 %cmp, label %a_guard, label %out 724 725a_guard: 726 %sel_cmp = icmp ne i32 %a, 5 727 %add = add i32 %a, -1 728 %sel = select i1 %sel_cmp, i32 %add, i32 5 729 %res = icmp eq i32 %sel, 4 730 ret i1 %res 731out: 732 ret i1 false 733} 734 735define i1 @clamp_low3(i32 %a) { 736; CHECK-LABEL: @clamp_low3( 737; CHECK-NEXT: entry: 738; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 739; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 740; CHECK: a_guard: 741; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sgt i32 [[A]], 5 742; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 743; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 744; CHECK-NEXT: ret i1 false 745; CHECK: out: 746; CHECK-NEXT: ret i1 false 747; 748entry: 749 %cmp = icmp sge i32 %a, 5 750 br i1 %cmp, label %a_guard, label %out 751 752a_guard: 753 %sel_cmp = icmp sgt i32 %a, 5 754 %add = add i32 %a, -1 755 %sel = select i1 %sel_cmp, i32 %add, i32 5 756 %res = icmp eq i32 %sel, 4 757 ret i1 %res 758out: 759 ret i1 false 760} 761 762define i1 @clamp_low4(i32 %a) { 763; CHECK-LABEL: @clamp_low4( 764; CHECK-NEXT: entry: 765; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 766; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 767; CHECK: a_guard: 768; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sle i32 [[A]], 5 769; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 770; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] 771; CHECK-NEXT: ret i1 false 772; CHECK: out: 773; CHECK-NEXT: ret i1 false 774; 775entry: 776 %cmp = icmp sge i32 %a, 5 777 br i1 %cmp, label %a_guard, label %out 778 779a_guard: 780 %sel_cmp = icmp sle i32 %a, 5 781 %add = add i32 %a, -1 782 %sel = select i1 %sel_cmp, i32 5, i32 %add 783 %res = icmp eq i32 %sel, 4 784 ret i1 %res 785out: 786 ret i1 false 787} 788 789define i1 @clamp_high1(i32 %a) { 790; CHECK-LABEL: @clamp_high1( 791; CHECK-NEXT: entry: 792; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 793; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 794; CHECK: a_guard: 795; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5 796; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 797; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] 798; CHECK-NEXT: ret i1 false 799; CHECK: out: 800; CHECK-NEXT: ret i1 false 801; 802entry: 803 %cmp = icmp sle i32 %a, 5 804 br i1 %cmp, label %a_guard, label %out 805 806a_guard: 807 %sel_cmp = icmp eq i32 %a, 5 808 %add = add i32 %a, 1 809 %sel = select i1 %sel_cmp, i32 5, i32 %add 810 %res = icmp eq i32 %sel, 6 811 ret i1 %res 812out: 813 ret i1 false 814} 815 816define i1 @clamp_high2(i32 %a) { 817; CHECK-LABEL: @clamp_high2( 818; CHECK-NEXT: entry: 819; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 820; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 821; CHECK: a_guard: 822; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 823; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 824; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 825; CHECK-NEXT: ret i1 false 826; CHECK: out: 827; CHECK-NEXT: ret i1 false 828; 829entry: 830 %cmp = icmp sle i32 %a, 5 831 br i1 %cmp, label %a_guard, label %out 832 833a_guard: 834 %sel_cmp = icmp ne i32 %a, 5 835 %add = add i32 %a, 1 836 %sel = select i1 %sel_cmp, i32 %add, i32 5 837 %res = icmp eq i32 %sel, 6 838 ret i1 %res 839out: 840 ret i1 false 841} 842 843define i1 @clamp_high3(i32 %a) { 844; CHECK-LABEL: @clamp_high3( 845; CHECK-NEXT: entry: 846; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 847; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 848; CHECK: a_guard: 849; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5 850; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 851; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 852; CHECK-NEXT: ret i1 false 853; CHECK: out: 854; CHECK-NEXT: ret i1 false 855; 856entry: 857 %cmp = icmp sle i32 %a, 5 858 br i1 %cmp, label %a_guard, label %out 859 860a_guard: 861 %sel_cmp = icmp slt i32 %a, 5 862 %add = add i32 %a, 1 863 %sel = select i1 %sel_cmp, i32 %add, i32 5 864 %res = icmp eq i32 %sel, 6 865 ret i1 %res 866out: 867 ret i1 false 868} 869 870define i1 @clamp_high4(i32 %a) { 871; CHECK-LABEL: @clamp_high4( 872; CHECK-NEXT: entry: 873; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 874; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 875; CHECK: a_guard: 876; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5 877; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 878; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] 879; CHECK-NEXT: ret i1 false 880; CHECK: out: 881; CHECK-NEXT: ret i1 false 882; 883entry: 884 %cmp = icmp sle i32 %a, 5 885 br i1 %cmp, label %a_guard, label %out 886 887a_guard: 888 %sel_cmp = icmp sge i32 %a, 5 889 %add = add i32 %a, 1 890 %sel = select i1 %sel_cmp, i32 5, i32 %add 891 %res = icmp eq i32 %sel, 6 892 ret i1 %res 893out: 894 ret i1 false 895} 896 897; Just showing arbitrary constants work, not really a clamp 898define i1 @not_clamp_high(i32 %a) { 899; CHECK-LABEL: @not_clamp_high( 900; CHECK-NEXT: entry: 901; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 902; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 903; CHECK: a_guard: 904; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 905; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 100 906; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 907; CHECK-NEXT: ret i1 false 908; CHECK: out: 909; CHECK-NEXT: ret i1 false 910; 911entry: 912 %cmp = icmp sle i32 %a, 5 913 br i1 %cmp, label %a_guard, label %out 914 915a_guard: 916 %sel_cmp = icmp ne i32 %a, 5 917 %add = add i32 %a, 100 918 %sel = select i1 %sel_cmp, i32 %add, i32 5 919 %res = icmp eq i32 %sel, 105 920 ret i1 %res 921out: 922 ret i1 false 923} 924 925define void @abs1(i32 %a, i1* %p) { 926; CHECK-LABEL: @abs1( 927; CHECK-NEXT: entry: 928; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 929; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 930; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 931; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 932; CHECK: guard: 933; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 934; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0 935; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]] 936; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 937; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[ABS]], 19 938; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 939; CHECK-NEXT: store i1 true, i1* [[P]], align 1 940; CHECK-NEXT: [[C4:%.*]] = icmp sge i32 [[ABS]], 1 941; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 942; CHECK-NEXT: br label [[EXIT]] 943; CHECK: exit: 944; CHECK-NEXT: ret void 945; 946entry: 947 %cmp1 = icmp slt i32 %a, 10 948 %cmp2 = icmp sgt i32 %a, -20 949 %and = and i1 %cmp1, %cmp2 950 br i1 %and, label %guard, label %exit 951 952guard: 953 %sub = sub i32 0, %a 954 %cmp = icmp slt i32 %a, 0 955 %abs = select i1 %cmp, i32 %sub, i32 %a 956 %c1 = icmp slt i32 %abs, 20 957 store i1 %c1, i1* %p 958 %c2 = icmp slt i32 %abs, 19 959 store i1 %c2, i1* %p 960 %c3 = icmp sge i32 %abs, 0 961 store i1 %c3, i1* %p 962 %c4 = icmp sge i32 %abs, 1 963 store i1 %c4, i1* %p 964 br label %exit 965 966exit: 967 ret void 968} 969 970define void @abs2(i32 %a, i1* %p) { 971; CHECK-LABEL: @abs2( 972; CHECK-NEXT: entry: 973; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 974; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 975; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 976; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 977; CHECK: guard: 978; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 979; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 0 980; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]] 981; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 982; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[ABS]], 19 983; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 984; CHECK-NEXT: store i1 true, i1* [[P]], align 1 985; CHECK-NEXT: [[C4:%.*]] = icmp sge i32 [[ABS]], 1 986; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 987; CHECK-NEXT: br label [[EXIT]] 988; CHECK: exit: 989; CHECK-NEXT: ret void 990; 991entry: 992 %cmp1 = icmp slt i32 %a, 10 993 %cmp2 = icmp sgt i32 %a, -20 994 %and = and i1 %cmp1, %cmp2 995 br i1 %and, label %guard, label %exit 996 997guard: 998 %sub = sub i32 0, %a 999 %cmp = icmp sge i32 %a, 0 1000 %abs = select i1 %cmp, i32 %a, i32 %sub 1001 %c1 = icmp slt i32 %abs, 20 1002 store i1 %c1, i1* %p 1003 %c2 = icmp slt i32 %abs, 19 1004 store i1 %c2, i1* %p 1005 %c3 = icmp sge i32 %abs, 0 1006 store i1 %c3, i1* %p 1007 %c4 = icmp sge i32 %abs, 1 1008 store i1 %c4, i1* %p 1009 br label %exit 1010 1011exit: 1012 ret void 1013} 1014 1015define void @nabs1(i32 %a, i1* %p) { 1016; CHECK-LABEL: @nabs1( 1017; CHECK-NEXT: entry: 1018; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 1019; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 1020; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 1021; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1022; CHECK: guard: 1023; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 1024; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0 1025; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]] 1026; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 1027; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19 1028; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1029; CHECK-NEXT: store i1 true, i1* [[P]], align 1 1030; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1 1031; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 1032; CHECK-NEXT: br label [[EXIT]] 1033; CHECK: exit: 1034; CHECK-NEXT: ret void 1035; 1036entry: 1037 %cmp1 = icmp slt i32 %a, 10 1038 %cmp2 = icmp sgt i32 %a, -20 1039 %and = and i1 %cmp1, %cmp2 1040 br i1 %and, label %guard, label %exit 1041 1042guard: 1043 %sub = sub i32 0, %a 1044 %cmp = icmp sgt i32 %a, 0 1045 %nabs = select i1 %cmp, i32 %sub, i32 %a 1046 %c1 = icmp sgt i32 %nabs, -20 1047 store i1 %c1, i1* %p 1048 %c2 = icmp sgt i32 %nabs, -19 1049 store i1 %c2, i1* %p 1050 %c3 = icmp sle i32 %nabs, 0 1051 store i1 %c3, i1* %p 1052 %c4 = icmp sle i32 %nabs, -1 1053 store i1 %c4, i1* %p 1054 br label %exit 1055 1056exit: 1057 ret void 1058} 1059 1060define void @nabs2(i32 %a, i1* %p) { 1061; CHECK-LABEL: @nabs2( 1062; CHECK-NEXT: entry: 1063; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 1064; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 1065; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 1066; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1067; CHECK: guard: 1068; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 1069; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0 1070; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]] 1071; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 1072; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19 1073; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1074; CHECK-NEXT: store i1 true, i1* [[P]], align 1 1075; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1 1076; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 1077; CHECK-NEXT: br label [[EXIT]] 1078; CHECK: exit: 1079; CHECK-NEXT: ret void 1080; 1081entry: 1082 %cmp1 = icmp slt i32 %a, 10 1083 %cmp2 = icmp sgt i32 %a, -20 1084 %and = and i1 %cmp1, %cmp2 1085 br i1 %and, label %guard, label %exit 1086 1087guard: 1088 %sub = sub i32 0, %a 1089 %cmp = icmp slt i32 %a, 0 1090 %nabs = select i1 %cmp, i32 %a, i32 %sub 1091 %c1 = icmp sgt i32 %nabs, -20 1092 store i1 %c1, i1* %p 1093 %c2 = icmp sgt i32 %nabs, -19 1094 store i1 %c2, i1* %p 1095 %c3 = icmp sle i32 %nabs, 0 1096 store i1 %c3, i1* %p 1097 %c4 = icmp sle i32 %nabs, -1 1098 store i1 %c4, i1* %p 1099 br label %exit 1100 1101exit: 1102 ret void 1103} 1104 1105define i1 @zext_unknown(i8 %a) { 1106; CHECK-LABEL: @zext_unknown( 1107; CHECK-NEXT: entry: 1108; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A:%.*]] to i32 1109; CHECK-NEXT: ret i1 true 1110; 1111entry: 1112 %a32 = zext i8 %a to i32 1113 %cmp = icmp sle i32 %a32, 256 1114 ret i1 %cmp 1115} 1116 1117define i1 @trunc_unknown(i32 %a) { 1118; CHECK-LABEL: @trunc_unknown( 1119; CHECK-NEXT: entry: 1120; CHECK-NEXT: [[A8:%.*]] = trunc i32 [[A:%.*]] to i8 1121; CHECK-NEXT: [[A32:%.*]] = sext i8 [[A8]] to i32 1122; CHECK-NEXT: ret i1 true 1123; 1124entry: 1125 %a8 = trunc i32 %a to i8 1126 %a32 = sext i8 %a8 to i32 1127 %cmp = icmp sle i32 %a32, 128 1128 ret i1 %cmp 1129} 1130 1131; TODO: missed optimization 1132; Make sure we exercise non-integer inputs to unary operators (i.e. crash check). 1133define i1 @bitcast_unknown(float %a) { 1134; CHECK-LABEL: @bitcast_unknown( 1135; CHECK-NEXT: entry: 1136; CHECK-NEXT: [[A32:%.*]] = bitcast float [[A:%.*]] to i32 1137; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A32]], 128 1138; CHECK-NEXT: ret i1 [[CMP]] 1139; 1140entry: 1141 %a32 = bitcast float %a to i32 1142 %cmp = icmp sle i32 %a32, 128 1143 ret i1 %cmp 1144} 1145 1146define i1 @bitcast_unknown2(i8* %p) { 1147; CHECK-LABEL: @bitcast_unknown2( 1148; CHECK-NEXT: entry: 1149; CHECK-NEXT: [[P64:%.*]] = ptrtoint i8* [[P:%.*]] to i64 1150; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[P64]], 128 1151; CHECK-NEXT: ret i1 [[CMP]] 1152; 1153entry: 1154 %p64 = ptrtoint i8* %p to i64 1155 %cmp = icmp sle i64 %p64, 128 1156 ret i1 %cmp 1157} 1158 1159 1160define i1 @and_unknown(i32 %a) { 1161; CHECK-LABEL: @and_unknown( 1162; CHECK-NEXT: entry: 1163; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 128 1164; CHECK-NEXT: ret i1 true 1165; 1166entry: 1167 %and = and i32 %a, 128 1168 %cmp = icmp sle i32 %and, 128 1169 ret i1 %cmp 1170} 1171 1172define i1 @lshr_unknown(i32 %a) { 1173; CHECK-LABEL: @lshr_unknown( 1174; CHECK-NEXT: entry: 1175; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[A:%.*]], 30 1176; CHECK-NEXT: ret i1 true 1177; 1178entry: 1179 %and = lshr i32 %a, 30 1180 %cmp = icmp sle i32 %and, 128 1181 ret i1 %cmp 1182} 1183 1184define i1 @urem_unknown(i32 %a) { 1185; CHECK-LABEL: @urem_unknown( 1186; CHECK-NEXT: entry: 1187; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[A:%.*]], 30 1188; CHECK-NEXT: ret i1 true 1189; 1190entry: 1191 %urem = urem i32 %a, 30 1192 %cmp = icmp ult i32 %urem, 30 1193 ret i1 %cmp 1194} 1195 1196define i1 @srem_unknown(i32 %a) { 1197; CHECK-LABEL: @srem_unknown( 1198; CHECK-NEXT: entry: 1199; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[A:%.*]], 30 1200; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1201; CHECK: exit1: 1202; CHECK-NEXT: ret i1 true 1203; CHECK: exit2: 1204; CHECK-NEXT: ret i1 true 1205; 1206entry: 1207 %srem = srem i32 %a, 30 1208 %cmp1 = icmp slt i32 %srem, 30 1209 %cmp2 = icmp sgt i32 %srem, -30 1210 br i1 undef, label %exit1, label %exit2 1211exit1: 1212 ret i1 %cmp1 1213exit2: 1214 ret i1 %cmp2 1215} 1216 1217define i1 @sdiv_unknown(i32 %a) { 1218; CHECK-LABEL: @sdiv_unknown( 1219; CHECK-NEXT: entry: 1220; CHECK-NEXT: [[SREM:%.*]] = sdiv i32 [[A:%.*]], 123 1221; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1222; CHECK: exit1: 1223; CHECK-NEXT: ret i1 true 1224; CHECK: exit2: 1225; CHECK-NEXT: ret i1 true 1226; 1227entry: 1228 %srem = sdiv i32 %a, 123 1229 %cmp1 = icmp slt i32 %srem, 17459217 1230 %cmp2 = icmp sgt i32 %srem, -17459217 1231 br i1 undef, label %exit1, label %exit2 1232exit1: 1233 ret i1 %cmp1 1234exit2: 1235 ret i1 %cmp2 1236} 1237 1238define i1 @uadd_sat_unknown(i32 %a) { 1239; CHECK-LABEL: @uadd_sat_unknown( 1240; CHECK-NEXT: entry: 1241; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A:%.*]], i32 100) 1242; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100 1243; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1244; CHECK: exit1: 1245; CHECK-NEXT: ret i1 true 1246; CHECK: exit2: 1247; CHECK-NEXT: ret i1 [[CMP2]] 1248; 1249entry: 1250 %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100) 1251 %cmp1 = icmp uge i32 %val, 100 1252 %cmp2 = icmp ugt i32 %val, 100 1253 br i1 undef, label %exit1, label %exit2 1254exit1: 1255 ret i1 %cmp1 1256exit2: 1257 ret i1 %cmp2 1258} 1259 1260define i1 @usub_sat_unknown(i32 %a) { 1261; CHECK-LABEL: @usub_sat_unknown( 1262; CHECK-NEXT: entry: 1263; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 100) 1264; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101 1265; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1266; CHECK: exit1: 1267; CHECK-NEXT: ret i1 true 1268; CHECK: exit2: 1269; CHECK-NEXT: ret i1 [[CMP2]] 1270; 1271entry: 1272 %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100) 1273 %cmp1 = icmp ule i32 %val, 4294967195 1274 %cmp2 = icmp ult i32 %val, 4294967195 1275 br i1 undef, label %exit1, label %exit2 1276exit1: 1277 ret i1 %cmp1 1278exit2: 1279 ret i1 %cmp2 1280} 1281 1282define i1 @sadd_sat_unknown(i32 %a) { 1283; CHECK-LABEL: @sadd_sat_unknown( 1284; CHECK-NEXT: entry: 1285; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 100) 1286; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548 1287; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1288; CHECK: exit1: 1289; CHECK-NEXT: ret i1 true 1290; CHECK: exit2: 1291; CHECK-NEXT: ret i1 [[CMP2]] 1292; 1293entry: 1294 %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100) 1295 %cmp1 = icmp sge i32 %val, -2147483548 1296 %cmp2 = icmp sgt i32 %val, -2147483548 1297 br i1 undef, label %exit1, label %exit2 1298exit1: 1299 ret i1 %cmp1 1300exit2: 1301 ret i1 %cmp2 1302} 1303 1304define i1 @ssub_sat_unknown(i32 %a) { 1305; CHECK-LABEL: @ssub_sat_unknown( 1306; CHECK-NEXT: entry: 1307; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 100) 1308; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547 1309; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1310; CHECK: exit1: 1311; CHECK-NEXT: ret i1 true 1312; CHECK: exit2: 1313; CHECK-NEXT: ret i1 [[CMP2]] 1314; 1315entry: 1316 %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100) 1317 %cmp1 = icmp sle i32 %val, 2147483547 1318 %cmp2 = icmp slt i32 %val, 2147483547 1319 br i1 undef, label %exit1, label %exit2 1320exit1: 1321 ret i1 %cmp1 1322exit2: 1323 ret i1 %cmp2 1324} 1325 1326define void @select_and(i32 %a, i1* %p) { 1327; CHECK-LABEL: @select_and( 1328; CHECK-NEXT: entry: 1329; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10 1330; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10 1331; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false 1332; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1333; CHECK: guard: 1334; CHECK-NEXT: store i1 false, i1* [[P:%.*]], align 1 1335; CHECK-NEXT: store i1 false, i1* [[P]], align 1 1336; CHECK-NEXT: br label [[EXIT]] 1337; CHECK: exit: 1338; CHECK-NEXT: ret void 1339; 1340entry: 1341 %cmp1 = icmp sgt i32 %a, -10 1342 %cmp2 = icmp slt i32 %a, 10 1343 %and = select i1 %cmp1, i1 %cmp2, i1 false 1344 br i1 %and, label %guard, label %exit 1345 1346guard: 1347 %c1 = icmp sgt i32 %a, 20 1348 store i1 %c1, i1* %p 1349 %c2 = icmp slt i32 %a, -20 1350 store i1 %c2, i1* %p 1351 br label %exit 1352 1353exit: 1354 ret void 1355} 1356 1357define void @select_and_wrong_const(i32 %a, i1* %p) { 1358; CHECK-LABEL: @select_and_wrong_const( 1359; CHECK-NEXT: entry: 1360; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10 1361; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10 1362; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true 1363; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1364; CHECK: guard: 1365; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20 1366; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1 1367; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20 1368; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1369; CHECK-NEXT: br label [[EXIT]] 1370; CHECK: exit: 1371; CHECK-NEXT: ret void 1372; 1373entry: 1374 %cmp1 = icmp sgt i32 %a, -10 1375 %cmp2 = icmp slt i32 %a, 10 1376 %and = select i1 %cmp1, i1 %cmp2, i1 true 1377 br i1 %and, label %guard, label %exit 1378 1379guard: 1380 %c1 = icmp sgt i32 %a, 20 1381 store i1 %c1, i1* %p 1382 %c2 = icmp slt i32 %a, -20 1383 store i1 %c2, i1* %p 1384 br label %exit 1385 1386exit: 1387 ret void 1388} 1389 1390define void @select_and_wrong_operand(i32 %a, i1* %p) { 1391; CHECK-LABEL: @select_and_wrong_operand( 1392; CHECK-NEXT: entry: 1393; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10 1394; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10 1395; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]] 1396; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1397; CHECK: guard: 1398; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20 1399; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1 1400; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20 1401; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1402; CHECK-NEXT: br label [[EXIT]] 1403; CHECK: exit: 1404; CHECK-NEXT: ret void 1405; 1406entry: 1407 %cmp1 = icmp sgt i32 %a, -10 1408 %cmp2 = icmp slt i32 %a, 10 1409 %and = select i1 %cmp1, i1 false, i1 %cmp2 1410 br i1 %and, label %guard, label %exit 1411 1412guard: 1413 %c1 = icmp sgt i32 %a, 20 1414 store i1 %c1, i1* %p 1415 %c2 = icmp slt i32 %a, -20 1416 store i1 %c2, i1* %p 1417 br label %exit 1418 1419exit: 1420 ret void 1421} 1422 1423define void @select_or(i32 %a, i1* %p) { 1424; CHECK-LABEL: @select_or( 1425; CHECK-NEXT: entry: 1426; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10 1427; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10 1428; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]] 1429; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1430; CHECK: guard: 1431; CHECK-NEXT: store i1 false, i1* [[P:%.*]], align 1 1432; CHECK-NEXT: store i1 false, i1* [[P]], align 1 1433; CHECK-NEXT: br label [[EXIT]] 1434; CHECK: exit: 1435; CHECK-NEXT: ret void 1436; 1437entry: 1438 %cmp1 = icmp slt i32 %a, -10 1439 %cmp2 = icmp sgt i32 %a, 10 1440 %or = select i1 %cmp1, i1 true, i1 %cmp2 1441 br i1 %or, label %exit, label %guard 1442 1443guard: 1444 %c1 = icmp sgt i32 %a, 20 1445 store i1 %c1, i1* %p 1446 %c2 = icmp slt i32 %a, -20 1447 store i1 %c2, i1* %p 1448 br label %exit 1449 1450exit: 1451 ret void 1452} 1453 1454define void @select_or_wrong_const(i32 %a, i1* %p) { 1455; CHECK-LABEL: @select_or_wrong_const( 1456; CHECK-NEXT: entry: 1457; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10 1458; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10 1459; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]] 1460; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1461; CHECK: guard: 1462; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20 1463; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1 1464; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20 1465; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1466; CHECK-NEXT: br label [[EXIT]] 1467; CHECK: exit: 1468; CHECK-NEXT: ret void 1469; 1470entry: 1471 %cmp1 = icmp slt i32 %a, -10 1472 %cmp2 = icmp sgt i32 %a, 10 1473 %or = select i1 %cmp1, i1 false, i1 %cmp2 1474 br i1 %or, label %exit, label %guard 1475 1476guard: 1477 %c1 = icmp sgt i32 %a, 20 1478 store i1 %c1, i1* %p 1479 %c2 = icmp slt i32 %a, -20 1480 store i1 %c2, i1* %p 1481 br label %exit 1482 1483exit: 1484 ret void 1485} 1486 1487define void @select_or_wrong_operand(i32 %a, i1* %p) { 1488; CHECK-LABEL: @select_or_wrong_operand( 1489; CHECK-NEXT: entry: 1490; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10 1491; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10 1492; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true 1493; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1494; CHECK: guard: 1495; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20 1496; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1 1497; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20 1498; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1499; CHECK-NEXT: br label [[EXIT]] 1500; CHECK: exit: 1501; CHECK-NEXT: ret void 1502; 1503entry: 1504 %cmp1 = icmp slt i32 %a, -10 1505 %cmp2 = icmp sgt i32 %a, 10 1506 %or = select i1 %cmp1, i1 %cmp2, i1 true 1507 br i1 %or, label %exit, label %guard 1508 1509guard: 1510 %c1 = icmp sgt i32 %a, 20 1511 store i1 %c1, i1* %p 1512 %c2 = icmp slt i32 %a, -20 1513 store i1 %c2, i1* %p 1514 br label %exit 1515 1516exit: 1517 ret void 1518} 1519 1520define void @or_union(i32 %a, i1* %p) { 1521; CHECK-LABEL: @or_union( 1522; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10 1523; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 12 1524; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 1525; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1526; CHECK: guard: 1527; CHECK-NEXT: store i1 false, i1* [[P:%.*]], align 1 1528; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 10 1529; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1530; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 11 1531; CHECK-NEXT: store i1 [[C3]], i1* [[P]], align 1 1532; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 12 1533; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 1534; CHECK-NEXT: store i1 false, i1* [[P]], align 1 1535; CHECK-NEXT: br label [[EXIT]] 1536; CHECK: exit: 1537; CHECK-NEXT: ret void 1538; 1539 %cmp1 = icmp eq i32 %a, 10 1540 %cmp2 = icmp eq i32 %a, 12 1541 %or = or i1 %cmp1, %cmp2 1542 br i1 %or, label %guard, label %exit 1543 1544guard: 1545 %c1 = icmp eq i32 %a, 9 1546 store i1 %c1, i1* %p 1547 %c2 = icmp eq i32 %a, 10 1548 store i1 %c2, i1* %p 1549 %c3 = icmp eq i32 %a, 11 1550 store i1 %c3, i1* %p 1551 %c4 = icmp eq i32 %a, 12 1552 store i1 %c4, i1* %p 1553 %c5 = icmp eq i32 %a, 13 1554 store i1 %c5, i1* %p 1555 br label %exit 1556 1557exit: 1558 ret void 1559} 1560 1561define i1 @or_union_unknown_cond(i32 %a, i1 %c) { 1562; CHECK-LABEL: @or_union_unknown_cond( 1563; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10 1564; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[C:%.*]] 1565; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1566; CHECK: guard: 1567; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 10 1568; CHECK-NEXT: ret i1 [[CMP2]] 1569; CHECK: exit: 1570; CHECK-NEXT: ret i1 false 1571; 1572 %cmp1 = icmp eq i32 %a, 10 1573 %or = or i1 %cmp1, %c 1574 br i1 %or, label %guard, label %exit 1575 1576guard: 1577 %cmp2 = icmp eq i32 %a, 10 1578 ret i1 %cmp2 1579 1580exit: 1581 ret i1 false 1582} 1583 1584define void @and_union(i32 %a, i1* %p) { 1585; CHECK-LABEL: @and_union( 1586; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10 1587; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], 12 1588; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 1589; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1590; CHECK: guard: 1591; CHECK-NEXT: store i1 false, i1* [[P:%.*]], align 1 1592; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 10 1593; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1594; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 11 1595; CHECK-NEXT: store i1 [[C3]], i1* [[P]], align 1 1596; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 12 1597; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 1598; CHECK-NEXT: store i1 false, i1* [[P]], align 1 1599; CHECK-NEXT: br label [[EXIT]] 1600; CHECK: exit: 1601; CHECK-NEXT: ret void 1602; 1603 %cmp1 = icmp ne i32 %a, 10 1604 %cmp2 = icmp ne i32 %a, 12 1605 %and = and i1 %cmp1, %cmp2 1606 br i1 %and, label %exit, label %guard 1607 1608guard: 1609 %c1 = icmp eq i32 %a, 9 1610 store i1 %c1, i1* %p 1611 %c2 = icmp eq i32 %a, 10 1612 store i1 %c2, i1* %p 1613 %c3 = icmp eq i32 %a, 11 1614 store i1 %c3, i1* %p 1615 %c4 = icmp eq i32 %a, 12 1616 store i1 %c4, i1* %p 1617 %c5 = icmp eq i32 %a, 13 1618 store i1 %c5, i1* %p 1619 br label %exit 1620 1621exit: 1622 ret void 1623} 1624 1625define i1 @and_union_unknown_cond(i32 %a, i1 %c) { 1626; CHECK-LABEL: @and_union_unknown_cond( 1627; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10 1628; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[C:%.*]] 1629; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1630; CHECK: guard: 1631; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 10 1632; CHECK-NEXT: ret i1 [[CMP2]] 1633; CHECK: exit: 1634; CHECK-NEXT: ret i1 false 1635; 1636 %cmp1 = icmp ne i32 %a, 10 1637 %and = and i1 %cmp1, %c 1638 br i1 %and, label %exit, label %guard 1639 1640guard: 1641 %cmp2 = icmp eq i32 %a, 10 1642 ret i1 %cmp2 1643 1644exit: 1645 ret i1 false 1646} 1647 1648 1649declare i32 @llvm.uadd.sat.i32(i32, i32) 1650declare i32 @llvm.usub.sat.i32(i32, i32) 1651declare i32 @llvm.sadd.sat.i32(i32, i32) 1652declare i32 @llvm.ssub.sat.i32(i32, i32) 1653declare void @llvm.assume(i1) 1654