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 i1 @arg_attribute(i8* nonnull %a) { 282; CHECK-LABEL: @arg_attribute( 283; CHECK-NEXT: ret i1 false 284; 285 %cmp = icmp eq i8* %a, null 286 ret i1 %cmp 287} 288 289declare nonnull i8* @return_nonnull() 290define i1 @call_attribute() { 291; CHECK-LABEL: @call_attribute( 292; CHECK-NEXT: [[A:%.*]] = call i8* @return_nonnull() 293; CHECK-NEXT: ret i1 false 294; 295 %a = call i8* @return_nonnull() 296 %cmp = icmp eq i8* %a, null 297 ret i1 %cmp 298} 299 300define i1 @umin(i32 %a, i32 %b) { 301; CHECK-LABEL: @umin( 302; CHECK-NEXT: entry: 303; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5 304; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 305; CHECK: a_guard: 306; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20 307; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 308; CHECK: b_guard: 309; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]] 310; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 311; CHECK-NEXT: ret i1 false 312; CHECK: out: 313; CHECK-NEXT: ret i1 false 314; 315entry: 316 %cmp = icmp ult i32 %a, 5 317 br i1 %cmp, label %a_guard, label %out 318 319a_guard: 320 %cmp2 = icmp ult i32 %b, 20 321 br i1 %cmp2, label %b_guard, label %out 322 323b_guard: 324 %sel_cmp = icmp ult i32 %a, %b 325 %min = select i1 %sel_cmp, i32 %a, i32 %b 326 %res = icmp eq i32 %min, 7 327 ret i1 %res 328out: 329 ret i1 false 330} 331 332define i1 @smin(i32 %a, i32 %b) { 333; CHECK-LABEL: @smin( 334; CHECK-NEXT: entry: 335; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5 336; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 337; CHECK: a_guard: 338; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20 339; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 340; CHECK: b_guard: 341; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sle i32 [[A]], [[B]] 342; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 343; CHECK-NEXT: ret i1 false 344; CHECK: out: 345; CHECK-NEXT: ret i1 false 346; 347entry: 348 %cmp = icmp ult i32 %a, 5 349 br i1 %cmp, label %a_guard, label %out 350 351a_guard: 352 %cmp2 = icmp ult i32 %b, 20 353 br i1 %cmp2, label %b_guard, label %out 354 355b_guard: 356 %sel_cmp = icmp sle i32 %a, %b 357 %min = select i1 %sel_cmp, i32 %a, i32 %b 358 %res = icmp eq i32 %min, 7 359 ret i1 %res 360out: 361 ret i1 false 362} 363 364define i1 @smax(i32 %a, i32 %b) { 365; CHECK-LABEL: @smax( 366; CHECK-NEXT: entry: 367; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 368; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 369; CHECK: a_guard: 370; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20 371; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 372; CHECK: b_guard: 373; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], [[B]] 374; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 375; CHECK-NEXT: ret i1 false 376; CHECK: out: 377; CHECK-NEXT: ret i1 false 378; 379entry: 380 %cmp = icmp sgt i32 %a, 5 381 br i1 %cmp, label %a_guard, label %out 382 383a_guard: 384 %cmp2 = icmp sgt i32 %b, 20 385 br i1 %cmp2, label %b_guard, label %out 386 387b_guard: 388 %sel_cmp = icmp sge i32 %a, %b 389 %max = select i1 %sel_cmp, i32 %a, i32 %b 390 %res = icmp eq i32 %max, 7 391 ret i1 %res 392out: 393 ret i1 false 394} 395 396define i1 @umax(i32 %a, i32 %b) { 397; CHECK-LABEL: @umax( 398; CHECK-NEXT: entry: 399; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 400; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 401; CHECK: a_guard: 402; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20 403; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]] 404; CHECK: b_guard: 405; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]] 406; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] 407; CHECK-NEXT: ret i1 false 408; CHECK: out: 409; CHECK-NEXT: ret i1 false 410; 411entry: 412 %cmp = icmp sgt i32 %a, 5 413 br i1 %cmp, label %a_guard, label %out 414 415a_guard: 416 %cmp2 = icmp sgt i32 %b, 20 417 br i1 %cmp2, label %b_guard, label %out 418 419b_guard: 420 %sel_cmp = icmp uge i32 %a, %b 421 %max = select i1 %sel_cmp, i32 %a, i32 %b 422 %res = icmp eq i32 %max, 7 423 ret i1 %res 424out: 425 ret i1 false 426} 427 428define i1 @clamp_low1(i32 %a) { 429; CHECK-LABEL: @clamp_low1( 430; CHECK-NEXT: entry: 431; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 432; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 433; CHECK: a_guard: 434; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5 435; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 436; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[A]] 437; CHECK-NEXT: ret i1 false 438; CHECK: out: 439; CHECK-NEXT: ret i1 false 440; 441entry: 442 %cmp = icmp sge i32 %a, 5 443 br i1 %cmp, label %a_guard, label %out 444 445a_guard: 446 %sel_cmp = icmp eq i32 %a, 5 447 %add = add i32 %a, -1 448 %sel = select i1 %sel_cmp, i32 5, i32 %a 449 %res = icmp eq i32 %sel, 4 450 ret i1 %res 451out: 452 ret i1 false 453} 454 455define i1 @clamp_low2(i32 %a) { 456; CHECK-LABEL: @clamp_low2( 457; CHECK-NEXT: entry: 458; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5 459; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 460; CHECK: a_guard: 461; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 462; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 463; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5 464; CHECK-NEXT: ret i1 false 465; CHECK: out: 466; CHECK-NEXT: ret i1 false 467; 468entry: 469 %cmp = icmp sge i32 %a, 5 470 br i1 %cmp, label %a_guard, label %out 471 472a_guard: 473 %sel_cmp = icmp ne i32 %a, 5 474 %add = add i32 %a, -1 475 %sel = select i1 %sel_cmp, i32 %a, i32 5 476 %res = icmp eq i32 %sel, 4 477 ret i1 %res 478out: 479 ret i1 false 480} 481 482define i1 @clamp_high1(i32 %a) { 483; CHECK-LABEL: @clamp_high1( 484; CHECK-NEXT: entry: 485; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 486; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 487; CHECK: a_guard: 488; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5 489; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 490; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[A]] 491; CHECK-NEXT: ret i1 false 492; CHECK: out: 493; CHECK-NEXT: ret i1 false 494; 495entry: 496 %cmp = icmp sle i32 %a, 5 497 br i1 %cmp, label %a_guard, label %out 498 499a_guard: 500 %sel_cmp = icmp eq i32 %a, 5 501 %add = add i32 %a, 1 502 %sel = select i1 %sel_cmp, i32 5, i32 %a 503 %res = icmp eq i32 %sel, 6 504 ret i1 %res 505out: 506 ret i1 false 507} 508 509define i1 @clamp_high2(i32 %a) { 510; CHECK-LABEL: @clamp_high2( 511; CHECK-NEXT: entry: 512; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 513; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 514; CHECK: a_guard: 515; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 516; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 517; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5 518; CHECK-NEXT: ret i1 false 519; CHECK: out: 520; CHECK-NEXT: ret i1 false 521; 522entry: 523 %cmp = icmp sle i32 %a, 5 524 br i1 %cmp, label %a_guard, label %out 525 526a_guard: 527 %sel_cmp = icmp ne i32 %a, 5 528 %add = add i32 %a, 1 529 %sel = select i1 %sel_cmp, i32 %a, i32 5 530 %res = icmp eq i32 %sel, 6 531 ret i1 %res 532out: 533 ret i1 false 534} 535 536; Just showing arbitrary constants work, not really a clamp 537define i1 @clamp_high3(i32 %a) { 538; CHECK-LABEL: @clamp_high3( 539; CHECK-NEXT: entry: 540; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5 541; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]] 542; CHECK: a_guard: 543; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 544; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 100 545; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5 546; CHECK-NEXT: ret i1 false 547; CHECK: out: 548; CHECK-NEXT: ret i1 false 549; 550entry: 551 %cmp = icmp sle i32 %a, 5 552 br i1 %cmp, label %a_guard, label %out 553 554a_guard: 555 %sel_cmp = icmp ne i32 %a, 5 556 %add = add i32 %a, 100 557 %sel = select i1 %sel_cmp, i32 %a, i32 5 558 %res = icmp eq i32 %sel, 105 559 ret i1 %res 560out: 561 ret i1 false 562} 563 564define void @abs1(i32 %a, i1* %p) { 565; CHECK-LABEL: @abs1( 566; CHECK-NEXT: entry: 567; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 568; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 569; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 570; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 571; CHECK: guard: 572; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 573; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0 574; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]] 575; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 576; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[ABS]], 19 577; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 578; CHECK-NEXT: store i1 true, i1* [[P]], align 1 579; CHECK-NEXT: [[C4:%.*]] = icmp sge i32 [[ABS]], 1 580; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 581; CHECK-NEXT: br label [[EXIT]] 582; CHECK: exit: 583; CHECK-NEXT: ret void 584; 585entry: 586 %cmp1 = icmp slt i32 %a, 10 587 %cmp2 = icmp sgt i32 %a, -20 588 %and = and i1 %cmp1, %cmp2 589 br i1 %and, label %guard, label %exit 590 591guard: 592 %sub = sub i32 0, %a 593 %cmp = icmp slt i32 %a, 0 594 %abs = select i1 %cmp, i32 %sub, i32 %a 595 %c1 = icmp slt i32 %abs, 20 596 store i1 %c1, i1* %p 597 %c2 = icmp slt i32 %abs, 19 598 store i1 %c2, i1* %p 599 %c3 = icmp sge i32 %abs, 0 600 store i1 %c3, i1* %p 601 %c4 = icmp sge i32 %abs, 1 602 store i1 %c4, i1* %p 603 br label %exit 604 605exit: 606 ret void 607} 608 609define void @abs2(i32 %a, i1* %p) { 610; CHECK-LABEL: @abs2( 611; CHECK-NEXT: entry: 612; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 613; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 614; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 615; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 616; CHECK: guard: 617; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 618; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 0 619; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]] 620; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 621; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[ABS]], 19 622; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 623; CHECK-NEXT: store i1 true, i1* [[P]], align 1 624; CHECK-NEXT: [[C4:%.*]] = icmp sge i32 [[ABS]], 1 625; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 626; CHECK-NEXT: br label [[EXIT]] 627; CHECK: exit: 628; CHECK-NEXT: ret void 629; 630entry: 631 %cmp1 = icmp slt i32 %a, 10 632 %cmp2 = icmp sgt i32 %a, -20 633 %and = and i1 %cmp1, %cmp2 634 br i1 %and, label %guard, label %exit 635 636guard: 637 %sub = sub i32 0, %a 638 %cmp = icmp sge i32 %a, 0 639 %abs = select i1 %cmp, i32 %a, i32 %sub 640 %c1 = icmp slt i32 %abs, 20 641 store i1 %c1, i1* %p 642 %c2 = icmp slt i32 %abs, 19 643 store i1 %c2, i1* %p 644 %c3 = icmp sge i32 %abs, 0 645 store i1 %c3, i1* %p 646 %c4 = icmp sge i32 %abs, 1 647 store i1 %c4, i1* %p 648 br label %exit 649 650exit: 651 ret void 652} 653 654define void @nabs1(i32 %a, i1* %p) { 655; CHECK-LABEL: @nabs1( 656; CHECK-NEXT: entry: 657; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 658; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 659; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 660; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 661; CHECK: guard: 662; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 663; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0 664; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]] 665; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 666; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19 667; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 668; CHECK-NEXT: store i1 true, i1* [[P]], align 1 669; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1 670; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 671; CHECK-NEXT: br label [[EXIT]] 672; CHECK: exit: 673; CHECK-NEXT: ret void 674; 675entry: 676 %cmp1 = icmp slt i32 %a, 10 677 %cmp2 = icmp sgt i32 %a, -20 678 %and = and i1 %cmp1, %cmp2 679 br i1 %and, label %guard, label %exit 680 681guard: 682 %sub = sub i32 0, %a 683 %cmp = icmp sgt i32 %a, 0 684 %nabs = select i1 %cmp, i32 %sub, i32 %a 685 %c1 = icmp sgt i32 %nabs, -20 686 store i1 %c1, i1* %p 687 %c2 = icmp sgt i32 %nabs, -19 688 store i1 %c2, i1* %p 689 %c3 = icmp sle i32 %nabs, 0 690 store i1 %c3, i1* %p 691 %c4 = icmp sle i32 %nabs, -1 692 store i1 %c4, i1* %p 693 br label %exit 694 695exit: 696 ret void 697} 698 699define void @nabs2(i32 %a, i1* %p) { 700; CHECK-LABEL: @nabs2( 701; CHECK-NEXT: entry: 702; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10 703; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20 704; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 705; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]] 706; CHECK: guard: 707; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 708; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0 709; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]] 710; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1 711; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19 712; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1 713; CHECK-NEXT: store i1 true, i1* [[P]], align 1 714; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1 715; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1 716; CHECK-NEXT: br label [[EXIT]] 717; CHECK: exit: 718; CHECK-NEXT: ret void 719; 720entry: 721 %cmp1 = icmp slt i32 %a, 10 722 %cmp2 = icmp sgt i32 %a, -20 723 %and = and i1 %cmp1, %cmp2 724 br i1 %and, label %guard, label %exit 725 726guard: 727 %sub = sub i32 0, %a 728 %cmp = icmp slt i32 %a, 0 729 %nabs = select i1 %cmp, i32 %a, i32 %sub 730 %c1 = icmp sgt i32 %nabs, -20 731 store i1 %c1, i1* %p 732 %c2 = icmp sgt i32 %nabs, -19 733 store i1 %c2, i1* %p 734 %c3 = icmp sle i32 %nabs, 0 735 store i1 %c3, i1* %p 736 %c4 = icmp sle i32 %nabs, -1 737 store i1 %c4, i1* %p 738 br label %exit 739 740exit: 741 ret void 742} 743 744define i1 @zext_unknown(i8 %a) { 745; CHECK-LABEL: @zext_unknown( 746; CHECK-NEXT: entry: 747; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A:%.*]] to i32 748; CHECK-NEXT: ret i1 true 749; 750entry: 751 %a32 = zext i8 %a to i32 752 %cmp = icmp sle i32 %a32, 256 753 ret i1 %cmp 754} 755 756define i1 @trunc_unknown(i32 %a) { 757; CHECK-LABEL: @trunc_unknown( 758; CHECK-NEXT: entry: 759; CHECK-NEXT: [[A8:%.*]] = trunc i32 [[A:%.*]] to i8 760; CHECK-NEXT: [[A32:%.*]] = sext i8 [[A8]] to i32 761; CHECK-NEXT: ret i1 true 762; 763entry: 764 %a8 = trunc i32 %a to i8 765 %a32 = sext i8 %a8 to i32 766 %cmp = icmp sle i32 %a32, 128 767 ret i1 %cmp 768} 769 770; TODO: missed optimization 771; Make sure we exercise non-integer inputs to unary operators (i.e. crash check). 772define i1 @bitcast_unknown(float %a) { 773; CHECK-LABEL: @bitcast_unknown( 774; CHECK-NEXT: entry: 775; CHECK-NEXT: [[A32:%.*]] = bitcast float [[A:%.*]] to i32 776; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A32]], 128 777; CHECK-NEXT: ret i1 [[CMP]] 778; 779entry: 780 %a32 = bitcast float %a to i32 781 %cmp = icmp sle i32 %a32, 128 782 ret i1 %cmp 783} 784 785define i1 @bitcast_unknown2(i8* %p) { 786; CHECK-LABEL: @bitcast_unknown2( 787; CHECK-NEXT: entry: 788; CHECK-NEXT: [[P64:%.*]] = ptrtoint i8* [[P:%.*]] to i64 789; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[P64]], 128 790; CHECK-NEXT: ret i1 [[CMP]] 791; 792entry: 793 %p64 = ptrtoint i8* %p to i64 794 %cmp = icmp sle i64 %p64, 128 795 ret i1 %cmp 796} 797 798 799define i1 @and_unknown(i32 %a) { 800; CHECK-LABEL: @and_unknown( 801; CHECK-NEXT: entry: 802; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 128 803; CHECK-NEXT: ret i1 true 804; 805entry: 806 %and = and i32 %a, 128 807 %cmp = icmp sle i32 %and, 128 808 ret i1 %cmp 809} 810 811define i1 @lshr_unknown(i32 %a) { 812; CHECK-LABEL: @lshr_unknown( 813; CHECK-NEXT: entry: 814; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[A:%.*]], 30 815; CHECK-NEXT: ret i1 true 816; 817entry: 818 %and = lshr i32 %a, 30 819 %cmp = icmp sle i32 %and, 128 820 ret i1 %cmp 821} 822 823define i1 @urem_unknown(i32 %a) { 824; CHECK-LABEL: @urem_unknown( 825; CHECK-NEXT: entry: 826; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[A:%.*]], 30 827; CHECK-NEXT: ret i1 true 828; 829entry: 830 %urem = urem i32 %a, 30 831 %cmp = icmp ult i32 %urem, 30 832 ret i1 %cmp 833} 834 835define i1 @srem_unknown(i32 %a) { 836; CHECK-LABEL: @srem_unknown( 837; CHECK-NEXT: entry: 838; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[A:%.*]], 30 839; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 840; CHECK: exit1: 841; CHECK-NEXT: ret i1 true 842; CHECK: exit2: 843; CHECK-NEXT: ret i1 true 844; 845entry: 846 %srem = srem i32 %a, 30 847 %cmp1 = icmp slt i32 %srem, 30 848 %cmp2 = icmp sgt i32 %srem, -30 849 br i1 undef, label %exit1, label %exit2 850exit1: 851 ret i1 %cmp1 852exit2: 853 ret i1 %cmp2 854} 855 856define i1 @sdiv_unknown(i32 %a) { 857; CHECK-LABEL: @sdiv_unknown( 858; CHECK-NEXT: entry: 859; CHECK-NEXT: [[SREM:%.*]] = sdiv i32 [[A:%.*]], 123 860; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 861; CHECK: exit1: 862; CHECK-NEXT: ret i1 true 863; CHECK: exit2: 864; CHECK-NEXT: ret i1 true 865; 866entry: 867 %srem = sdiv i32 %a, 123 868 %cmp1 = icmp slt i32 %srem, 17459217 869 %cmp2 = icmp sgt i32 %srem, -17459217 870 br i1 undef, label %exit1, label %exit2 871exit1: 872 ret i1 %cmp1 873exit2: 874 ret i1 %cmp2 875} 876 877define i1 @uadd_sat_unknown(i32 %a) { 878; CHECK-LABEL: @uadd_sat_unknown( 879; CHECK-NEXT: entry: 880; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A:%.*]], i32 100) 881; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100 882; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 883; CHECK: exit1: 884; CHECK-NEXT: ret i1 true 885; CHECK: exit2: 886; CHECK-NEXT: ret i1 [[CMP2]] 887; 888entry: 889 %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100) 890 %cmp1 = icmp uge i32 %val, 100 891 %cmp2 = icmp ugt i32 %val, 100 892 br i1 undef, label %exit1, label %exit2 893exit1: 894 ret i1 %cmp1 895exit2: 896 ret i1 %cmp2 897} 898 899define i1 @usub_sat_unknown(i32 %a) { 900; CHECK-LABEL: @usub_sat_unknown( 901; CHECK-NEXT: entry: 902; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 100) 903; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101 904; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 905; CHECK: exit1: 906; CHECK-NEXT: ret i1 true 907; CHECK: exit2: 908; CHECK-NEXT: ret i1 [[CMP2]] 909; 910entry: 911 %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100) 912 %cmp1 = icmp ule i32 %val, 4294967195 913 %cmp2 = icmp ult i32 %val, 4294967195 914 br i1 undef, label %exit1, label %exit2 915exit1: 916 ret i1 %cmp1 917exit2: 918 ret i1 %cmp2 919} 920 921define i1 @sadd_sat_unknown(i32 %a) { 922; CHECK-LABEL: @sadd_sat_unknown( 923; CHECK-NEXT: entry: 924; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 100) 925; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548 926; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 927; CHECK: exit1: 928; CHECK-NEXT: ret i1 true 929; CHECK: exit2: 930; CHECK-NEXT: ret i1 [[CMP2]] 931; 932entry: 933 %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100) 934 %cmp1 = icmp sge i32 %val, -2147483548 935 %cmp2 = icmp sgt i32 %val, -2147483548 936 br i1 undef, label %exit1, label %exit2 937exit1: 938 ret i1 %cmp1 939exit2: 940 ret i1 %cmp2 941} 942 943define i1 @ssub_sat_unknown(i32 %a) { 944; CHECK-LABEL: @ssub_sat_unknown( 945; CHECK-NEXT: entry: 946; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 100) 947; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547 948; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] 949; CHECK: exit1: 950; CHECK-NEXT: ret i1 true 951; CHECK: exit2: 952; CHECK-NEXT: ret i1 [[CMP2]] 953; 954entry: 955 %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100) 956 %cmp1 = icmp sle i32 %val, 2147483547 957 %cmp2 = icmp slt i32 %val, 2147483547 958 br i1 undef, label %exit1, label %exit2 959exit1: 960 ret i1 %cmp1 961exit2: 962 ret i1 %cmp2 963} 964 965declare i32 @llvm.uadd.sat.i32(i32, i32) 966declare i32 @llvm.usub.sat.i32(i32, i32) 967declare i32 @llvm.sadd.sat.i32(i32, i32) 968declare i32 @llvm.ssub.sat.i32(i32, i32) 969