1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -correlated-propagation -S %s | FileCheck %s 3; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s 4 5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 6target triple = "x86_64-apple-macosx10.10.0" 7 8declare void @check1(i1) #1 9declare void @check2(i1) #1 10declare void @llvm.assume(i1) 11 12; Make sure we propagate the value of %tmp35 to the true/false cases 13 14define void @test1(i64 %tmp35) { 15; CHECK-LABEL: @test1( 16; CHECK-NEXT: bb: 17; CHECK-NEXT: [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0 18; CHECK-NEXT: br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]] 19; CHECK: bb_true: 20; CHECK-NEXT: tail call void @check1(i1 false) #[[ATTR1:[0-9]+]] 21; CHECK-NEXT: unreachable 22; CHECK: bb_false: 23; CHECK-NEXT: tail call void @check2(i1 true) #[[ATTR1]] 24; CHECK-NEXT: unreachable 25; 26bb: 27 %tmp36 = icmp sgt i64 %tmp35, 0 28 br i1 %tmp36, label %bb_true, label %bb_false 29 30bb_true: 31 %tmp47 = icmp slt i64 %tmp35, 0 32 tail call void @check1(i1 %tmp47) #4 33 unreachable 34 35bb_false: 36 %tmp48 = icmp sle i64 %tmp35, 0 37 tail call void @check2(i1 %tmp48) #4 38 unreachable 39} 40 41; This is the same as test1 but with a diamond to ensure we 42; get %tmp36 from both true and false BBs. 43 44define void @test2(i64 %tmp35, i1 %inner_cmp) { 45; CHECK-LABEL: @test2( 46; CHECK-NEXT: bb: 47; CHECK-NEXT: [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0 48; CHECK-NEXT: br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]] 49; CHECK: bb_true: 50; CHECK-NEXT: br i1 [[INNER_CMP:%.*]], label [[INNER_TRUE:%.*]], label [[INNER_FALSE:%.*]] 51; CHECK: inner_true: 52; CHECK-NEXT: br label [[MERGE:%.*]] 53; CHECK: inner_false: 54; CHECK-NEXT: br label [[MERGE]] 55; CHECK: merge: 56; CHECK-NEXT: tail call void @check1(i1 false) 57; CHECK-NEXT: unreachable 58; CHECK: bb_false: 59; CHECK-NEXT: tail call void @check2(i1 true) #[[ATTR1]] 60; CHECK-NEXT: unreachable 61; 62bb: 63 %tmp36 = icmp sgt i64 %tmp35, 0 64 br i1 %tmp36, label %bb_true, label %bb_false 65 66bb_true: 67 br i1 %inner_cmp, label %inner_true, label %inner_false 68 69inner_true: 70 br label %merge 71 72inner_false: 73 br label %merge 74 75merge: 76 %tmp47 = icmp slt i64 %tmp35, 0 77 tail call void @check1(i1 %tmp47) #0 78 unreachable 79 80bb_false: 81 %tmp48 = icmp sle i64 %tmp35, 0 82 tail call void @check2(i1 %tmp48) #4 83 unreachable 84} 85 86; Make sure binary operator transfer functions are run when RHS is non-constant 87 88define i1 @test3(i32 %x, i32 %y) #0 { 89; CHECK-LABEL: @test3( 90; CHECK-NEXT: entry: 91; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10 92; CHECK-NEXT: br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]] 93; CHECK: cont1: 94; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10 95; CHECK-NEXT: br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]] 96; CHECK: cont2: 97; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]] 98; CHECK-NEXT: br label [[OUT]] 99; CHECK: out: 100; CHECK-NEXT: ret i1 true 101; 102entry: 103 %cmp1 = icmp ult i32 %x, 10 104 br i1 %cmp1, label %cont1, label %out 105 106cont1: 107 %cmp2 = icmp ult i32 %y, 10 108 br i1 %cmp2, label %cont2, label %out 109 110cont2: 111 %add = add i32 %x, %y 112 %cmp3 = icmp ult i32 %add, 25 113 br label %out 114 115out: 116 %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ] 117 ret i1 %ret 118} 119 120; Same as previous but make sure nobody gets over-zealous 121 122define i1 @test4(i32 %x, i32 %y) #0 { 123; CHECK-LABEL: @test4( 124; CHECK-NEXT: entry: 125; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10 126; CHECK-NEXT: br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]] 127; CHECK: cont1: 128; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10 129; CHECK-NEXT: br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]] 130; CHECK: cont2: 131; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]] 132; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[ADD]], 15 133; CHECK-NEXT: br label [[OUT]] 134; CHECK: out: 135; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ] 136; CHECK-NEXT: ret i1 [[RET]] 137; 138entry: 139 %cmp1 = icmp ult i32 %x, 10 140 br i1 %cmp1, label %cont1, label %out 141 142cont1: 143 %cmp2 = icmp ult i32 %y, 10 144 br i1 %cmp2, label %cont2, label %out 145 146cont2: 147 %add = add i32 %x, %y 148 %cmp3 = icmp ult i32 %add, 15 149 br label %out 150 151out: 152 %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ] 153 ret i1 %ret 154} 155 156; Make sure binary operator transfer functions are run when RHS is non-constant 157 158define i1 @test5(i32 %x, i32 %y) #0 { 159; CHECK-LABEL: @test5( 160; CHECK-NEXT: entry: 161; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5 162; CHECK-NEXT: br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]] 163; CHECK: cont1: 164; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 5 165; CHECK-NEXT: br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]] 166; CHECK: cont2: 167; CHECK-NEXT: [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]] 168; CHECK-NEXT: br label [[OUT]] 169; CHECK: out: 170; CHECK-NEXT: ret i1 true 171; 172entry: 173 %cmp1 = icmp ult i32 %x, 5 174 br i1 %cmp1, label %cont1, label %out 175 176cont1: 177 %cmp2 = icmp ult i32 %y, 5 178 br i1 %cmp2, label %cont2, label %out 179 180cont2: 181 %shifted = shl i32 %x, %y 182 %cmp3 = icmp ult i32 %shifted, 65536 183 br label %out 184 185out: 186 %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ] 187 ret i1 %ret 188} 189 190; Same as previous but make sure nobody gets over-zealous 191 192define i1 @test6(i32 %x, i32 %y) #0 { 193; CHECK-LABEL: @test6( 194; CHECK-NEXT: entry: 195; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5 196; CHECK-NEXT: br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]] 197; CHECK: cont1: 198; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 15 199; CHECK-NEXT: br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]] 200; CHECK: cont2: 201; CHECK-NEXT: [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]] 202; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[SHIFTED]], 65536 203; CHECK-NEXT: br label [[OUT]] 204; CHECK: out: 205; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ] 206; CHECK-NEXT: ret i1 [[RET]] 207; 208entry: 209 %cmp1 = icmp ult i32 %x, 5 210 br i1 %cmp1, label %cont1, label %out 211 212cont1: 213 %cmp2 = icmp ult i32 %y, 15 214 br i1 %cmp2, label %cont2, label %out 215 216cont2: 217 %shifted = shl i32 %x, %y 218 %cmp3 = icmp ult i32 %shifted, 65536 219 br label %out 220 221out: 222 %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ] 223 ret i1 %ret 224} 225 226define i1 @test7(i32 %a, i32 %b) { 227; CHECK-LABEL: @test7( 228; CHECK-NEXT: begin: 229; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0 230; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0 231; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]] 232; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]] 233; CHECK: bb: 234; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], [[B]] 235; CHECK-NEXT: [[RES:%.*]] = icmp sge i32 [[ADD]], 0 236; CHECK-NEXT: br label [[EXIT]] 237; CHECK: exit: 238; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ] 239; CHECK-NEXT: ret i1 [[IV]] 240; 241begin: 242 %cmp0 = icmp sge i32 %a, 0 243 %cmp1 = icmp sge i32 %b, 0 244 %br = and i1 %cmp0, %cmp1 245 br i1 %br, label %bb, label %exit 246 247bb: 248 %add = add i32 %a, %b 249 %res = icmp sge i32 %add, 0 250 br label %exit 251 252exit: 253 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 254 ret i1 %iv 255} 256 257define i1 @test8(i32 %a, i32 %b) { 258; CHECK-LABEL: @test8( 259; CHECK-NEXT: begin: 260; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0 261; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0 262; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]] 263; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]] 264; CHECK: bb: 265; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[A]], [[B]] 266; CHECK-NEXT: br label [[EXIT]] 267; CHECK: exit: 268; CHECK-NEXT: ret i1 true 269; 270begin: 271 %cmp0 = icmp sge i32 %a, 0 272 %cmp1 = icmp sge i32 %b, 0 273 %br = and i1 %cmp0, %cmp1 274 br i1 %br, label %bb, label %exit 275 276bb: 277 %add = add nsw i32 %a, %b 278 %res = icmp sge i32 %add, 0 279 br label %exit 280 281exit: 282 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 283 ret i1 %iv 284} 285 286define i1 @test10(i32 %a, i32 %b) { 287; CHECK-LABEL: @test10( 288; CHECK-NEXT: begin: 289; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256 290; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 291; CHECK: bb: 292; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B:%.*]] 293; CHECK-NEXT: [[RES:%.*]] = icmp uge i32 [[ADD]], -256 294; CHECK-NEXT: br label [[EXIT]] 295; CHECK: exit: 296; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ] 297; CHECK-NEXT: ret i1 [[IV]] 298; 299begin: 300 %cmp = icmp uge i32 %a, 4294967040 301 br i1 %cmp, label %bb, label %exit 302 303bb: 304 %add = add i32 %a, %b 305 %res = icmp uge i32 %add, 4294967040 306 br label %exit 307 308exit: 309 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 310 ret i1 %iv 311} 312 313define i1 @test11(i32 %a, i32 %b) { 314; CHECK-LABEL: @test11( 315; CHECK-NEXT: begin: 316; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256 317; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 318; CHECK: bb: 319; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], [[B:%.*]] 320; CHECK-NEXT: br label [[EXIT]] 321; CHECK: exit: 322; CHECK-NEXT: ret i1 true 323; 324begin: 325 %cmp = icmp uge i32 %a, 4294967040 326 br i1 %cmp, label %bb, label %exit 327 328bb: 329 %add = add nuw i32 %a, %b 330 %res = icmp uge i32 %add, 4294967040 331 br label %exit 332 333exit: 334 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 335 ret i1 %iv 336} 337 338define i1 @test12(i32 %x) { 339; CHECK-LABEL: @test12( 340; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X:%.*]] to i64 341; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i64 [[ZEXT]], 7 342; CHECK-NEXT: [[SHR:%.*]] = lshr i64 [[MUL]], 32 343; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[SHR]] to i32 344; CHECK-NEXT: ret i1 true 345; 346 %zext = zext i32 %x to i64 347 %mul = mul nuw i64 %zext, 7 348 %shr = lshr i64 %mul, 32 349 %trunc = trunc i64 %shr to i32 350 %cmp = icmp ult i32 %trunc, 7 351 ret i1 %cmp 352} 353 354define i1 @test13(i8 %x, i64* %p) { 355; CHECK-LABEL: @test13( 356; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i64 357; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[ZEXT]], 128 358; CHECK-NEXT: store i64 [[ADD]], i64* [[P:%.*]], align 8 359; CHECK-NEXT: ret i1 true 360; 361 %zext = zext i8 %x to i64 362 %add = add nuw nsw i64 %zext, 128 363 %cmp = icmp ult i64 %add, 384 364 ; Without this extra use, InstSimplify could handle this 365 store i64 %add, i64* %p 366 ret i1 %cmp 367} 368 369define i1 @test14(i32 %a, i32 %b) { 370; CHECK-LABEL: @test14( 371; CHECK-NEXT: begin: 372; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0 373; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0 374; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]] 375; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]] 376; CHECK: bb: 377; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], [[B]] 378; CHECK-NEXT: [[RES:%.*]] = icmp sge i32 [[SUB]], 0 379; CHECK-NEXT: br label [[EXIT]] 380; CHECK: exit: 381; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ] 382; CHECK-NEXT: ret i1 [[IV]] 383; 384begin: 385 %cmp0 = icmp sge i32 %a, 0 386 %cmp1 = icmp sge i32 %b, 0 387 %br = and i1 %cmp0, %cmp1 388 br i1 %br, label %bb, label %exit 389 390bb: 391 %sub = sub i32 %a, %b 392 %res = icmp sge i32 %sub, 0 393 br label %exit 394 395exit: 396 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 397 ret i1 %iv 398} 399 400define i1 @test15(i32 %a, i32 %b) { 401; CHECK-LABEL: @test15( 402; CHECK-NEXT: begin: 403; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0 404; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0 405; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]] 406; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]] 407; CHECK: bb: 408; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], [[B]] 409; CHECK-NEXT: [[RES:%.*]] = icmp sge i32 [[SUB]], 0 410; CHECK-NEXT: br label [[EXIT]] 411; CHECK: exit: 412; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ] 413; CHECK-NEXT: ret i1 [[IV]] 414; 415begin: 416 %cmp0 = icmp sge i32 %a, 0 417 %cmp1 = icmp sge i32 %b, 0 418 %br = and i1 %cmp0, %cmp1 419 br i1 %br, label %bb, label %exit 420 421bb: 422 %sub = sub nsw i32 %a, %b 423 %res = icmp sge i32 %sub, 0 424 br label %exit 425 426exit: 427 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 428 ret i1 %iv 429} 430 431define i1 @test16(i32 %a, i32 %b) { 432; CHECK-LABEL: @test16( 433; CHECK-NEXT: begin: 434; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0 435; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0 436; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]] 437; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]] 438; CHECK: bb: 439; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], [[B]] 440; CHECK-NEXT: br label [[EXIT]] 441; CHECK: exit: 442; CHECK-NEXT: ret i1 true 443; 444begin: 445 %cmp0 = icmp sge i32 %a, 0 446 %cmp1 = icmp sge i32 %b, 0 447 %br = and i1 %cmp0, %cmp1 448 br i1 %br, label %bb, label %exit 449 450bb: 451 %sub = sub nuw i32 %a, %b 452 %res = icmp sge i32 %sub, 0 453 br label %exit 454 455exit: 456 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 457 ret i1 %iv 458} 459 460define i1 @test17(i32 %a, i32 %b) { 461; CHECK-LABEL: @test17( 462; CHECK-NEXT: begin: 463; CHECK-NEXT: [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0 464; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0 465; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]] 466; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]] 467; CHECK: bb: 468; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], [[B]] 469; CHECK-NEXT: [[RES:%.*]] = icmp sle i32 [[SUB]], 0 470; CHECK-NEXT: br label [[EXIT]] 471; CHECK: exit: 472; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ] 473; CHECK-NEXT: ret i1 [[IV]] 474; 475begin: 476 %cmp0 = icmp sle i32 %a, 0 477 %cmp1 = icmp sge i32 %b, 0 478 %br = and i1 %cmp0, %cmp1 479 br i1 %br, label %bb, label %exit 480 481bb: 482 %sub = sub i32 %a, %b 483 %res = icmp sle i32 %sub, 0 484 br label %exit 485 486exit: 487 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 488 ret i1 %iv 489} 490 491define i1 @test18(i32 %a, i32 %b) { 492; CHECK-LABEL: @test18( 493; CHECK-NEXT: begin: 494; CHECK-NEXT: [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0 495; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0 496; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]] 497; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]] 498; CHECK: bb: 499; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[A]], [[B]] 500; CHECK-NEXT: [[RES:%.*]] = icmp sle i32 [[SUB]], 0 501; CHECK-NEXT: br label [[EXIT]] 502; CHECK: exit: 503; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ] 504; CHECK-NEXT: ret i1 [[IV]] 505; 506begin: 507 %cmp0 = icmp sle i32 %a, 0 508 %cmp1 = icmp sge i32 %b, 0 509 %br = and i1 %cmp0, %cmp1 510 br i1 %br, label %bb, label %exit 511 512bb: 513 %sub = sub nuw i32 %a, %b 514 %res = icmp sle i32 %sub, 0 515 br label %exit 516 517exit: 518 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 519 ret i1 %iv 520} 521 522define i1 @test19(i32 %a, i32 %b) { 523; CHECK-LABEL: @test19( 524; CHECK-NEXT: begin: 525; CHECK-NEXT: [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0 526; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0 527; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]] 528; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]] 529; CHECK: bb: 530; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], [[B]] 531; CHECK-NEXT: br label [[EXIT]] 532; CHECK: exit: 533; CHECK-NEXT: ret i1 true 534; 535begin: 536 %cmp0 = icmp sle i32 %a, 0 537 %cmp1 = icmp sge i32 %b, 0 538 %br = and i1 %cmp0, %cmp1 539 br i1 %br, label %bb, label %exit 540 541bb: 542 %sub = sub nsw i32 %a, %b 543 %res = icmp sle i32 %sub, 0 544 br label %exit 545 546exit: 547 %iv = phi i1 [ true, %begin ], [ %res, %bb ] 548 ret i1 %iv 549} 550 551define i1 @test_br_cmp_with_offset(i64 %idx) { 552; CHECK-LABEL: @test_br_cmp_with_offset( 553; CHECK-NEXT: [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5 554; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3 555; CHECK-NEXT: br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 556; CHECK: if.true: 557; CHECK-NEXT: [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1 558; CHECK-NEXT: ret i1 true 559; CHECK: if.false: 560; CHECK-NEXT: ret i1 undef 561; 562 %idx.off1 = add i64 %idx, -5 563 %cmp1 = icmp ult i64 %idx.off1, 3 564 br i1 %cmp1, label %if.true, label %if.false 565 566if.true: 567 %idx.off2 = add i64 %idx, -1 568 %cmp2 = icmp ult i64 %idx.off2, 10 569 ret i1 %cmp2 570 571if.false: 572 ret i1 undef 573} 574 575define i1 @test_assume_cmp_with_offset(i64 %idx) { 576; CHECK-LABEL: @test_assume_cmp_with_offset( 577; CHECK-NEXT: [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5 578; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3 579; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP1]]) 580; CHECK-NEXT: [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1 581; CHECK-NEXT: ret i1 true 582; 583 %idx.off1 = add i64 %idx, -5 584 %cmp1 = icmp ult i64 %idx.off1, 3 585 tail call void @llvm.assume(i1 %cmp1) 586 %idx.off2 = add i64 %idx, -1 587 %cmp2 = icmp ult i64 %idx.off2, 10 588 ret i1 %cmp2 589} 590 591define void @test_cmp_phi(i8 %a) { 592; CHECK-LABEL: @test_cmp_phi( 593; CHECK-NEXT: entry: 594; CHECK-NEXT: [[C0:%.*]] = icmp ult i8 [[A:%.*]], 2 595; CHECK-NEXT: br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]] 596; CHECK: loop: 597; CHECK-NEXT: [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ] 598; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[P]], 0 599; CHECK-NEXT: [[C4:%.*]] = call i1 @get_bool() 600; CHECK-NEXT: [[B]] = zext i1 [[C4]] to i8 601; CHECK-NEXT: br i1 [[C1]], label [[LOOP]], label [[EXIT]] 602; CHECK: exit: 603; CHECK-NEXT: ret void 604; 605entry: 606 %c0 = icmp ult i8 %a, 2 607 br i1 %c0, label %loop, label %exit 608 609loop: 610 %p = phi i8 [ %a, %entry ], [ %b, %loop ] 611 %c1 = icmp ne i8 %p, 0 612 %c2 = icmp ne i8 %p, 2 613 %c3 = and i1 %c1, %c2 614 %c4 = call i1 @get_bool() 615 %b = zext i1 %c4 to i8 616 br i1 %c3, label %loop, label %exit 617 618exit: 619 ret void 620} 621 622declare i1 @get_bool() 623 624define void @test_icmp_or_ult(i32 %a, i32 %b) { 625; CHECK-LABEL: @test_icmp_or_ult( 626; CHECK-NEXT: entry: 627; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 628; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[OR]], 42 629; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 630; CHECK: if.true: 631; CHECK-NEXT: call void @check1(i1 true) 632; CHECK-NEXT: call void @check1(i1 true) 633; CHECK-NEXT: ret void 634; CHECK: if.false: 635; CHECK-NEXT: [[CMP4:%.*]] = icmp uge i32 [[A]], 42 636; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 637; CHECK-NEXT: [[CMP5:%.*]] = icmp uge i32 [[B]], 42 638; CHECK-NEXT: call void @check1(i1 [[CMP5]]) 639; CHECK-NEXT: ret void 640; 641entry: 642 %or = or i32 %a, %b 643 %cmp = icmp ult i32 %or, 42 644 br i1 %cmp, label %if.true, label %if.false 645 646if.true: 647 %cmp2 = icmp ult i32 %a, 42 648 call void @check1(i1 %cmp2) 649 %cmp3 = icmp ult i32 %b, 42 650 call void @check1(i1 %cmp3) 651 ret void 652 653if.false: 654 %cmp4 = icmp uge i32 %a, 42 655 call void @check1(i1 %cmp4) 656 %cmp5 = icmp uge i32 %b, 42 657 call void @check1(i1 %cmp5) 658 ret void 659} 660 661define void @test_icmp_or_ule(i32 %a, i32 %b) { 662; CHECK-LABEL: @test_icmp_or_ule( 663; CHECK-NEXT: entry: 664; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 665; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OR]], 42 666; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 667; CHECK: if.true: 668; CHECK-NEXT: call void @check1(i1 true) 669; CHECK-NEXT: call void @check1(i1 true) 670; CHECK-NEXT: ret void 671; CHECK: if.false: 672; CHECK-NEXT: [[CMP4:%.*]] = icmp ugt i32 [[A]], 42 673; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 674; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[B]], 42 675; CHECK-NEXT: call void @check1(i1 [[CMP5]]) 676; CHECK-NEXT: ret void 677; 678entry: 679 %or = or i32 %a, %b 680 %cmp = icmp ule i32 %or, 42 681 br i1 %cmp, label %if.true, label %if.false 682 683if.true: 684 %cmp2 = icmp ule i32 %a, 42 685 call void @check1(i1 %cmp2) 686 %cmp3 = icmp ule i32 %b, 42 687 call void @check1(i1 %cmp3) 688 ret void 689 690if.false: 691 %cmp4 = icmp ugt i32 %a, 42 692 call void @check1(i1 %cmp4) 693 %cmp5 = icmp ugt i32 %b, 42 694 call void @check1(i1 %cmp5) 695 ret void 696} 697 698define void @test_icmp_or_ugt(i32 %a, i32 %b) { 699; CHECK-LABEL: @test_icmp_or_ugt( 700; CHECK-NEXT: entry: 701; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 702; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[OR]], 42 703; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 704; CHECK: if.true: 705; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[A]], 42 706; CHECK-NEXT: call void @check1(i1 [[CMP2]]) 707; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[B]], 42 708; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 709; CHECK-NEXT: ret void 710; CHECK: if.false: 711; CHECK-NEXT: call void @check1(i1 true) 712; CHECK-NEXT: call void @check1(i1 true) 713; CHECK-NEXT: ret void 714; 715entry: 716 %or = or i32 %a, %b 717 %cmp = icmp ugt i32 %or, 42 718 br i1 %cmp, label %if.true, label %if.false 719 720if.true: 721 %cmp2 = icmp ugt i32 %a, 42 722 call void @check1(i1 %cmp2) 723 %cmp3 = icmp ugt i32 %b, 42 724 call void @check1(i1 %cmp3) 725 ret void 726 727if.false: 728 %cmp4 = icmp ule i32 %a, 42 729 call void @check1(i1 %cmp4) 730 %cmp5 = icmp ule i32 %b, 42 731 call void @check1(i1 %cmp5) 732 ret void 733} 734 735define void @test_icmp_or_uge(i32 %a, i32 %b) { 736; CHECK-LABEL: @test_icmp_or_uge( 737; CHECK-NEXT: entry: 738; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 739; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[OR]], 42 740; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 741; CHECK: if.true: 742; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 42 743; CHECK-NEXT: call void @check1(i1 [[CMP2]]) 744; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i32 [[B]], 42 745; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 746; CHECK-NEXT: ret void 747; CHECK: if.false: 748; CHECK-NEXT: call void @check1(i1 true) 749; CHECK-NEXT: call void @check1(i1 true) 750; CHECK-NEXT: ret void 751; 752entry: 753 %or = or i32 %a, %b 754 %cmp = icmp uge i32 %or, 42 755 br i1 %cmp, label %if.true, label %if.false 756 757if.true: 758 %cmp2 = icmp uge i32 %a, 42 759 call void @check1(i1 %cmp2) 760 %cmp3 = icmp uge i32 %b, 42 761 call void @check1(i1 %cmp3) 762 ret void 763 764if.false: 765 %cmp4 = icmp ult i32 %a, 42 766 call void @check1(i1 %cmp4) 767 %cmp5 = icmp ult i32 %b, 42 768 call void @check1(i1 %cmp5) 769 ret void 770} 771 772define void @test_icmp_or_slt(i32 %a, i32 %b) { 773; CHECK-LABEL: @test_icmp_or_slt( 774; CHECK-NEXT: entry: 775; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 776; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[OR]], 42 777; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 778; CHECK: if.true: 779; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 42 780; CHECK-NEXT: call void @check1(i1 [[CMP2]]) 781; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[B]], 42 782; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 783; CHECK-NEXT: ret void 784; CHECK: if.false: 785; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[A]], 42 786; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 787; CHECK-NEXT: [[CMP5:%.*]] = icmp sge i32 [[B]], 42 788; CHECK-NEXT: call void @check1(i1 [[CMP5]]) 789; CHECK-NEXT: ret void 790; 791entry: 792 %or = or i32 %a, %b 793 %cmp = icmp slt i32 %or, 42 794 br i1 %cmp, label %if.true, label %if.false 795 796if.true: 797 %cmp2 = icmp slt i32 %a, 42 798 call void @check1(i1 %cmp2) 799 %cmp3 = icmp slt i32 %b, 42 800 call void @check1(i1 %cmp3) 801 ret void 802 803if.false: 804 %cmp4 = icmp sge i32 %a, 42 805 call void @check1(i1 %cmp4) 806 %cmp5 = icmp sge i32 %b, 42 807 call void @check1(i1 %cmp5) 808 ret void 809} 810 811define void @test_icmp_and_ugt(i32 %a, i32 %b) { 812; CHECK-LABEL: @test_icmp_and_ugt( 813; CHECK-NEXT: entry: 814; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 815; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[AND]], 42 816; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 817; CHECK: if.true: 818; CHECK-NEXT: call void @check1(i1 true) 819; CHECK-NEXT: call void @check1(i1 true) 820; CHECK-NEXT: ret void 821; CHECK: if.false: 822; CHECK-NEXT: [[CMP4:%.*]] = icmp ule i32 [[A]], 42 823; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 824; CHECK-NEXT: [[CMP5:%.*]] = icmp ule i32 [[B]], 42 825; CHECK-NEXT: call void @check1(i1 [[CMP5]]) 826; CHECK-NEXT: ret void 827; 828entry: 829 %and = and i32 %a, %b 830 %cmp = icmp ugt i32 %and, 42 831 br i1 %cmp, label %if.true, label %if.false 832 833if.true: 834 %cmp2 = icmp ugt i32 %a, 42 835 call void @check1(i1 %cmp2) 836 %cmp3 = icmp ugt i32 %b, 42 837 call void @check1(i1 %cmp3) 838 ret void 839 840if.false: 841 %cmp4 = icmp ule i32 %a, 42 842 call void @check1(i1 %cmp4) 843 %cmp5 = icmp ule i32 %b, 42 844 call void @check1(i1 %cmp5) 845 ret void 846} 847 848define void @test_icmp_and_uge(i32 %a, i32 %b) { 849; CHECK-LABEL: @test_icmp_and_uge( 850; CHECK-NEXT: entry: 851; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 852; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[AND]], 42 853; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 854; CHECK: if.true: 855; CHECK-NEXT: call void @check1(i1 true) 856; CHECK-NEXT: call void @check1(i1 true) 857; CHECK-NEXT: ret void 858; CHECK: if.false: 859; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 42 860; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 861; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[B]], 42 862; CHECK-NEXT: call void @check1(i1 [[CMP5]]) 863; CHECK-NEXT: ret void 864; 865entry: 866 %and = and i32 %a, %b 867 %cmp = icmp uge i32 %and, 42 868 br i1 %cmp, label %if.true, label %if.false 869 870if.true: 871 %cmp2 = icmp uge i32 %a, 42 872 call void @check1(i1 %cmp2) 873 %cmp3 = icmp uge i32 %b, 42 874 call void @check1(i1 %cmp3) 875 ret void 876 877if.false: 878 %cmp4 = icmp ult i32 %a, 42 879 call void @check1(i1 %cmp4) 880 %cmp5 = icmp ult i32 %b, 42 881 call void @check1(i1 %cmp5) 882 ret void 883} 884 885define void @test_icmp_and_ult(i32 %a, i32 %b) { 886; CHECK-LABEL: @test_icmp_and_ult( 887; CHECK-NEXT: entry: 888; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 889; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[AND]], 42 890; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 891; CHECK: if.true: 892; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[A]], 42 893; CHECK-NEXT: call void @check1(i1 [[CMP2]]) 894; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[B]], 42 895; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 896; CHECK-NEXT: ret void 897; CHECK: if.false: 898; CHECK-NEXT: call void @check1(i1 true) 899; CHECK-NEXT: call void @check1(i1 true) 900; CHECK-NEXT: ret void 901; 902entry: 903 %and = and i32 %a, %b 904 %cmp = icmp ult i32 %and, 42 905 br i1 %cmp, label %if.true, label %if.false 906 907if.true: 908 %cmp2 = icmp ult i32 %a, 42 909 call void @check1(i1 %cmp2) 910 %cmp3 = icmp ult i32 %b, 42 911 call void @check1(i1 %cmp3) 912 ret void 913 914if.false: 915 %cmp4 = icmp uge i32 %a, 42 916 call void @check1(i1 %cmp4) 917 %cmp5 = icmp uge i32 %b, 42 918 call void @check1(i1 %cmp5) 919 ret void 920} 921 922define void @test_icmp_and_sgt(i32 %a, i32 %b) { 923; CHECK-LABEL: @test_icmp_and_sgt( 924; CHECK-NEXT: entry: 925; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 926; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[AND]], 42 927; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 928; CHECK: if.true: 929; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 42 930; CHECK-NEXT: call void @check1(i1 [[CMP2]]) 931; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[B]], 42 932; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 933; CHECK-NEXT: ret void 934; CHECK: if.false: 935; CHECK-NEXT: [[CMP4:%.*]] = icmp sle i32 [[A]], 42 936; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 937; CHECK-NEXT: [[CMP5:%.*]] = icmp sle i32 [[B]], 42 938; CHECK-NEXT: call void @check1(i1 [[CMP5]]) 939; CHECK-NEXT: ret void 940; 941entry: 942 %and = and i32 %a, %b 943 %cmp = icmp sgt i32 %and, 42 944 br i1 %cmp, label %if.true, label %if.false 945 946if.true: 947 %cmp2 = icmp sgt i32 %a, 42 948 call void @check1(i1 %cmp2) 949 %cmp3 = icmp sgt i32 %b, 42 950 call void @check1(i1 %cmp3) 951 ret void 952 953if.false: 954 %cmp4 = icmp sle i32 %a, 42 955 call void @check1(i1 %cmp4) 956 %cmp5 = icmp sle i32 %b, 42 957 call void @check1(i1 %cmp5) 958 ret void 959} 960 961define void @test_icmp_mask_eq_two_values(i32 %a) { 962; CHECK-LABEL: @test_icmp_mask_eq_two_values( 963; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2 964; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 10 965; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 966; CHECK: if.true: 967; CHECK-NEXT: call void @check1(i1 true) 968; CHECK-NEXT: call void @check1(i1 true) 969; CHECK-NEXT: call void @check1(i1 false) 970; CHECK-NEXT: call void @check1(i1 false) 971; CHECK-NEXT: ret void 972; CHECK: if.false: 973; CHECK-NEXT: ret void 974; 975 %and = and i32 %a, -2 976 %cmp = icmp eq i32 %and, 10 977 br i1 %cmp, label %if.true, label %if.false 978 979if.true: 980 %cmp2 = icmp uge i32 %a, 10 981 call void @check1(i1 %cmp2) 982 %cmp3 = icmp ule i32 %a, 11 983 call void @check1(i1 %cmp3) 984 %cmp4 = icmp ult i32 %a, 10 985 call void @check1(i1 %cmp4) 986 %cmp5 = icmp ugt i32 %a, 11 987 call void @check1(i1 %cmp5) 988 ret void 989 990if.false: 991 ret void 992} 993 994define void @test_icmp_mask_eq_bit_set(i32 %a) { 995; CHECK-LABEL: @test_icmp_mask_eq_bit_set( 996; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 32 997; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 32 998; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 999; CHECK: if.true: 1000; CHECK-NEXT: call void @check1(i1 true) 1001; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i32 [[A]], 33 1002; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 1003; CHECK-NEXT: ret void 1004; CHECK: if.false: 1005; CHECK-NEXT: ret void 1006; 1007 %and = and i32 %a, 32 1008 %cmp = icmp eq i32 %and, 32 1009 br i1 %cmp, label %if.true, label %if.false 1010 1011if.true: 1012 %cmp2 = icmp uge i32 %a, 32 1013 call void @check1(i1 %cmp2) 1014 %cmp3 = icmp uge i32 %a, 33 1015 call void @check1(i1 %cmp3) 1016 ret void 1017 1018if.false: 1019 ret void 1020} 1021 1022define void @test_icmp_mask_eq_bit_unset(i32 %a) { 1023; CHECK-LABEL: @test_icmp_mask_eq_bit_unset( 1024; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 32 1025; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 1026; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1027; CHECK: if.true: 1028; CHECK-NEXT: call void @check1(i1 true) 1029; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], -34 1030; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 1031; CHECK-NEXT: ret void 1032; CHECK: if.false: 1033; CHECK-NEXT: ret void 1034; 1035 %and = and i32 %a, 32 1036 %cmp = icmp eq i32 %and, 0 1037 br i1 %cmp, label %if.true, label %if.false 1038 1039if.true: 1040 %cmp2 = icmp ule i32 %a, -33 1041 call void @check1(i1 %cmp2) 1042 %cmp3 = icmp ule i32 %a, -34 1043 call void @check1(i1 %cmp3) 1044 ret void 1045 1046if.false: 1047 ret void 1048} 1049 1050define void @test_icmp_mask_eq_wrong_predicate(i32 %a) { 1051; CHECK-LABEL: @test_icmp_mask_eq_wrong_predicate( 1052; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2 1053; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 10 1054; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1055; CHECK: if.true: 1056; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 10 1057; CHECK-NEXT: call void @check1(i1 [[CMP2]]) 1058; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], 11 1059; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 1060; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 10 1061; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 1062; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[A]], 11 1063; CHECK-NEXT: call void @check1(i1 [[CMP5]]) 1064; CHECK-NEXT: ret void 1065; CHECK: if.false: 1066; CHECK-NEXT: ret void 1067; 1068 %and = and i32 %a, -2 1069 %cmp = icmp ne i32 %and, 10 1070 br i1 %cmp, label %if.true, label %if.false 1071 1072if.true: 1073 %cmp2 = icmp uge i32 %a, 10 1074 call void @check1(i1 %cmp2) 1075 %cmp3 = icmp ule i32 %a, 11 1076 call void @check1(i1 %cmp3) 1077 %cmp4 = icmp ult i32 %a, 10 1078 call void @check1(i1 %cmp4) 1079 %cmp5 = icmp ugt i32 %a, 11 1080 call void @check1(i1 %cmp5) 1081 ret void 1082 1083if.false: 1084 ret void 1085} 1086 1087define void @test_icmp_mask_ne(i32 %a) { 1088; CHECK-LABEL: @test_icmp_mask_ne( 1089; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 6 1090; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 1091; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1092; CHECK: if.true: 1093; CHECK-NEXT: call void @check1(i1 true) 1094; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 2 1095; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 1096; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], -1 1097; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 1098; CHECK-NEXT: ret void 1099; CHECK: if.false: 1100; CHECK-NEXT: ret void 1101; 1102 %and = and i32 %a, 6 1103 %cmp = icmp ne i32 %and, 0 1104 br i1 %cmp, label %if.true, label %if.false 1105 1106if.true: 1107 %cmp2 = icmp uge i32 %a, 2 1108 call void @check1(i1 %cmp2) 1109 %cmp3 = icmp ugt i32 %a, 2 1110 call void @check1(i1 %cmp3) 1111 %cmp4 = icmp ult i32 %a, -1 1112 call void @check1(i1 %cmp4) 1113 ret void 1114 1115if.false: 1116 ret void 1117} 1118 1119define void @test_icmp_mask_ne_nonzero_cmp(i32 %a) { 1120; CHECK-LABEL: @test_icmp_mask_ne_nonzero_cmp( 1121; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 6 1122; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 6 1123; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1124; CHECK: if.true: 1125; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 2 1126; CHECK-NEXT: call void @check1(i1 [[CMP2]]) 1127; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 2 1128; CHECK-NEXT: call void @check1(i1 [[CMP3]]) 1129; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], -1 1130; CHECK-NEXT: call void @check1(i1 [[CMP4]]) 1131; CHECK-NEXT: ret void 1132; CHECK: if.false: 1133; CHECK-NEXT: ret void 1134; 1135 %and = and i32 %a, 6 1136 %cmp = icmp ne i32 %and, 6 1137 br i1 %cmp, label %if.true, label %if.false 1138 1139if.true: 1140 %cmp2 = icmp uge i32 %a, 2 1141 call void @check1(i1 %cmp2) 1142 %cmp3 = icmp ugt i32 %a, 2 1143 call void @check1(i1 %cmp3) 1144 %cmp4 = icmp ult i32 %a, -1 1145 call void @check1(i1 %cmp4) 1146 ret void 1147 1148if.false: 1149 ret void 1150} 1151 1152define void @test_icmp_mask_ne_zero_mask(i32 %a) { 1153; CHECK-LABEL: @test_icmp_mask_ne_zero_mask( 1154; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 0 1155; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1156; CHECK: if.true: 1157; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], 0 1158; CHECK-NEXT: call void @check1(i1 [[CMP2]]) 1159; CHECK-NEXT: ret void 1160; CHECK: if.false: 1161; CHECK-NEXT: ret void 1162; 1163 %and = and i32 %a, 0 1164 %cmp = icmp ne i32 %and, 0 1165 br i1 %cmp, label %if.true, label %if.false 1166 1167if.true: 1168 %cmp2 = icmp ne i32 %a, 0 1169 call void @check1(i1 %cmp2) 1170 ret void 1171 1172if.false: 1173 ret void 1174} 1175 1176attributes #4 = { noreturn } 1177