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 i1 @arg_attribute(i8* nonnull %a) { 381; CHECK-LABEL: @arg_attribute( 382; CHECK-NEXT: ret i1 false 383; 384 %cmp = icmp eq i8* %a, null 385 ret i1 %cmp 386} 387 388declare nonnull i8* @return_nonnull() 389define i1 @call_attribute() { 390; CHECK-LABEL: @call_attribute( 391; CHECK-NEXT: [[A:%.*]] = call i8* @return_nonnull() 392; CHECK-NEXT: ret i1 false 393; 394 %a = call i8* @return_nonnull() 395 %cmp = icmp eq i8* %a, null 396 ret i1 %cmp 397} 398 399define i1 @umin(i32 %a, i32 %b) { 400; CHECK-LABEL: @umin( 401; CHECK-NEXT: entry: 402; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5 403; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 404; CHECK: a_guard: 405; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20 406; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 407; CHECK: b_guard: 408; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]] 409; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 410; CHECK-NEXT: ret i1 false 411; CHECK: out: 412; CHECK-NEXT: ret i1 false 413; 414entry: 415 %cmp = icmp ult i32 %a, 5 416 br i1 %cmp, label %a_guard, label %out 417 418a_guard: 419 %cmp2 = icmp ult i32 %b, 20 420 br i1 %cmp2, label %b_guard, label %out 421 422b_guard: 423 %sel_cmp = icmp ult i32 %a, %b 424 %min = select i1 %sel_cmp, i32 %a, i32 %b 425 %res = icmp eq i32 %min, 7 426 ret i1 %res 427out: 428 ret i1 false 429} 430 431define i1 @smin(i32 %a, i32 %b) { 432; CHECK-LABEL: @smin( 433; CHECK-NEXT: entry: 434; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5 435; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 436; CHECK: a_guard: 437; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20 438; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 439; CHECK: b_guard: 440; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sle i32 [[A]], [[B]] 441; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 442; CHECK-NEXT: ret i1 false 443; CHECK: out: 444; CHECK-NEXT: ret i1 false 445; 446entry: 447 %cmp = icmp ult i32 %a, 5 448 br i1 %cmp, label %a_guard, label %out 449 450a_guard: 451 %cmp2 = icmp ult i32 %b, 20 452 br i1 %cmp2, label %b_guard, label %out 453 454b_guard: 455 %sel_cmp = icmp sle i32 %a, %b 456 %min = select i1 %sel_cmp, i32 %a, i32 %b 457 %res = icmp eq i32 %min, 7 458 ret i1 %res 459out: 460 ret i1 false 461} 462 463define i1 @smax(i32 %a, i32 %b) { 464; CHECK-LABEL: @smax( 465; CHECK-NEXT: entry: 466; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 467; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 468; CHECK: a_guard: 469; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20 470; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 471; CHECK: b_guard: 472; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], [[B]] 473; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 474; CHECK-NEXT: ret i1 false 475; CHECK: out: 476; CHECK-NEXT: ret i1 false 477; 478entry: 479 %cmp = icmp sgt i32 %a, 5 480 br i1 %cmp, label %a_guard, label %out 481 482a_guard: 483 %cmp2 = icmp sgt i32 %b, 20 484 br i1 %cmp2, label %b_guard, label %out 485 486b_guard: 487 %sel_cmp = icmp sge i32 %a, %b 488 %max = select i1 %sel_cmp, i32 %a, i32 %b 489 %res = icmp eq i32 %max, 7 490 ret i1 %res 491out: 492 ret i1 false 493} 494 495define i1 @umax(i32 %a, i32 %b) { 496; CHECK-LABEL: @umax( 497; CHECK-NEXT: entry: 498; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 499; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 500; CHECK: a_guard: 501; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20 502; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 503; CHECK: b_guard: 504; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]] 505; CHECK-NEXT: [[MAX:%.*]] = 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 sgt i32 %a, 5 512 br i1 %cmp, label %a_guard, label %out 513 514a_guard: 515 %cmp2 = icmp sgt i32 %b, 20 516 br i1 %cmp2, label %b_guard, label %out 517 518b_guard: 519 %sel_cmp = icmp uge i32 %a, %b 520 %max = select i1 %sel_cmp, i32 %a, i32 %b 521 %res = icmp eq i32 %max, 7 522 ret i1 %res 523out: 524 ret i1 false 525} 526 527define i1 @umin_lhs_overdefined_rhs_const(i32 %a) { 528; CHECK-LABEL: @umin_lhs_overdefined_rhs_const( 529; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 42 530; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42 531; CHECK-NEXT: ret i1 true 532; 533 %cmp = icmp ult i32 %a, 42 534 %sel = select i1 %cmp, i32 %a, i32 42 535 %cmp2 = icmp ule i32 %sel, 42 536 ret i1 %cmp2 537} 538 539define i1 @umin_rhs_overdefined_lhs_const(i32 %a) { 540; CHECK-LABEL: @umin_rhs_overdefined_lhs_const( 541; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], 42 542; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]] 543; CHECK-NEXT: ret i1 true 544; 545 %cmp = icmp uge i32 %a, 42 546 %sel = select i1 %cmp, i32 42, i32 %a 547 %cmp2 = icmp ule i32 %sel, 42 548 ret i1 %cmp2 549} 550 551define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) { 552; CHECK-LABEL: @umin_lhs_overdefined_rhs_range( 553; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42 554; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]]) 555; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B]] 556; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]] 557; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[SEL]], 42 558; CHECK-NEXT: ret i1 [[CMP2]] 559; 560 %assume = icmp ult i32 %b, 42 561 call void @llvm.assume(i1 %assume) 562 %cmp = icmp ult i32 %a, %b 563 %sel = select i1 %cmp, i32 %a, i32 %b 564 %cmp2 = icmp ult i32 %sel, 42 565 ret i1 %cmp2 566} 567 568define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) { 569; CHECK-LABEL: @umin_rhs_overdefined_lhs_range( 570; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42 571; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]]) 572; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], [[B]] 573; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]] 574; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[SEL]], 42 575; CHECK-NEXT: ret i1 [[CMP2]] 576; 577 %assume = icmp ult i32 %b, 42 578 call void @llvm.assume(i1 %assume) 579 %cmp = icmp uge i32 %a, %b 580 %sel = select i1 %cmp, i32 %b, i32 %a 581 %cmp2 = icmp ult i32 %sel, 42 582 ret i1 %cmp2 583} 584 585define i1 @clamp_low1(i32 %a) { 586; CHECK-LABEL: @clamp_low1( 587; CHECK-NEXT: entry: 588; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 589; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 590; CHECK: a_guard: 591; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5 592; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 593; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] 594; CHECK-NEXT: ret i1 false 595; CHECK: out: 596; CHECK-NEXT: ret i1 false 597; 598entry: 599 %cmp = icmp sge i32 %a, 5 600 br i1 %cmp, label %a_guard, label %out 601 602a_guard: 603 %sel_cmp = icmp eq i32 %a, 5 604 %add = add i32 %a, -1 605 %sel = select i1 %sel_cmp, i32 5, i32 %add 606 %res = icmp eq i32 %sel, 4 607 ret i1 %res 608out: 609 ret i1 false 610} 611 612define i1 @clamp_low2(i32 %a) { 613; CHECK-LABEL: @clamp_low2( 614; CHECK-NEXT: entry: 615; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 616; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 617; CHECK: a_guard: 618; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 619; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 620; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 621; CHECK-NEXT: ret i1 false 622; CHECK: out: 623; CHECK-NEXT: ret i1 false 624; 625entry: 626 %cmp = icmp sge i32 %a, 5 627 br i1 %cmp, label %a_guard, label %out 628 629a_guard: 630 %sel_cmp = icmp ne i32 %a, 5 631 %add = add i32 %a, -1 632 %sel = select i1 %sel_cmp, i32 %add, i32 5 633 %res = icmp eq i32 %sel, 4 634 ret i1 %res 635out: 636 ret i1 false 637} 638 639define i1 @clamp_low3(i32 %a) { 640; CHECK-LABEL: @clamp_low3( 641; CHECK-NEXT: entry: 642; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 643; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 644; CHECK: a_guard: 645; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sgt i32 [[A]], 5 646; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 647; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 648; CHECK-NEXT: ret i1 false 649; CHECK: out: 650; CHECK-NEXT: ret i1 false 651; 652entry: 653 %cmp = icmp sge i32 %a, 5 654 br i1 %cmp, label %a_guard, label %out 655 656a_guard: 657 %sel_cmp = icmp sgt i32 %a, 5 658 %add = add i32 %a, -1 659 %sel = select i1 %sel_cmp, i32 %add, i32 5 660 %res = icmp eq i32 %sel, 4 661 ret i1 %res 662out: 663 ret i1 false 664} 665 666define i1 @clamp_low4(i32 %a) { 667; CHECK-LABEL: @clamp_low4( 668; CHECK-NEXT: entry: 669; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 670; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 671; CHECK: a_guard: 672; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sle i32 [[A]], 5 673; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 674; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] 675; CHECK-NEXT: ret i1 false 676; CHECK: out: 677; CHECK-NEXT: ret i1 false 678; 679entry: 680 %cmp = icmp sge i32 %a, 5 681 br i1 %cmp, label %a_guard, label %out 682 683a_guard: 684 %sel_cmp = icmp sle i32 %a, 5 685 %add = add i32 %a, -1 686 %sel = select i1 %sel_cmp, i32 5, i32 %add 687 %res = icmp eq i32 %sel, 4 688 ret i1 %res 689out: 690 ret i1 false 691} 692 693define i1 @clamp_high1(i32 %a) { 694; CHECK-LABEL: @clamp_high1( 695; CHECK-NEXT: entry: 696; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 697; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 698; CHECK: a_guard: 699; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5 700; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 701; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] 702; CHECK-NEXT: ret i1 false 703; CHECK: out: 704; CHECK-NEXT: ret i1 false 705; 706entry: 707 %cmp = icmp sle i32 %a, 5 708 br i1 %cmp, label %a_guard, label %out 709 710a_guard: 711 %sel_cmp = icmp eq i32 %a, 5 712 %add = add i32 %a, 1 713 %sel = select i1 %sel_cmp, i32 5, i32 %add 714 %res = icmp eq i32 %sel, 6 715 ret i1 %res 716out: 717 ret i1 false 718} 719 720define i1 @clamp_high2(i32 %a) { 721; CHECK-LABEL: @clamp_high2( 722; CHECK-NEXT: entry: 723; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 724; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 725; CHECK: a_guard: 726; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 727; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 728; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 729; CHECK-NEXT: ret i1 false 730; CHECK: out: 731; CHECK-NEXT: ret i1 false 732; 733entry: 734 %cmp = icmp sle i32 %a, 5 735 br i1 %cmp, label %a_guard, label %out 736 737a_guard: 738 %sel_cmp = icmp ne i32 %a, 5 739 %add = add i32 %a, 1 740 %sel = select i1 %sel_cmp, i32 %add, i32 5 741 %res = icmp eq i32 %sel, 6 742 ret i1 %res 743out: 744 ret i1 false 745} 746 747define i1 @clamp_high3(i32 %a) { 748; CHECK-LABEL: @clamp_high3( 749; CHECK-NEXT: entry: 750; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 751; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 752; CHECK: a_guard: 753; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5 754; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 755; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 756; CHECK-NEXT: ret i1 false 757; CHECK: out: 758; CHECK-NEXT: ret i1 false 759; 760entry: 761 %cmp = icmp sle i32 %a, 5 762 br i1 %cmp, label %a_guard, label %out 763 764a_guard: 765 %sel_cmp = icmp slt i32 %a, 5 766 %add = add i32 %a, 1 767 %sel = select i1 %sel_cmp, i32 %add, i32 5 768 %res = icmp eq i32 %sel, 6 769 ret i1 %res 770out: 771 ret i1 false 772} 773 774define i1 @clamp_high4(i32 %a) { 775; CHECK-LABEL: @clamp_high4( 776; CHECK-NEXT: entry: 777; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 778; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 779; CHECK: a_guard: 780; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5 781; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 782; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] 783; CHECK-NEXT: ret i1 false 784; CHECK: out: 785; CHECK-NEXT: ret i1 false 786; 787entry: 788 %cmp = icmp sle i32 %a, 5 789 br i1 %cmp, label %a_guard, label %out 790 791a_guard: 792 %sel_cmp = icmp sge i32 %a, 5 793 %add = add i32 %a, 1 794 %sel = select i1 %sel_cmp, i32 5, i32 %add 795 %res = icmp eq i32 %sel, 6 796 ret i1 %res 797out: 798 ret i1 false 799} 800 801; Just showing arbitrary constants work, not really a clamp 802define i1 @not_clamp_high(i32 %a) { 803; CHECK-LABEL: @not_clamp_high( 804; CHECK-NEXT: entry: 805; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 806; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 807; CHECK: a_guard: 808; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 809; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 100 810; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 811; CHECK-NEXT: ret i1 false 812; CHECK: out: 813; CHECK-NEXT: ret i1 false 814; 815entry: 816 %cmp = icmp sle i32 %a, 5 817 br i1 %cmp, label %a_guard, label %out 818 819a_guard: 820 %sel_cmp = icmp ne i32 %a, 5 821 %add = add i32 %a, 100 822 %sel = select i1 %sel_cmp, i32 %add, i32 5 823 %res = icmp eq i32 %sel, 105 824 ret i1 %res 825out: 826 ret i1 false 827} 828 829define void @abs1(i32 %a, i1* %p) { 830; CHECK-LABEL: @abs1( 831; CHECK-NEXT: entry: 832; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 833; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 834; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 835; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 836; CHECK: guard: 837; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 838; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0 839; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]] 840; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 841; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[ABS]], 19 842; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 843; CHECK-NEXT: store i1 true, i1* [[P]], align 1 844; CHECK-NEXT: [[C4:%.*]] = icmp sge i32 [[ABS]], 1 845; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 846; CHECK-NEXT: br label [[EXIT]] 847; CHECK: exit: 848; CHECK-NEXT: ret void 849; 850entry: 851 %cmp1 = icmp slt i32 %a, 10 852 %cmp2 = icmp sgt i32 %a, -20 853 %and = and i1 %cmp1, %cmp2 854 br i1 %and, label %guard, label %exit 855 856guard: 857 %sub = sub i32 0, %a 858 %cmp = icmp slt i32 %a, 0 859 %abs = select i1 %cmp, i32 %sub, i32 %a 860 %c1 = icmp slt i32 %abs, 20 861 store i1 %c1, i1* %p 862 %c2 = icmp slt i32 %abs, 19 863 store i1 %c2, i1* %p 864 %c3 = icmp sge i32 %abs, 0 865 store i1 %c3, i1* %p 866 %c4 = icmp sge i32 %abs, 1 867 store i1 %c4, i1* %p 868 br label %exit 869 870exit: 871 ret void 872} 873 874define void @abs2(i32 %a, i1* %p) { 875; CHECK-LABEL: @abs2( 876; CHECK-NEXT: entry: 877; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 878; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 879; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 880; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 881; CHECK: guard: 882; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 883; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 0 884; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]] 885; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 886; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[ABS]], 19 887; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 888; CHECK-NEXT: store i1 true, i1* [[P]], align 1 889; CHECK-NEXT: [[C4:%.*]] = icmp sge i32 [[ABS]], 1 890; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 891; CHECK-NEXT: br label [[EXIT]] 892; CHECK: exit: 893; CHECK-NEXT: ret void 894; 895entry: 896 %cmp1 = icmp slt i32 %a, 10 897 %cmp2 = icmp sgt i32 %a, -20 898 %and = and i1 %cmp1, %cmp2 899 br i1 %and, label %guard, label %exit 900 901guard: 902 %sub = sub i32 0, %a 903 %cmp = icmp sge i32 %a, 0 904 %abs = select i1 %cmp, i32 %a, i32 %sub 905 %c1 = icmp slt i32 %abs, 20 906 store i1 %c1, i1* %p 907 %c2 = icmp slt i32 %abs, 19 908 store i1 %c2, i1* %p 909 %c3 = icmp sge i32 %abs, 0 910 store i1 %c3, i1* %p 911 %c4 = icmp sge i32 %abs, 1 912 store i1 %c4, i1* %p 913 br label %exit 914 915exit: 916 ret void 917} 918 919define void @nabs1(i32 %a, i1* %p) { 920; CHECK-LABEL: @nabs1( 921; CHECK-NEXT: entry: 922; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 923; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 924; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 925; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 926; CHECK: guard: 927; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 928; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0 929; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]] 930; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 931; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19 932; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 933; CHECK-NEXT: store i1 true, i1* [[P]], align 1 934; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1 935; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 936; CHECK-NEXT: br label [[EXIT]] 937; CHECK: exit: 938; CHECK-NEXT: ret void 939; 940entry: 941 %cmp1 = icmp slt i32 %a, 10 942 %cmp2 = icmp sgt i32 %a, -20 943 %and = and i1 %cmp1, %cmp2 944 br i1 %and, label %guard, label %exit 945 946guard: 947 %sub = sub i32 0, %a 948 %cmp = icmp sgt i32 %a, 0 949 %nabs = select i1 %cmp, i32 %sub, i32 %a 950 %c1 = icmp sgt i32 %nabs, -20 951 store i1 %c1, i1* %p 952 %c2 = icmp sgt i32 %nabs, -19 953 store i1 %c2, i1* %p 954 %c3 = icmp sle i32 %nabs, 0 955 store i1 %c3, i1* %p 956 %c4 = icmp sle i32 %nabs, -1 957 store i1 %c4, i1* %p 958 br label %exit 959 960exit: 961 ret void 962} 963 964define void @nabs2(i32 %a, i1* %p) { 965; CHECK-LABEL: @nabs2( 966; CHECK-NEXT: entry: 967; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 968; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 969; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 970; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 971; CHECK: guard: 972; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 973; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0 974; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]] 975; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 976; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19 977; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 978; CHECK-NEXT: store i1 true, i1* [[P]], align 1 979; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1 980; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 981; CHECK-NEXT: br label [[EXIT]] 982; CHECK: exit: 983; CHECK-NEXT: ret void 984; 985entry: 986 %cmp1 = icmp slt i32 %a, 10 987 %cmp2 = icmp sgt i32 %a, -20 988 %and = and i1 %cmp1, %cmp2 989 br i1 %and, label %guard, label %exit 990 991guard: 992 %sub = sub i32 0, %a 993 %cmp = icmp slt i32 %a, 0 994 %nabs = select i1 %cmp, i32 %a, i32 %sub 995 %c1 = icmp sgt i32 %nabs, -20 996 store i1 %c1, i1* %p 997 %c2 = icmp sgt i32 %nabs, -19 998 store i1 %c2, i1* %p 999 %c3 = icmp sle i32 %nabs, 0 1000 store i1 %c3, i1* %p 1001 %c4 = icmp sle i32 %nabs, -1 1002 store i1 %c4, i1* %p 1003 br label %exit 1004 1005exit: 1006 ret void 1007} 1008 1009define i1 @zext_unknown(i8 %a) { 1010; CHECK-LABEL: @zext_unknown( 1011; CHECK-NEXT: entry: 1012; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A:%.*]] to i32 1013; CHECK-NEXT: ret i1 true 1014; 1015entry: 1016 %a32 = zext i8 %a to i32 1017 %cmp = icmp sle i32 %a32, 256 1018 ret i1 %cmp 1019} 1020 1021define i1 @trunc_unknown(i32 %a) { 1022; CHECK-LABEL: @trunc_unknown( 1023; CHECK-NEXT: entry: 1024; CHECK-NEXT: [[A8:%.*]] = trunc i32 [[A:%.*]] to i8 1025; CHECK-NEXT: [[A32:%.*]] = sext i8 [[A8]] to i32 1026; CHECK-NEXT: ret i1 true 1027; 1028entry: 1029 %a8 = trunc i32 %a to i8 1030 %a32 = sext i8 %a8 to i32 1031 %cmp = icmp sle i32 %a32, 128 1032 ret i1 %cmp 1033} 1034 1035; TODO: missed optimization 1036; Make sure we exercise non-integer inputs to unary operators (i.e. crash check). 1037define i1 @bitcast_unknown(float %a) { 1038; CHECK-LABEL: @bitcast_unknown( 1039; CHECK-NEXT: entry: 1040; CHECK-NEXT: [[A32:%.*]] = bitcast float [[A:%.*]] to i32 1041; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A32]], 128 1042; CHECK-NEXT: ret i1 [[CMP]] 1043; 1044entry: 1045 %a32 = bitcast float %a to i32 1046 %cmp = icmp sle i32 %a32, 128 1047 ret i1 %cmp 1048} 1049 1050define i1 @bitcast_unknown2(i8* %p) { 1051; CHECK-LABEL: @bitcast_unknown2( 1052; CHECK-NEXT: entry: 1053; CHECK-NEXT: [[P64:%.*]] = ptrtoint i8* [[P:%.*]] to i64 1054; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[P64]], 128 1055; CHECK-NEXT: ret i1 [[CMP]] 1056; 1057entry: 1058 %p64 = ptrtoint i8* %p to i64 1059 %cmp = icmp sle i64 %p64, 128 1060 ret i1 %cmp 1061} 1062 1063 1064define i1 @and_unknown(i32 %a) { 1065; CHECK-LABEL: @and_unknown( 1066; CHECK-NEXT: entry: 1067; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 128 1068; CHECK-NEXT: ret i1 true 1069; 1070entry: 1071 %and = and i32 %a, 128 1072 %cmp = icmp sle i32 %and, 128 1073 ret i1 %cmp 1074} 1075 1076define i1 @lshr_unknown(i32 %a) { 1077; CHECK-LABEL: @lshr_unknown( 1078; CHECK-NEXT: entry: 1079; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[A:%.*]], 30 1080; CHECK-NEXT: ret i1 true 1081; 1082entry: 1083 %and = lshr i32 %a, 30 1084 %cmp = icmp sle i32 %and, 128 1085 ret i1 %cmp 1086} 1087 1088define i1 @urem_unknown(i32 %a) { 1089; CHECK-LABEL: @urem_unknown( 1090; CHECK-NEXT: entry: 1091; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[A:%.*]], 30 1092; CHECK-NEXT: ret i1 true 1093; 1094entry: 1095 %urem = urem i32 %a, 30 1096 %cmp = icmp ult i32 %urem, 30 1097 ret i1 %cmp 1098} 1099 1100define i1 @srem_unknown(i32 %a) { 1101; CHECK-LABEL: @srem_unknown( 1102; CHECK-NEXT: entry: 1103; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[A:%.*]], 30 1104; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1105; CHECK: exit1: 1106; CHECK-NEXT: ret i1 true 1107; CHECK: exit2: 1108; CHECK-NEXT: ret i1 true 1109; 1110entry: 1111 %srem = srem i32 %a, 30 1112 %cmp1 = icmp slt i32 %srem, 30 1113 %cmp2 = icmp sgt i32 %srem, -30 1114 br i1 undef, label %exit1, label %exit2 1115exit1: 1116 ret i1 %cmp1 1117exit2: 1118 ret i1 %cmp2 1119} 1120 1121define i1 @sdiv_unknown(i32 %a) { 1122; CHECK-LABEL: @sdiv_unknown( 1123; CHECK-NEXT: entry: 1124; CHECK-NEXT: [[SREM:%.*]] = sdiv i32 [[A:%.*]], 123 1125; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1126; CHECK: exit1: 1127; CHECK-NEXT: ret i1 true 1128; CHECK: exit2: 1129; CHECK-NEXT: ret i1 true 1130; 1131entry: 1132 %srem = sdiv i32 %a, 123 1133 %cmp1 = icmp slt i32 %srem, 17459217 1134 %cmp2 = icmp sgt i32 %srem, -17459217 1135 br i1 undef, label %exit1, label %exit2 1136exit1: 1137 ret i1 %cmp1 1138exit2: 1139 ret i1 %cmp2 1140} 1141 1142define i1 @uadd_sat_unknown(i32 %a) { 1143; CHECK-LABEL: @uadd_sat_unknown( 1144; CHECK-NEXT: entry: 1145; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A:%.*]], i32 100) 1146; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100 1147; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1148; CHECK: exit1: 1149; CHECK-NEXT: ret i1 true 1150; CHECK: exit2: 1151; CHECK-NEXT: ret i1 [[CMP2]] 1152; 1153entry: 1154 %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100) 1155 %cmp1 = icmp uge i32 %val, 100 1156 %cmp2 = icmp ugt i32 %val, 100 1157 br i1 undef, label %exit1, label %exit2 1158exit1: 1159 ret i1 %cmp1 1160exit2: 1161 ret i1 %cmp2 1162} 1163 1164define i1 @usub_sat_unknown(i32 %a) { 1165; CHECK-LABEL: @usub_sat_unknown( 1166; CHECK-NEXT: entry: 1167; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 100) 1168; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101 1169; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1170; CHECK: exit1: 1171; CHECK-NEXT: ret i1 true 1172; CHECK: exit2: 1173; CHECK-NEXT: ret i1 [[CMP2]] 1174; 1175entry: 1176 %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100) 1177 %cmp1 = icmp ule i32 %val, 4294967195 1178 %cmp2 = icmp ult i32 %val, 4294967195 1179 br i1 undef, label %exit1, label %exit2 1180exit1: 1181 ret i1 %cmp1 1182exit2: 1183 ret i1 %cmp2 1184} 1185 1186define i1 @sadd_sat_unknown(i32 %a) { 1187; CHECK-LABEL: @sadd_sat_unknown( 1188; CHECK-NEXT: entry: 1189; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 100) 1190; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548 1191; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1192; CHECK: exit1: 1193; CHECK-NEXT: ret i1 true 1194; CHECK: exit2: 1195; CHECK-NEXT: ret i1 [[CMP2]] 1196; 1197entry: 1198 %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100) 1199 %cmp1 = icmp sge i32 %val, -2147483548 1200 %cmp2 = icmp sgt i32 %val, -2147483548 1201 br i1 undef, label %exit1, label %exit2 1202exit1: 1203 ret i1 %cmp1 1204exit2: 1205 ret i1 %cmp2 1206} 1207 1208define i1 @ssub_sat_unknown(i32 %a) { 1209; CHECK-LABEL: @ssub_sat_unknown( 1210; CHECK-NEXT: entry: 1211; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 100) 1212; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547 1213; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 1214; CHECK: exit1: 1215; CHECK-NEXT: ret i1 true 1216; CHECK: exit2: 1217; CHECK-NEXT: ret i1 [[CMP2]] 1218; 1219entry: 1220 %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100) 1221 %cmp1 = icmp sle i32 %val, 2147483547 1222 %cmp2 = icmp slt i32 %val, 2147483547 1223 br i1 undef, label %exit1, label %exit2 1224exit1: 1225 ret i1 %cmp1 1226exit2: 1227 ret i1 %cmp2 1228} 1229 1230define void @select_and(i32 %a, i1* %p) { 1231; CHECK-LABEL: @select_and( 1232; CHECK-NEXT: entry: 1233; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10 1234; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10 1235; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false 1236; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1237; CHECK: guard: 1238; CHECK-NEXT: store i1 false, i1* [[P:%.*]], align 1 1239; CHECK-NEXT: store i1 false, i1* [[P]], align 1 1240; CHECK-NEXT: br label [[EXIT]] 1241; CHECK: exit: 1242; CHECK-NEXT: ret void 1243; 1244entry: 1245 %cmp1 = icmp sgt i32 %a, -10 1246 %cmp2 = icmp slt i32 %a, 10 1247 %and = select i1 %cmp1, i1 %cmp2, i1 false 1248 br i1 %and, label %guard, label %exit 1249 1250guard: 1251 %c1 = icmp sgt i32 %a, 20 1252 store i1 %c1, i1* %p 1253 %c2 = icmp slt i32 %a, -20 1254 store i1 %c2, i1* %p 1255 br label %exit 1256 1257exit: 1258 ret void 1259} 1260 1261define void @select_and_wrong_const(i32 %a, i1* %p) { 1262; CHECK-LABEL: @select_and_wrong_const( 1263; CHECK-NEXT: entry: 1264; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10 1265; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10 1266; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true 1267; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1268; CHECK: guard: 1269; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20 1270; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1 1271; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20 1272; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1273; CHECK-NEXT: br label [[EXIT]] 1274; CHECK: exit: 1275; CHECK-NEXT: ret void 1276; 1277entry: 1278 %cmp1 = icmp sgt i32 %a, -10 1279 %cmp2 = icmp slt i32 %a, 10 1280 %and = select i1 %cmp1, i1 %cmp2, i1 true 1281 br i1 %and, label %guard, label %exit 1282 1283guard: 1284 %c1 = icmp sgt i32 %a, 20 1285 store i1 %c1, i1* %p 1286 %c2 = icmp slt i32 %a, -20 1287 store i1 %c2, i1* %p 1288 br label %exit 1289 1290exit: 1291 ret void 1292} 1293 1294define void @select_and_wrong_operand(i32 %a, i1* %p) { 1295; CHECK-LABEL: @select_and_wrong_operand( 1296; CHECK-NEXT: entry: 1297; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10 1298; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10 1299; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]] 1300; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1301; CHECK: guard: 1302; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20 1303; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1 1304; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20 1305; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1306; CHECK-NEXT: br label [[EXIT]] 1307; CHECK: exit: 1308; CHECK-NEXT: ret void 1309; 1310entry: 1311 %cmp1 = icmp sgt i32 %a, -10 1312 %cmp2 = icmp slt i32 %a, 10 1313 %and = select i1 %cmp1, i1 false, i1 %cmp2 1314 br i1 %and, label %guard, label %exit 1315 1316guard: 1317 %c1 = icmp sgt i32 %a, 20 1318 store i1 %c1, i1* %p 1319 %c2 = icmp slt i32 %a, -20 1320 store i1 %c2, i1* %p 1321 br label %exit 1322 1323exit: 1324 ret void 1325} 1326 1327define void @select_or(i32 %a, i1* %p) { 1328; CHECK-LABEL: @select_or( 1329; CHECK-NEXT: entry: 1330; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10 1331; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10 1332; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]] 1333; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1334; CHECK: guard: 1335; CHECK-NEXT: store i1 false, i1* [[P:%.*]], align 1 1336; CHECK-NEXT: store i1 false, i1* [[P]], align 1 1337; CHECK-NEXT: br label [[EXIT]] 1338; CHECK: exit: 1339; CHECK-NEXT: ret void 1340; 1341entry: 1342 %cmp1 = icmp slt i32 %a, -10 1343 %cmp2 = icmp sgt i32 %a, 10 1344 %or = select i1 %cmp1, i1 true, i1 %cmp2 1345 br i1 %or, label %exit, label %guard 1346 1347guard: 1348 %c1 = icmp sgt i32 %a, 20 1349 store i1 %c1, i1* %p 1350 %c2 = icmp slt i32 %a, -20 1351 store i1 %c2, i1* %p 1352 br label %exit 1353 1354exit: 1355 ret void 1356} 1357 1358define void @select_or_wrong_const(i32 %a, i1* %p) { 1359; CHECK-LABEL: @select_or_wrong_const( 1360; CHECK-NEXT: entry: 1361; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10 1362; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10 1363; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]] 1364; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1365; CHECK: guard: 1366; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20 1367; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1 1368; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20 1369; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1370; CHECK-NEXT: br label [[EXIT]] 1371; CHECK: exit: 1372; CHECK-NEXT: ret void 1373; 1374entry: 1375 %cmp1 = icmp slt i32 %a, -10 1376 %cmp2 = icmp sgt i32 %a, 10 1377 %or = select i1 %cmp1, i1 false, i1 %cmp2 1378 br i1 %or, label %exit, label %guard 1379 1380guard: 1381 %c1 = icmp sgt i32 %a, 20 1382 store i1 %c1, i1* %p 1383 %c2 = icmp slt i32 %a, -20 1384 store i1 %c2, i1* %p 1385 br label %exit 1386 1387exit: 1388 ret void 1389} 1390 1391define void @select_or_wrong_operand(i32 %a, i1* %p) { 1392; CHECK-LABEL: @select_or_wrong_operand( 1393; CHECK-NEXT: entry: 1394; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10 1395; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10 1396; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true 1397; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1398; CHECK: guard: 1399; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20 1400; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1 1401; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20 1402; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1403; CHECK-NEXT: br label [[EXIT]] 1404; CHECK: exit: 1405; CHECK-NEXT: ret void 1406; 1407entry: 1408 %cmp1 = icmp slt i32 %a, -10 1409 %cmp2 = icmp sgt i32 %a, 10 1410 %or = select i1 %cmp1, i1 %cmp2, i1 true 1411 br i1 %or, label %exit, label %guard 1412 1413guard: 1414 %c1 = icmp sgt i32 %a, 20 1415 store i1 %c1, i1* %p 1416 %c2 = icmp slt i32 %a, -20 1417 store i1 %c2, i1* %p 1418 br label %exit 1419 1420exit: 1421 ret void 1422} 1423 1424define void @or_union(i32 %a, i1* %p) { 1425; CHECK-LABEL: @or_union( 1426; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10 1427; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 12 1428; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 1429; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1430; CHECK: guard: 1431; CHECK-NEXT: store i1 false, i1* [[P:%.*]], align 1 1432; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 10 1433; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1434; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 11 1435; CHECK-NEXT: store i1 [[C3]], i1* [[P]], align 1 1436; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 12 1437; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 1438; CHECK-NEXT: store i1 false, i1* [[P]], align 1 1439; CHECK-NEXT: br label [[EXIT]] 1440; CHECK: exit: 1441; CHECK-NEXT: ret void 1442; 1443 %cmp1 = icmp eq i32 %a, 10 1444 %cmp2 = icmp eq i32 %a, 12 1445 %or = or i1 %cmp1, %cmp2 1446 br i1 %or, label %guard, label %exit 1447 1448guard: 1449 %c1 = icmp eq i32 %a, 9 1450 store i1 %c1, i1* %p 1451 %c2 = icmp eq i32 %a, 10 1452 store i1 %c2, i1* %p 1453 %c3 = icmp eq i32 %a, 11 1454 store i1 %c3, i1* %p 1455 %c4 = icmp eq i32 %a, 12 1456 store i1 %c4, i1* %p 1457 %c5 = icmp eq i32 %a, 13 1458 store i1 %c5, i1* %p 1459 br label %exit 1460 1461exit: 1462 ret void 1463} 1464 1465define i1 @or_union_unknown_cond(i32 %a, i1 %c) { 1466; CHECK-LABEL: @or_union_unknown_cond( 1467; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10 1468; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[C:%.*]] 1469; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]] 1470; CHECK: guard: 1471; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 10 1472; CHECK-NEXT: ret i1 [[CMP2]] 1473; CHECK: exit: 1474; CHECK-NEXT: ret i1 false 1475; 1476 %cmp1 = icmp eq i32 %a, 10 1477 %or = or i1 %cmp1, %c 1478 br i1 %or, label %guard, label %exit 1479 1480guard: 1481 %cmp2 = icmp eq i32 %a, 10 1482 ret i1 %cmp2 1483 1484exit: 1485 ret i1 false 1486} 1487 1488define void @and_union(i32 %a, i1* %p) { 1489; CHECK-LABEL: @and_union( 1490; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10 1491; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], 12 1492; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 1493; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1494; CHECK: guard: 1495; CHECK-NEXT: store i1 false, i1* [[P:%.*]], align 1 1496; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 10 1497; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 1498; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 11 1499; CHECK-NEXT: store i1 [[C3]], i1* [[P]], align 1 1500; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 12 1501; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 1502; CHECK-NEXT: store i1 false, i1* [[P]], align 1 1503; CHECK-NEXT: br label [[EXIT]] 1504; CHECK: exit: 1505; CHECK-NEXT: ret void 1506; 1507 %cmp1 = icmp ne i32 %a, 10 1508 %cmp2 = icmp ne i32 %a, 12 1509 %and = and i1 %cmp1, %cmp2 1510 br i1 %and, label %exit, label %guard 1511 1512guard: 1513 %c1 = icmp eq i32 %a, 9 1514 store i1 %c1, i1* %p 1515 %c2 = icmp eq i32 %a, 10 1516 store i1 %c2, i1* %p 1517 %c3 = icmp eq i32 %a, 11 1518 store i1 %c3, i1* %p 1519 %c4 = icmp eq i32 %a, 12 1520 store i1 %c4, i1* %p 1521 %c5 = icmp eq i32 %a, 13 1522 store i1 %c5, i1* %p 1523 br label %exit 1524 1525exit: 1526 ret void 1527} 1528 1529define i1 @and_union_unknown_cond(i32 %a, i1 %c) { 1530; CHECK-LABEL: @and_union_unknown_cond( 1531; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10 1532; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[C:%.*]] 1533; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]] 1534; CHECK: guard: 1535; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 10 1536; CHECK-NEXT: ret i1 [[CMP2]] 1537; CHECK: exit: 1538; CHECK-NEXT: ret i1 false 1539; 1540 %cmp1 = icmp ne i32 %a, 10 1541 %and = and i1 %cmp1, %c 1542 br i1 %and, label %exit, label %guard 1543 1544guard: 1545 %cmp2 = icmp eq i32 %a, 10 1546 ret i1 %cmp2 1547 1548exit: 1549 ret i1 false 1550} 1551 1552 1553declare i32 @llvm.uadd.sat.i32(i32, i32) 1554declare i32 @llvm.usub.sat.i32(i32, i32) 1555declare i32 @llvm.sadd.sat.i32(i32, i32) 1556declare i32 @llvm.ssub.sat.i32(i32, i32) 1557declare void @llvm.assume(i1) 1558