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