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