1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4define void @test_shl(i1 %x) { 5; CHECK-LABEL: @test_shl( 6; CHECK-NEXT: call void @sink(i8 0) 7; CHECK-NEXT: ret void 8; 9 %y = zext i1 %x to i8 10 %z = shl i8 64, %y 11 %a = and i8 %z, 1 12 call void @sink(i8 %a) 13 ret void 14} 15 16define void @test_lshr(i1 %x) { 17; CHECK-LABEL: @test_lshr( 18; CHECK-NEXT: call void @sink(i8 0) 19; CHECK-NEXT: ret void 20; 21 %y = zext i1 %x to i8 22 %z = lshr i8 64, %y 23 %a = and i8 %z, 1 24 call void @sink(i8 %a) 25 ret void 26} 27 28define void @test_ashr(i1 %x) { 29; CHECK-LABEL: @test_ashr( 30; CHECK-NEXT: call void @sink(i8 0) 31; CHECK-NEXT: ret void 32; 33 %y = zext i1 %x to i8 34 %z = ashr i8 -16, %y 35 %a = and i8 %z, 3 36 call void @sink(i8 %a) 37 ret void 38} 39 40define void @test_udiv(i8 %x) { 41; CHECK-LABEL: @test_udiv( 42; CHECK-NEXT: call void @sink(i8 0) 43; CHECK-NEXT: ret void 44; 45 %y = udiv i8 10, %x 46 %z = and i8 %y, 64 47 call void @sink(i8 %z) 48 ret void 49} 50 51define i8 @test_cond(i8 %x) { 52; CHECK-LABEL: @test_cond( 53; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 54; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 55; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]] 56; CHECK: if: 57; CHECK-NEXT: ret i8 -4 58; CHECK: exit: 59; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 60; CHECK-NEXT: ret i8 [[OR2]] 61; 62 %and = and i8 %x, 3 63 %cmp = icmp eq i8 %and, 0 64 br i1 %cmp, label %if, label %exit 65 66if: 67 %or1 = or i8 %x, -4 68 ret i8 %or1 69 70exit: 71 %or2 = or i8 %x, -4 72 ret i8 %or2 73} 74 75define i8 @test_cond_inv(i8 %x) { 76; CHECK-LABEL: @test_cond_inv( 77; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 78; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0 79; CHECK-NEXT: call void @use(i1 [[CMP]]) 80; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[IF:%.*]] 81; CHECK: if: 82; CHECK-NEXT: ret i8 -4 83; CHECK: exit: 84; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 85; CHECK-NEXT: ret i8 [[OR2]] 86; 87 %and = and i8 %x, 3 88 %cmp = icmp ne i8 %and, 0 89 call void @use(i1 %cmp) 90 br i1 %cmp, label %exit, label %if 91 92if: 93 %or1 = or i8 %x, -4 94 ret i8 %or1 95 96exit: 97 %or2 = or i8 %x, -4 98 ret i8 %or2 99} 100 101define i8 @test_cond_and(i8 %x, i1 %c) { 102; CHECK-LABEL: @test_cond_and( 103; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 104; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 105; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]] 106; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 107; CHECK: if: 108; CHECK-NEXT: ret i8 -4 109; CHECK: exit: 110; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 111; CHECK-NEXT: ret i8 [[OR2]] 112; 113 %and = and i8 %x, 3 114 %cmp = icmp eq i8 %and, 0 115 %cond = and i1 %cmp, %c 116 br i1 %cond, label %if, label %exit 117 118if: 119 %or1 = or i8 %x, -4 120 ret i8 %or1 121 122exit: 123 %or2 = or i8 %x, -4 124 ret i8 %or2 125} 126 127define i8 @test_cond_and_bothways(i8 %x) { 128; CHECK-LABEL: @test_cond_and_bothways( 129; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 91 130; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i8 [[AND]], 24 131; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[X]], 0 132; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP0]], [[CMP1]] 133; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 134; CHECK: if: 135; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 136; CHECK-NEXT: ret i8 [[OR1]] 137; CHECK: exit: 138; CHECK-NEXT: ret i8 -4 139; 140 %and = and i8 %x, 91 141 %cmp0 = icmp ne i8 %and, 24 142 %cmp1 = icmp ne i8 %x, 0 143 %cond = and i1 %cmp0, %cmp1 144 br i1 %cond, label %if, label %exit 145 146if: 147 %or1 = or i8 %x, -4 148 ret i8 %or1 149 150exit: 151 %or2 = or i8 %x, -4 152 ret i8 %or2 153} 154 155define i8 @test_cond_or_bothways(i8 %x) { 156; CHECK-LABEL: @test_cond_or_bothways( 157; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 91 158; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i8 [[AND]], 24 159; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 0 160; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP0]], [[CMP1]] 161; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 162; CHECK: if: 163; CHECK-NEXT: ret i8 -4 164; CHECK: exit: 165; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 166; CHECK-NEXT: ret i8 [[OR2]] 167; 168 %and = and i8 %x, 91 169 %cmp0 = icmp eq i8 %and, 24 170 %cmp1 = icmp eq i8 %x, 0 171 %cond = or i1 %cmp0, %cmp1 172 br i1 %cond, label %if, label %exit 173 174if: 175 %or1 = or i8 %x, -4 176 ret i8 %or1 177 178exit: 179 %or2 = or i8 %x, -4 180 ret i8 %or2 181} 182 183define i8 @test_cond_and_commuted(i8 %x, i1 %c1, i1 %c2) { 184; CHECK-LABEL: @test_cond_and_commuted( 185; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 186; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 187; CHECK-NEXT: [[C3:%.*]] = and i1 [[C1:%.*]], [[C2:%.*]] 188; CHECK-NEXT: [[COND:%.*]] = and i1 [[C3]], [[CMP]] 189; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 190; CHECK: if: 191; CHECK-NEXT: ret i8 -4 192; CHECK: exit: 193; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 194; CHECK-NEXT: ret i8 [[OR2]] 195; 196 %and = and i8 %x, 3 197 %cmp = icmp eq i8 %and, 0 198 %c3 = and i1 %c1, %c2 199 %cond = and i1 %c3, %cmp 200 br i1 %cond, label %if, label %exit 201 202if: 203 %or1 = or i8 %x, -4 204 ret i8 %or1 205 206exit: 207 %or2 = or i8 %x, -4 208 ret i8 %or2 209} 210 211define i8 @test_cond_logical_and(i8 %x, i1 %c) { 212; CHECK-LABEL: @test_cond_logical_and( 213; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 214; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 215; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i1 [[C:%.*]], i1 false 216; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 217; CHECK: if: 218; CHECK-NEXT: ret i8 -4 219; CHECK: exit: 220; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 221; CHECK-NEXT: ret i8 [[OR2]] 222; 223 %and = and i8 %x, 3 224 %cmp = icmp eq i8 %and, 0 225 %cond = select i1 %cmp, i1 %c, i1 false 226 br i1 %cond, label %if, label %exit 227 228if: 229 %or1 = or i8 %x, -4 230 ret i8 %or1 231 232exit: 233 %or2 = or i8 %x, -4 234 ret i8 %or2 235} 236 237define i8 @test_cond_or_invalid(i8 %x, i1 %c) { 238; CHECK-LABEL: @test_cond_or_invalid( 239; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 240; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 241; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP]], [[C:%.*]] 242; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 243; CHECK: if: 244; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 245; CHECK-NEXT: ret i8 [[OR1]] 246; CHECK: exit: 247; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 248; CHECK-NEXT: ret i8 [[OR2]] 249; 250 %and = and i8 %x, 3 251 %cmp = icmp eq i8 %and, 0 252 %cond = or i1 %cmp, %c 253 br i1 %cond, label %if, label %exit 254 255if: 256 %or1 = or i8 %x, -4 257 ret i8 %or1 258 259exit: 260 %or2 = or i8 %x, -4 261 ret i8 %or2 262} 263 264define i8 @test_cond_inv_or(i8 %x, i1 %c) { 265; CHECK-LABEL: @test_cond_inv_or( 266; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 267; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0 268; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP]], [[C:%.*]] 269; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 270; CHECK: if: 271; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 272; CHECK-NEXT: ret i8 [[OR1]] 273; CHECK: exit: 274; CHECK-NEXT: ret i8 -4 275; 276 %and = and i8 %x, 3 277 %cmp = icmp ne i8 %and, 0 278 %cond = or i1 %cmp, %c 279 br i1 %cond, label %if, label %exit 280 281if: 282 %or1 = or i8 %x, -4 283 ret i8 %or1 284 285exit: 286 %or2 = or i8 %x, -4 287 ret i8 %or2 288} 289 290define i8 @test_cond_inv_logical_or(i8 %x, i1 %c) { 291; CHECK-LABEL: @test_cond_inv_logical_or( 292; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 293; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0 294; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP_NOT]], i1 [[C:%.*]], i1 false 295; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 296; CHECK: if: 297; CHECK-NEXT: ret i8 -4 298; CHECK: exit: 299; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 300; CHECK-NEXT: ret i8 [[OR2]] 301; 302 %and = and i8 %x, 3 303 %cmp = icmp ne i8 %and, 0 304 %cond = select i1 %cmp, i1 false, i1 %c 305 br i1 %cond, label %if, label %exit 306 307if: 308 %or1 = or i8 %x, -4 309 ret i8 %or1 310 311exit: 312 %or2 = or i8 %x, -4 313 ret i8 %or2 314} 315 316define i8 @test_cond_inv_and_invalid(i8 %x, i1 %c) { 317; CHECK-LABEL: @test_cond_inv_and_invalid( 318; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 319; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0 320; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]] 321; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] 322; CHECK: if: 323; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 324; CHECK-NEXT: ret i8 [[OR1]] 325; CHECK: exit: 326; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 327; CHECK-NEXT: ret i8 [[OR2]] 328; 329 %and = and i8 %x, 3 330 %cmp = icmp ne i8 %and, 0 331 %cond = and i1 %cmp, %c 332 br i1 %cond, label %if, label %exit 333 334if: 335 %or1 = or i8 %x, -4 336 ret i8 %or1 337 338exit: 339 %or2 = or i8 %x, -4 340 ret i8 %or2 341} 342 343define i32 @test_icmp_trunc1(i32 %x) { 344; CHECK-LABEL: @test_icmp_trunc1( 345; CHECK-NEXT: entry: 346; CHECK-NEXT: [[Y:%.*]] = trunc i32 [[X:%.*]] to i16 347; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[Y]], 7 348; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 349; CHECK: then: 350; CHECK-NEXT: ret i32 7 351; CHECK: else: 352; CHECK-NEXT: ret i32 0 353; 354entry: 355 %y = trunc i32 %x to i16 356 %cmp = icmp eq i16 %y, 7 357 br i1 %cmp, label %then, label %else 358then: 359 %z = and i32 %x, 15 360 ret i32 %z 361else: 362 ret i32 0 363} 364 365define i32 @test_icmp_trunc_assume(i32 %x) { 366; CHECK-LABEL: @test_icmp_trunc_assume( 367; CHECK-NEXT: entry: 368; CHECK-NEXT: [[Y:%.*]] = trunc i32 [[X:%.*]] to i16 369; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[Y]], 7 370; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 371; CHECK-NEXT: ret i32 7 372; 373entry: 374 %y = trunc i32 %x to i16 375 %cmp = icmp eq i16 %y, 7 376 call void @llvm.assume(i1 %cmp) 377 %z = and i32 %x, 15 378 ret i32 %z 379} 380 381define i64 @test_icmp_trunc2(i64 %x) { 382; CHECK-LABEL: @test_icmp_trunc2( 383; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[X:%.*]] to i32 384; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CONV]], 12 385; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 386; CHECK: if.then: 387; CHECK-NEXT: [[SEXT:%.*]] = and i64 [[X]], 2147483647 388; CHECK-NEXT: ret i64 [[SEXT]] 389; CHECK: if.else: 390; CHECK-NEXT: ret i64 0 391; 392 %conv = trunc i64 %x to i32 393 %cmp = icmp sgt i32 %conv, 12 394 br i1 %cmp, label %if.then, label %if.else 395 396if.then: 397 %sext = shl i64 %x, 32 398 %ret = ashr exact i64 %sext, 32 399 ret i64 %ret 400if.else: 401 ret i64 0 402} 403 404define i64 @test_icmp_trunc3(i64 %n) { 405; CHECK-LABEL: @test_icmp_trunc3( 406; CHECK-NEXT: entry: 407; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[N:%.*]] to i32 408; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 96 409; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 410; CHECK: if.then: 411; CHECK-NEXT: [[RET:%.*]] = and i64 [[N]], 127 412; CHECK-NEXT: ret i64 [[RET]] 413; CHECK: if.else: 414; CHECK-NEXT: ret i64 0 415; 416entry: 417 %conv = trunc i64 %n to i32 418 %cmp = icmp ult i32 %conv, 96 419 br i1 %cmp, label %if.then, label %if.else 420 421if.then: 422 %ret = and i64 %n, 4294967295 423 ret i64 %ret 424 425if.else: 426 ret i64 0 427} 428 429define i8 @test_icmp_trunc4(i64 %n) { 430; CHECK-LABEL: @test_icmp_trunc4( 431; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[N:%.*]] to i32 432; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 10 433; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 434; CHECK: if.then: 435; CHECK-NEXT: [[CONV2:%.*]] = trunc i64 [[N]] to i8 436; CHECK-NEXT: [[ADD:%.*]] = or disjoint i8 [[CONV2]], 48 437; CHECK-NEXT: ret i8 [[ADD]] 438; CHECK: if.else: 439; CHECK-NEXT: ret i8 0 440; 441 %conv = trunc i64 %n to i32 442 %cmp = icmp ult i32 %conv, 10 443 br i1 %cmp, label %if.then, label %if.else 444 445if.then: 446 %conv2 = trunc i64 %n to i8 447 %add = add i8 %conv2, 48 448 ret i8 %add 449 450if.else: 451 ret i8 0 452} 453 454define i64 @test_icmp_trunc5(i64 %n) { 455; CHECK-LABEL: @test_icmp_trunc5( 456; CHECK-NEXT: entry: 457; CHECK-NEXT: [[SHR:%.*]] = ashr i64 [[N:%.*]], 47 458; CHECK-NEXT: [[CONV1:%.*]] = trunc nsw i64 [[SHR]] to i32 459; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CONV1]], -13 460; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 461; CHECK: if.then: 462; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[SHR]], 15 463; CHECK-NEXT: [[NOT:%.*]] = xor i64 [[TMP0]], 15 464; CHECK-NEXT: ret i64 [[NOT]] 465; CHECK: if.else: 466; CHECK-NEXT: ret i64 13 467; 468entry: 469 %shr = ashr i64 %n, 47 470 %conv1 = trunc i64 %shr to i32 471 %cmp = icmp ugt i32 %conv1, -13 472 br i1 %cmp, label %if.then, label %if.else 473 474if.then: 475 %and = and i64 %shr, 4294967295 476 %not = xor i64 %and, 4294967295 477 ret i64 %not 478 479if.else: 480 ret i64 13 481} 482 483define i1 @test_icmp_or_distjoint(i8 %n, i1 %other) { 484; CHECK-LABEL: @test_icmp_or_distjoint( 485; CHECK-NEXT: entry: 486; CHECK-NEXT: [[N_OR:%.*]] = or disjoint i8 [[N:%.*]], 16 487; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_OR]], -111 488; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 489; CHECK: if.then: 490; CHECK-NEXT: ret i1 true 491; CHECK: if.else: 492; CHECK-NEXT: ret i1 [[OTHER:%.*]] 493; 494entry: 495 %n_or = or disjoint i8 %n, 16 496 %cmp = icmp ugt i8 %n_or, 145 497 br i1 %cmp, label %if.then, label %if.else 498 499if.then: 500 %r = icmp slt i8 %n, 0 501 ret i1 %r 502 503if.else: 504 ret i1 %other 505} 506 507define i1 @test_icmp_or_fail_missing_disjoint(i8 %n, i1 %other) { 508; CHECK-LABEL: @test_icmp_or_fail_missing_disjoint( 509; CHECK-NEXT: entry: 510; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], 16 511; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_OR]], -111 512; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 513; CHECK: if.then: 514; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[N]], 0 515; CHECK-NEXT: ret i1 [[R]] 516; CHECK: if.else: 517; CHECK-NEXT: ret i1 [[OTHER:%.*]] 518; 519entry: 520 %n_or = or i8 %n, 16 521 %cmp = icmp ugt i8 %n_or, 145 522 br i1 %cmp, label %if.then, label %if.else 523 524if.then: 525 %r = icmp slt i8 %n, 0 526 ret i1 %r 527 528if.else: 529 ret i1 %other 530} 531 532define i8 @and_eq_bits_must_be_set(i8 %x, i8 %y) { 533; CHECK-LABEL: @and_eq_bits_must_be_set( 534; CHECK-NEXT: [[XY:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 535; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 123 536; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 537; CHECK-NEXT: ret i8 1 538; 539 %xy = and i8 %x, %y 540 %cmp = icmp eq i8 %xy, 123 541 call void @llvm.assume(i1 %cmp) 542 %r = and i8 %x, 1 543 ret i8 %r 544} 545 546define i8 @test_icmp_or(i8 %n, i8 %n2, i8 %other) { 547; CHECK-LABEL: @test_icmp_or( 548; CHECK-NEXT: entry: 549; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], [[N2:%.*]] 550; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_OR]], 32 551; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 552; CHECK: if.then: 553; CHECK-NEXT: ret i8 0 554; CHECK: if.else: 555; CHECK-NEXT: ret i8 [[OTHER:%.*]] 556; 557entry: 558 %n_or = or i8 %n, %n2 559 %cmp = icmp ult i8 %n_or, 32 560 br i1 %cmp, label %if.then, label %if.else 561 562if.then: 563 %r = and i8 %n, 32 564 ret i8 %r 565 566if.else: 567 ret i8 %other 568} 569 570define i8 @test_icmp_or2(i8 %n, i8 %n2, i8 %other) { 571; CHECK-LABEL: @test_icmp_or2( 572; CHECK-NEXT: entry: 573; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], [[N2:%.*]] 574; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_OR]], 14 575; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 576; CHECK: if.then: 577; CHECK-NEXT: ret i8 [[OTHER:%.*]] 578; CHECK: if.else: 579; CHECK-NEXT: ret i8 0 580; 581entry: 582 %n_or = or i8 %n, %n2 583 %cmp = icmp uge i8 %n_or, 15 584 br i1 %cmp, label %if.then, label %if.else 585 586if.then: 587 ret i8 %other 588if.else: 589 %r = and i8 %n, 32 590 ret i8 %r 591 592} 593 594define i8 @test_icmp_or_fail_bad_range(i8 %n, i8 %n2, i8 %other) { 595; CHECK-LABEL: @test_icmp_or_fail_bad_range( 596; CHECK-NEXT: entry: 597; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], [[N2:%.*]] 598; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_OR]], 33 599; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 600; CHECK: if.then: 601; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 602; CHECK-NEXT: ret i8 [[R]] 603; CHECK: if.else: 604; CHECK-NEXT: ret i8 [[OTHER:%.*]] 605; 606entry: 607 %n_or = or i8 %n, %n2 608 %cmp = icmp ule i8 %n_or, 32 609 br i1 %cmp, label %if.then, label %if.else 610 611if.then: 612 %r = and i8 %n, 32 613 ret i8 %r 614 615if.else: 616 ret i8 %other 617} 618 619define i8 @test_icmp_or_fail_bad_pred(i8 %n, i8 %n2, i8 %other) { 620; CHECK-LABEL: @test_icmp_or_fail_bad_pred( 621; CHECK-NEXT: entry: 622; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], [[N2:%.*]] 623; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_OR]], 32 624; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 625; CHECK: if.then: 626; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 627; CHECK-NEXT: ret i8 [[R]] 628; CHECK: if.else: 629; CHECK-NEXT: ret i8 [[OTHER:%.*]] 630; 631entry: 632 %n_or = or i8 %n, %n2 633 %cmp = icmp ugt i8 %n_or, 32 634 br i1 %cmp, label %if.then, label %if.else 635 636if.then: 637 %r = and i8 %n, 32 638 ret i8 %r 639 640if.else: 641 ret i8 %other 642} 643 644define i8 @test_icmp_and(i8 %n, i8 %n2, i8 %other) { 645; CHECK-LABEL: @test_icmp_and( 646; CHECK-NEXT: entry: 647; CHECK-NEXT: [[N_AND:%.*]] = and i8 [[N:%.*]], [[N2:%.*]] 648; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_AND]], -33 649; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 650; CHECK: if.then: 651; CHECK-NEXT: ret i8 32 652; CHECK: if.else: 653; CHECK-NEXT: ret i8 [[OTHER:%.*]] 654; 655entry: 656 %n_and = and i8 %n, %n2 657 %cmp = icmp ugt i8 %n_and, 223 658 br i1 %cmp, label %if.then, label %if.else 659 660if.then: 661 %r = and i8 %n, 32 662 ret i8 %r 663 664if.else: 665 ret i8 %other 666} 667 668define i8 @test_icmp_and2(i8 %n, i8 %n2, i8 %other) { 669; CHECK-LABEL: @test_icmp_and2( 670; CHECK-NEXT: entry: 671; CHECK-NEXT: [[N_AND:%.*]] = and i8 [[N:%.*]], [[N2:%.*]] 672; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_AND]], -31 673; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 674; CHECK: if.then: 675; CHECK-NEXT: ret i8 [[OTHER:%.*]] 676; CHECK: if.else: 677; CHECK-NEXT: ret i8 32 678; 679entry: 680 %n_and = and i8 %n, %n2 681 %cmp = icmp ule i8 %n_and, 224 682 br i1 %cmp, label %if.then, label %if.else 683 684if.then: 685 ret i8 %other 686if.else: 687 %r = and i8 %n, 32 688 ret i8 %r 689 690} 691 692define i8 @test_icmp_and_fail_bad_range(i8 %n, i8 %n2, i8 %other) { 693; CHECK-LABEL: @test_icmp_and_fail_bad_range( 694; CHECK-NEXT: entry: 695; CHECK-NEXT: [[N_AND:%.*]] = and i8 [[N:%.*]], [[N2:%.*]] 696; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_AND]], -34 697; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 698; CHECK: if.then: 699; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 700; CHECK-NEXT: ret i8 [[R]] 701; CHECK: if.else: 702; CHECK-NEXT: ret i8 [[OTHER:%.*]] 703; 704entry: 705 %n_and = and i8 %n, %n2 706 %cmp = icmp uge i8 %n_and, 223 707 br i1 %cmp, label %if.then, label %if.else 708 709if.then: 710 %r = and i8 %n, 32 711 ret i8 %r 712 713if.else: 714 ret i8 %other 715} 716 717define i8 @test_icmp_and_fail_bad_pred(i8 %n, i8 %n2, i8 %other) { 718; CHECK-LABEL: @test_icmp_and_fail_bad_pred( 719; CHECK-NEXT: entry: 720; CHECK-NEXT: [[N_AND:%.*]] = and i8 [[N:%.*]], [[N2:%.*]] 721; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[N_AND]], 31 722; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 723; CHECK: if.then: 724; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 725; CHECK-NEXT: ret i8 [[R]] 726; CHECK: if.else: 727; CHECK-NEXT: ret i8 [[OTHER:%.*]] 728; 729entry: 730 %n_and = and i8 %n, %n2 731 %cmp = icmp sge i8 %n_and, 32 732 br i1 %cmp, label %if.then, label %if.else 733 734if.then: 735 %r = and i8 %n, 32 736 ret i8 %r 737 738if.else: 739 ret i8 %other 740} 741 742define i8 @and_eq_bits_must_be_set2(i8 %x, i8 %y) { 743; CHECK-LABEL: @and_eq_bits_must_be_set2( 744; CHECK-NEXT: [[XY:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 745; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 123 746; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 747; CHECK-NEXT: ret i8 11 748; 749 %xy = and i8 %x, %y 750 %cmp = icmp eq i8 %xy, 123 751 call void @llvm.assume(i1 %cmp) 752 %r = and i8 %y, 11 753 ret i8 %r 754} 755 756define i8 @and_eq_bits_must_be_set2_partial_fail(i8 %x, i8 %y) { 757; CHECK-LABEL: @and_eq_bits_must_be_set2_partial_fail( 758; CHECK-NEXT: [[XY:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 759; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 123 760; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 761; CHECK-NEXT: [[R:%.*]] = and i8 [[Y]], 111 762; CHECK-NEXT: ret i8 [[R]] 763; 764 %xy = and i8 %x, %y 765 %cmp = icmp eq i8 %xy, 123 766 call void @llvm.assume(i1 %cmp) 767 %r = and i8 %y, 111 768 ret i8 %r 769} 770 771define i8 @or_eq_bits_must_be_unset(i8 %x, i8 %y) { 772; CHECK-LABEL: @or_eq_bits_must_be_unset( 773; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 774; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 124 775; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 776; CHECK-NEXT: ret i8 0 777; 778 %xy = or i8 %x, %y 779 %cmp = icmp eq i8 %xy, 124 780 call void @llvm.assume(i1 %cmp) 781 %r = and i8 %x, 3 782 ret i8 %r 783} 784 785define i8 @or_eq_bits_must_be_unset2(i8 %x, i8 %y) { 786; CHECK-LABEL: @or_eq_bits_must_be_unset2( 787; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 788; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 124 789; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 790; CHECK-NEXT: ret i8 0 791; 792 %xy = or i8 %x, %y 793 %cmp = icmp eq i8 %xy, 124 794 call void @llvm.assume(i1 %cmp) 795 %r = and i8 %y, 1 796 ret i8 %r 797} 798 799define i8 @or_eq_bits_must_be_unset2_partial_fail(i8 %x, i8 %y) { 800; CHECK-LABEL: @or_eq_bits_must_be_unset2_partial_fail( 801; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 802; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 124 803; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 804; CHECK-NEXT: [[R:%.*]] = and i8 [[Y]], 4 805; CHECK-NEXT: ret i8 [[R]] 806; 807 %xy = or i8 %x, %y 808 %cmp = icmp eq i8 %xy, 124 809 call void @llvm.assume(i1 %cmp) 810 %r = and i8 %y, 7 811 ret i8 %r 812} 813 814define i8 @or_ne_bits_must_be_unset2_fail(i8 %x, i8 %y) { 815; CHECK-LABEL: @or_ne_bits_must_be_unset2_fail( 816; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 817; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[XY]], 124 818; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 819; CHECK-NEXT: [[R:%.*]] = and i8 [[X]], 3 820; CHECK-NEXT: ret i8 [[R]] 821; 822 %xy = or i8 %x, %y 823 %cmp = icmp ne i8 %xy, 124 824 call void @llvm.assume(i1 %cmp) 825 %r = and i8 %x, 3 826 ret i8 %r 827} 828 829declare void @use.i1(i1) 830declare void @use.i8(i8) 831 832declare void @use.2xi1(<2 x i1>) 833 834define i1 @extract_value_uadd(<2 x i8> %xx, <2 x i8> %yy) { 835; CHECK-LABEL: @extract_value_uadd( 836; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1> 837; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1> 838; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0> 839; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0> 840; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]]) 841; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1 842; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]]) 843; CHECK-NEXT: ret i1 false 844; 845 %x0 = and <2 x i8> %xx, <i8 63, i8 255> 846 %y0 = and <2 x i8> %yy, <i8 63, i8 255> 847 %x = add nuw <2 x i8> %x0, <i8 1, i8 0> 848 %y = add nuw <2 x i8> %y0, <i8 1, i8 0> 849 850 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y) 851 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0 852 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1 853 call void @use.2xi1(<2 x i1> %uov) 854 %add_ele = extractelement <2 x i8> %add, i32 0 855 %r = icmp eq i8 %add_ele, 0 856 ret i1 %r 857} 858 859define i1 @extract_value_uadd2(<2 x i8> %xx, <2 x i8> %yy) { 860; CHECK-LABEL: @extract_value_uadd2( 861; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 -1, i8 63> 862; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 -1, i8 63> 863; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 0, i8 1> 864; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 0, i8 1> 865; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]]) 866; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1 867; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]]) 868; CHECK-NEXT: ret i1 false 869; 870 %x0 = and <2 x i8> %xx, <i8 255, i8 63> 871 %y0 = and <2 x i8> %yy, <i8 255, i8 63> 872 %x = add nuw <2 x i8> %x0, <i8 0, i8 1> 873 %y = add nuw <2 x i8> %y0, <i8 0, i8 1> 874 875 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y) 876 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0 877 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1 878 call void @use.2xi1(<2 x i1> %uov) 879 %add_ele = extractelement <2 x i8> %add, i32 1 880 %r = icmp eq i8 %add_ele, 0 881 ret i1 %r 882} 883 884define i1 @extract_value_uadd_fail(<2 x i8> %xx, <2 x i8> %yy) { 885; CHECK-LABEL: @extract_value_uadd_fail( 886; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1> 887; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1> 888; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0> 889; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0> 890; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]]) 891; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0 892; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1 893; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]]) 894; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i64 1 895; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0 896; CHECK-NEXT: ret i1 [[R]] 897; 898 %x0 = and <2 x i8> %xx, <i8 63, i8 255> 899 %y0 = and <2 x i8> %yy, <i8 63, i8 255> 900 %x = add nuw <2 x i8> %x0, <i8 1, i8 0> 901 %y = add nuw <2 x i8> %y0, <i8 1, i8 0> 902 903 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y) 904 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0 905 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1 906 call void @use.2xi1(<2 x i1> %uov) 907 %add_ele = extractelement <2 x i8> %add, i32 1 908 %r = icmp eq i8 %add_ele, 0 909 ret i1 %r 910} 911 912define i1 @extract_value_uadd_fail2(<2 x i8> %xx, <2 x i8> %yy, i32 %idx) { 913; CHECK-LABEL: @extract_value_uadd_fail2( 914; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1> 915; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1> 916; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0> 917; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0> 918; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]]) 919; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0 920; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1 921; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]]) 922; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i32 [[IDX:%.*]] 923; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0 924; CHECK-NEXT: ret i1 [[R]] 925; 926 %x0 = and <2 x i8> %xx, <i8 63, i8 255> 927 %y0 = and <2 x i8> %yy, <i8 63, i8 255> 928 %x = add nuw <2 x i8> %x0, <i8 1, i8 0> 929 %y = add nuw <2 x i8> %y0, <i8 1, i8 0> 930 931 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y) 932 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0 933 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1 934 call void @use.2xi1(<2 x i1> %uov) 935 %add_ele = extractelement <2 x i8> %add, i32 %idx 936 %r = icmp eq i8 %add_ele, 0 937 ret i1 %r 938} 939 940define i1 @extract_value_uadd_fail3(<2 x i8> %xx, <2 x i8> %yy) { 941; CHECK-LABEL: @extract_value_uadd_fail3( 942; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], splat (i8 127) 943; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], splat (i8 127) 944; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], splat (i8 1) 945; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], splat (i8 1) 946; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]]) 947; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0 948; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1 949; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]]) 950; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i64 0 951; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0 952; CHECK-NEXT: ret i1 [[R]] 953; 954 %x0 = and <2 x i8> %xx, <i8 127, i8 127> 955 %y0 = and <2 x i8> %yy, <i8 127, i8 127> 956 %x = add nuw <2 x i8> %x0, <i8 1, i8 1> 957 %y = add nuw <2 x i8> %y0, <i8 1, i8 1> 958 959 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y) 960 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0 961 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1 962 call void @use.2xi1(<2 x i1> %uov) 963 %add_ele = extractelement <2 x i8> %add, i32 0 964 %r = icmp eq i8 %add_ele, 0 965 ret i1 %r 966} 967 968define i1 @extract_value_sadd(i8 %xx, i8 %yy) { 969; CHECK-LABEL: @extract_value_sadd( 970; CHECK-NEXT: [[X:%.*]] = add nuw i8 [[XX:%.*]], 1 971; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 972; CHECK-NEXT: [[X_LEMMA:%.*]] = icmp sgt i8 [[X]], -1 973; CHECK-NEXT: [[Y_LEMMA:%.*]] = icmp sgt i8 [[Y]], -1 974; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]]) 975; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]]) 976; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]]) 977; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1 978; CHECK-NEXT: call void @use.i1(i1 [[SOV]]) 979; CHECK-NEXT: ret i1 false 980; 981 %x = add nuw i8 %xx, 1 982 %y = add nuw i8 %yy, 1 983 %x_lemma = icmp ult i8 %x, 128 984 %y_lemma = icmp ult i8 %y, 128 985 call void @llvm.assume(i1 %x_lemma) 986 call void @llvm.assume(i1 %y_lemma) 987 988 %add_sov = call { i8, i1 } @llvm.sadd.with.overflow(i8 %x, i8 %y) 989 %add = extractvalue { i8, i1 } %add_sov, 0 990 %sov = extractvalue { i8, i1 } %add_sov, 1 991 call void @use.i1(i1 %sov) 992 %r = icmp eq i8 %add, 0 993 ret i1 %r 994} 995 996define i1 @extract_value_sadd_fail(i8 %xx, i8 %yy) { 997; CHECK-LABEL: @extract_value_sadd_fail( 998; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], 1 999; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1 1000; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]]) 1001; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 0 1002; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1 1003; CHECK-NEXT: call void @use.i1(i1 [[SOV]]) 1004; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0 1005; CHECK-NEXT: ret i1 [[R]] 1006; 1007 %x = add i8 %xx, 1 1008 %y = add i8 %yy, 1 1009 1010 %add_sov = call { i8, i1 } @llvm.sadd.with.overflow(i8 %x, i8 %y) 1011 %add = extractvalue { i8, i1 } %add_sov, 0 1012 %sov = extractvalue { i8, i1 } %add_sov, 1 1013 call void @use.i1(i1 %sov) 1014 %r = icmp eq i8 %add, 0 1015 ret i1 %r 1016} 1017 1018define i1 @extract_value_usub(i8 %x, i8 %zz) { 1019; CHECK-LABEL: @extract_value_usub( 1020; CHECK-NEXT: [[Z:%.*]] = add nuw i8 [[ZZ:%.*]], 1 1021; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z]] 1022; CHECK-NEXT: [[SUB_UOV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X]], i8 [[Y]]) 1023; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 0 1024; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1 1025; CHECK-NEXT: call void @use.i1(i1 [[UOV]]) 1026; CHECK-NEXT: call void @use.i8(i8 [[SUB]]) 1027; CHECK-NEXT: ret i1 false 1028; 1029 %z = add nuw i8 %zz, 1 1030 %y = add i8 %x, %z 1031 1032 %sub_uov = call { i8, i1 } @llvm.usub.with.overflow(i8 %x, i8 %y) 1033 %sub = extractvalue { i8, i1 } %sub_uov, 0 1034 %uov = extractvalue { i8, i1 } %sub_uov, 1 1035 call void @use.i1(i1 %uov) 1036 call void @use.i8(i8 %sub) 1037 %r = icmp eq i8 %sub, 0 1038 ret i1 %r 1039} 1040 1041define i1 @extract_value_usub_fail(i8 %x, i8 %z) { 1042; CHECK-LABEL: @extract_value_usub_fail( 1043; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z:%.*]] 1044; CHECK-NEXT: [[SUB_UOV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X]], i8 [[Y]]) 1045; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 0 1046; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1 1047; CHECK-NEXT: call void @use.i1(i1 [[UOV]]) 1048; CHECK-NEXT: call void @use.i8(i8 [[SUB]]) 1049; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0 1050; CHECK-NEXT: ret i1 [[R]] 1051; 1052 %y = add i8 %x, %z 1053 %sub_uov = call { i8, i1 } @llvm.usub.with.overflow(i8 %x, i8 %y) 1054 %sub = extractvalue { i8, i1 } %sub_uov, 0 1055 %uov = extractvalue { i8, i1 } %sub_uov, 1 1056 call void @use.i1(i1 %uov) 1057 call void @use.i8(i8 %sub) 1058 %r = icmp eq i8 %sub, 0 1059 ret i1 %r 1060} 1061 1062define i1 @extract_value_ssub(i8 %x, i8 %zz) { 1063; CHECK-LABEL: @extract_value_ssub( 1064; CHECK-NEXT: [[Z:%.*]] = add nuw i8 [[ZZ:%.*]], 1 1065; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z]] 1066; CHECK-NEXT: [[SUB_SOV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[Y]], i8 [[X]]) 1067; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 0 1068; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1 1069; CHECK-NEXT: call void @use.i1(i1 [[SOV]]) 1070; CHECK-NEXT: call void @use.i8(i8 [[SUB]]) 1071; CHECK-NEXT: ret i1 false 1072; 1073 %z = add nuw i8 %zz, 1 1074 %y = add i8 %x, %z 1075 1076 %sub_sov = call { i8, i1 } @llvm.ssub.with.overflow(i8 %y, i8 %x) 1077 %sub = extractvalue { i8, i1 } %sub_sov, 0 1078 %sov = extractvalue { i8, i1 } %sub_sov, 1 1079 call void @use.i1(i1 %sov) 1080 call void @use.i8(i8 %sub) 1081 %r = icmp eq i8 %sub, 0 1082 ret i1 %r 1083} 1084 1085define i1 @extract_value_ssub_fail(i8 %x) { 1086; CHECK-LABEL: @extract_value_ssub_fail( 1087; CHECK-NEXT: [[SUB_SOV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 10, i8 [[X:%.*]]) 1088; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 0 1089; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1 1090; CHECK-NEXT: call void @use.i1(i1 [[SOV]]) 1091; CHECK-NEXT: call void @use.i8(i8 [[SUB]]) 1092; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0 1093; CHECK-NEXT: ret i1 [[R]] 1094; 1095 %sub_sov = call { i8, i1 } @llvm.ssub.with.overflow(i8 10, i8 %x) 1096 %sub = extractvalue { i8, i1 } %sub_sov, 0 1097 %sov = extractvalue { i8, i1 } %sub_sov, 1 1098 call void @use.i1(i1 %sov) 1099 call void @use.i8(i8 %sub) 1100 %r = icmp eq i8 %sub, 0 1101 ret i1 %r 1102} 1103 1104define i1 @extract_value_umul(i8 %xx, i8 %yy) { 1105; CHECK-LABEL: @extract_value_umul( 1106; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1 1107; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 1108; CHECK-NEXT: [[MUL_UOV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X]], i8 [[Y]]) 1109; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 0 1110; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1 1111; CHECK-NEXT: call void @use.i1(i1 [[UOV]]) 1112; CHECK-NEXT: call void @use.i8(i8 [[MUL]]) 1113; CHECK-NEXT: ret i1 false 1114; 1115 %x = or i8 %xx, 1 1116 %y = add nuw i8 %yy, 1 1117 1118 %mul_uov = call { i8, i1 } @llvm.umul.with.overflow(i8 %x, i8 %y) 1119 %mul = extractvalue { i8, i1 } %mul_uov, 0 1120 %uov = extractvalue { i8, i1 } %mul_uov, 1 1121 call void @use.i1(i1 %uov) 1122 call void @use.i8(i8 %mul) 1123 %r = icmp eq i8 %mul, 0 1124 ret i1 %r 1125} 1126 1127define i1 @extract_value_umul_fail(i8 %xx, i8 %yy) { 1128; CHECK-LABEL: @extract_value_umul_fail( 1129; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 2 1130; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 1131; CHECK-NEXT: [[MUL_UOV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X]], i8 [[Y]]) 1132; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 0 1133; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1 1134; CHECK-NEXT: call void @use.i1(i1 [[UOV]]) 1135; CHECK-NEXT: call void @use.i8(i8 [[MUL]]) 1136; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0 1137; CHECK-NEXT: ret i1 [[R]] 1138; 1139 %x = or i8 %xx, 2 1140 %y = add nuw i8 %yy, 1 1141 1142 %mul_uov = call { i8, i1 } @llvm.umul.with.overflow(i8 %x, i8 %y) 1143 %mul = extractvalue { i8, i1 } %mul_uov, 0 1144 %uov = extractvalue { i8, i1 } %mul_uov, 1 1145 call void @use.i1(i1 %uov) 1146 call void @use.i8(i8 %mul) 1147 %r = icmp eq i8 %mul, 0 1148 ret i1 %r 1149} 1150 1151define i1 @extract_value_smul(i8 %xx, i8 %yy) { 1152; CHECK-LABEL: @extract_value_smul( 1153; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1 1154; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 1155; CHECK-NEXT: [[MUL_SOV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 [[X]]) 1156; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 0 1157; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1 1158; CHECK-NEXT: call void @use.i1(i1 [[SOV]]) 1159; CHECK-NEXT: call void @use.i8(i8 [[MUL]]) 1160; CHECK-NEXT: ret i1 false 1161; 1162 %x = or i8 %xx, 1 1163 %y = add nuw i8 %yy, 1 1164 1165 %mul_sov = call { i8, i1 } @llvm.smul.with.overflow(i8 %y, i8 %x) 1166 %mul = extractvalue { i8, i1 } %mul_sov, 0 1167 %sov = extractvalue { i8, i1 } %mul_sov, 1 1168 call void @use.i1(i1 %sov) 1169 call void @use.i8(i8 %mul) 1170 %r = icmp eq i8 %mul, 0 1171 ret i1 %r 1172} 1173 1174define i1 @extract_value_smul_fail(i8 %xx, i8 %yy) { 1175; CHECK-LABEL: @extract_value_smul_fail( 1176; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1 1177; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1 1178; CHECK-NEXT: [[MUL_SOV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 [[X]]) 1179; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 0 1180; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1 1181; CHECK-NEXT: call void @use.i1(i1 [[SOV]]) 1182; CHECK-NEXT: call void @use.i8(i8 [[MUL]]) 1183; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0 1184; CHECK-NEXT: ret i1 [[R]] 1185; 1186 %x = or i8 %xx, 1 1187 %y = add i8 %yy, 1 1188 1189 %mul_sov = call { i8, i1 } @llvm.smul.with.overflow(i8 %y, i8 %x) 1190 %mul = extractvalue { i8, i1 } %mul_sov, 0 1191 %sov = extractvalue { i8, i1 } %mul_sov, 1 1192 call void @use.i1(i1 %sov) 1193 call void @use.i8(i8 %mul) 1194 %r = icmp eq i8 %mul, 0 1195 ret i1 %r 1196} 1197 1198define i8 @known_reduce_or(<2 x i8> %xx) { 1199; CHECK-LABEL: @known_reduce_or( 1200; CHECK-NEXT: ret i8 1 1201; 1202 %x = or <2 x i8> %xx, <i8 5, i8 3> 1203 %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x) 1204 %r = and i8 %v, 1 1205 ret i8 %r 1206} 1207 1208define i8 @known_reduce_or_fail(<2 x i8> %xx) { 1209; CHECK-LABEL: @known_reduce_or_fail( 1210; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3> 1211; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]]) 1212; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 4 1213; CHECK-NEXT: ret i8 [[R]] 1214; 1215 %x = or <2 x i8> %xx, <i8 5, i8 3> 1216 %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x) 1217 %r = and i8 %v, 4 1218 ret i8 %r 1219} 1220 1221define i8 @known_reduce_and(<2 x i8> %xx) { 1222; CHECK-LABEL: @known_reduce_and( 1223; CHECK-NEXT: ret i8 1 1224; 1225 %x = or <2 x i8> %xx, <i8 5, i8 3> 1226 %v = call i8 @llvm.vector.reduce.and(<2 x i8> %x) 1227 %r = and i8 %v, 1 1228 ret i8 %r 1229} 1230 1231define i8 @known_reduce_and_fail(<2 x i8> %xx) { 1232; CHECK-LABEL: @known_reduce_and_fail( 1233; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3> 1234; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.and.v2i8(<2 x i8> [[X]]) 1235; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2 1236; CHECK-NEXT: ret i8 [[R]] 1237; 1238 %x = or <2 x i8> %xx, <i8 5, i8 3> 1239 %v = call i8 @llvm.vector.reduce.and(<2 x i8> %x) 1240 %r = and i8 %v, 2 1241 ret i8 %r 1242} 1243 1244define i8 @known_reduce_xor_even(<2 x i8> %xx) { 1245; CHECK-LABEL: @known_reduce_xor_even( 1246; CHECK-NEXT: ret i8 0 1247; 1248 %x = or <2 x i8> %xx, <i8 5, i8 3> 1249 %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x) 1250 %r = and i8 %v, 1 1251 ret i8 %r 1252} 1253 1254define i8 @known_reduce_xor_even2(<2 x i8> %xx) { 1255; CHECK-LABEL: @known_reduce_xor_even2( 1256; CHECK-NEXT: ret i8 0 1257; 1258 %x = and <2 x i8> %xx, <i8 15, i8 15> 1259 %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x) 1260 %r = and i8 %v, 16 1261 ret i8 %r 1262} 1263 1264define i8 @known_reduce_xor_even_fail(<2 x i8> %xx) { 1265; CHECK-LABEL: @known_reduce_xor_even_fail( 1266; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3> 1267; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]]) 1268; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2 1269; CHECK-NEXT: ret i8 [[R]] 1270; 1271 %x = or <2 x i8> %xx, <i8 5, i8 3> 1272 %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x) 1273 %r = and i8 %v, 2 1274 ret i8 %r 1275} 1276 1277define i8 @known_reduce_xor_odd(<3 x i8> %xx) { 1278; CHECK-LABEL: @known_reduce_xor_odd( 1279; CHECK-NEXT: ret i8 1 1280; 1281 %x = or <3 x i8> %xx, <i8 5, i8 3, i8 9> 1282 %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x) 1283 %r = and i8 %v, 1 1284 ret i8 %r 1285} 1286 1287define i8 @known_reduce_xor_odd2(<3 x i8> %xx) { 1288; CHECK-LABEL: @known_reduce_xor_odd2( 1289; CHECK-NEXT: ret i8 0 1290; 1291 %x = and <3 x i8> %xx, <i8 15, i8 15, i8 31> 1292 %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x) 1293 %r = and i8 %v, 32 1294 ret i8 %r 1295} 1296 1297define i8 @known_reduce_xor_odd2_fail(<3 x i8> %xx) { 1298; CHECK-LABEL: @known_reduce_xor_odd2_fail( 1299; CHECK-NEXT: [[X:%.*]] = and <3 x i8> [[XX:%.*]], <i8 15, i8 15, i8 31> 1300; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]]) 1301; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 16 1302; CHECK-NEXT: ret i8 [[R]] 1303; 1304 %x = and <3 x i8> %xx, <i8 15, i8 15, i8 31> 1305 %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x) 1306 %r = and i8 %v, 16 1307 ret i8 %r 1308} 1309 1310define i8 @known_reduce_xor_odd_fail(<3 x i8> %xx) { 1311; CHECK-LABEL: @known_reduce_xor_odd_fail( 1312; CHECK-NEXT: [[X:%.*]] = or <3 x i8> [[XX:%.*]], <i8 5, i8 3, i8 9> 1313; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]]) 1314; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2 1315; CHECK-NEXT: ret i8 [[R]] 1316; 1317 %x = or <3 x i8> %xx, <i8 5, i8 3, i8 9> 1318 %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x) 1319 %r = and i8 %v, 2 1320 ret i8 %r 1321} 1322 1323define i8 @nonzero_reduce_xor_vscale_even(<vscale x 2 x i8> %xx) { 1324; CHECK-LABEL: @nonzero_reduce_xor_vscale_even( 1325; CHECK-NEXT: ret i8 0 1326; 1327 %one = insertelement <vscale x 2 x i8> poison, i8 1, i64 0 1328 %ones = shufflevector <vscale x 2 x i8> %one, <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer 1329 %x = or <vscale x 2 x i8> %xx, %ones 1330 %v = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> %x) 1331 %r = and i8 %v, 1 1332 ret i8 %r 1333} 1334 1335define i8 @nonzero_reduce_xor_vscale_odd_fail(<vscale x 3 x i8> %xx) { 1336; CHECK-LABEL: @nonzero_reduce_xor_vscale_odd_fail( 1337; CHECK-NEXT: [[X:%.*]] = or <vscale x 3 x i8> [[XX:%.*]], splat (i8 1) 1338; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> [[X]]) 1339; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1 1340; CHECK-NEXT: ret i8 [[R]] 1341; 1342 %one = insertelement <vscale x 3 x i8> poison, i8 1, i64 0 1343 %ones = shufflevector <vscale x 3 x i8> %one, <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer 1344 %x = or <vscale x 3 x i8> %xx, %ones 1345 %v = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> %x) 1346 %r = and i8 %v, 1 1347 ret i8 %r 1348} 1349 1350define i8 @nonzero_reduce_xor_vscale_even_fail(<vscale x 2 x i8> %xx) { 1351; CHECK-LABEL: @nonzero_reduce_xor_vscale_even_fail( 1352; CHECK-NEXT: [[X:%.*]] = or <vscale x 2 x i8> [[XX:%.*]], splat (i8 1) 1353; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> [[X]]) 1354; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2 1355; CHECK-NEXT: ret i8 [[R]] 1356; 1357 %one = insertelement <vscale x 2 x i8> poison, i8 1, i64 0 1358 %ones = shufflevector <vscale x 2 x i8> %one, <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer 1359 %x = or <vscale x 2 x i8> %xx, %ones 1360 %v = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> %x) 1361 %r = and i8 %v, 2 1362 ret i8 %r 1363} 1364 1365define i8 @nonzero_reduce_xor_vscale_odd(<vscale x 3 x i8> %xx) { 1366; CHECK-LABEL: @nonzero_reduce_xor_vscale_odd( 1367; CHECK-NEXT: ret i8 0 1368; 1369 %one = insertelement <vscale x 3 x i8> poison, i8 1, i64 0 1370 %ones = shufflevector <vscale x 3 x i8> %one, <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer 1371 %x = and <vscale x 3 x i8> %xx, %ones 1372 %v = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> %x) 1373 %r = and i8 %v, 2 1374 ret i8 %r 1375} 1376 1377define i1 @test_sign_pos(float %x) { 1378; CHECK-LABEL: @test_sign_pos( 1379; CHECK-NEXT: ret i1 true 1380; 1381 %fabs = call float @llvm.fabs.f32(float %x) 1382 %y = bitcast float %fabs to i32 1383 %sign = icmp sgt i32 %y, -1 1384 ret i1 %sign 1385} 1386 1387define i1 @test_sign_pos_half(half %x) { 1388; CHECK-LABEL: @test_sign_pos_half( 1389; CHECK-NEXT: ret i1 true 1390; 1391 %fabs = call half @llvm.fabs.f16(half %x) 1392 %y = bitcast half %fabs to i16 1393 %sign = icmp sgt i16 %y, -1 1394 ret i1 %sign 1395} 1396 1397define i1 @test_sign_pos_half_non_elementwise(<2 x half> %x) { 1398; CHECK-LABEL: @test_sign_pos_half_non_elementwise( 1399; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]]) 1400; CHECK-NEXT: [[Y:%.*]] = bitcast <2 x half> [[FABS]] to i32 1401; CHECK-NEXT: [[SIGN:%.*]] = icmp sgt i32 [[Y]], -1 1402; CHECK-NEXT: ret i1 [[SIGN]] 1403; 1404 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 1405 %y = bitcast <2 x half> %fabs to i32 1406 %sign = icmp sgt i32 %y, -1 1407 ret i1 %sign 1408} 1409 1410define i1 @test_sign_neg(float %x) { 1411; CHECK-LABEL: @test_sign_neg( 1412; CHECK-NEXT: ret i1 true 1413; 1414 %fabs = call float @llvm.fabs.f32(float %x) 1415 %fnabs = fneg float %fabs 1416 %y = bitcast float %fnabs to i32 1417 %sign = icmp slt i32 %y, 0 1418 ret i1 %sign 1419} 1420 1421define <2 x i1> @test_sign_pos_vec(<2 x float> %x) { 1422; CHECK-LABEL: @test_sign_pos_vec( 1423; CHECK-NEXT: ret <2 x i1> zeroinitializer 1424; 1425 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %x) 1426 %y = bitcast <2 x float> %fabs to <2 x i32> 1427 %sign = icmp slt <2 x i32> %y, zeroinitializer 1428 ret <2 x i1> %sign 1429} 1430 1431define i32 @test_inf_only(float nofpclass(nan sub norm zero) %x) { 1432; CHECK-LABEL: @test_inf_only( 1433; CHECK-NEXT: ret i32 2139095040 1434; 1435 %y = bitcast float %x to i32 1436 %and = and i32 %y, 2147483647 1437 ret i32 %and 1438} 1439 1440define i16 @test_inf_only_bfloat(bfloat nofpclass(nan sub norm zero) %x) { 1441; CHECK-LABEL: @test_inf_only_bfloat( 1442; CHECK-NEXT: ret i16 32640 1443; 1444 %y = bitcast bfloat %x to i16 1445 %and = and i16 %y, 32767 1446 ret i16 %and 1447} 1448 1449define i128 @test_inf_only_ppc_fp128(ppc_fp128 nofpclass(nan sub norm zero) %x) { 1450; CHECK-LABEL: @test_inf_only_ppc_fp128( 1451; CHECK-NEXT: ret i128 9218868437227405312 1452; 1453 %y = bitcast ppc_fp128 %x to i128 1454 %and = and i128 %y, 170141183460469231731687303715884105727 1455 ret i128 %and 1456} 1457 1458define i32 @test_zero_only(float nofpclass(nan sub norm inf) %x) { 1459; CHECK-LABEL: @test_zero_only( 1460; CHECK-NEXT: ret i32 0 1461; 1462 %y = bitcast float %x to i32 1463 %and = and i32 %y, 2147483647 1464 ret i32 %and 1465} 1466 1467define i80 @test_zero_only_non_ieee(x86_fp80 nofpclass(nan sub norm inf) %x) { 1468; CHECK-LABEL: @test_zero_only_non_ieee( 1469; CHECK-NEXT: ret i80 0 1470; 1471 %y = bitcast x86_fp80 %x to i80 1472 %and = and i80 %y, 604462909807314587353087 1473 ret i80 %and 1474} 1475 1476define i32 @test_inf_nan_only(float nofpclass(sub norm zero) %x) { 1477; CHECK-LABEL: @test_inf_nan_only( 1478; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 1479; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432 1480; CHECK-NEXT: ret i32 [[AND]] 1481; 1482 %y = bitcast float %x to i32 1483 %and = and i32 %y, 2130706432 1484 ret i32 %and 1485} 1486 1487define i32 @test_sub_zero_only(float nofpclass(nan norm inf) %x) { 1488; CHECK-LABEL: @test_sub_zero_only( 1489; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 1490; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432 1491; CHECK-NEXT: ret i32 [[AND]] 1492; 1493 %y = bitcast float %x to i32 1494 %and = and i32 %y, 2130706432 1495 ret i32 %and 1496} 1497 1498define i32 @test_inf_zero_only(float nofpclass(nan norm sub) %x) { 1499; CHECK-LABEL: @test_inf_zero_only( 1500; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 1501; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 8388608 1502; CHECK-NEXT: ret i32 [[AND]] 1503; 1504 %y = bitcast float %x to i32 1505 %and = and i32 %y, 16777215 1506 ret i32 %and 1507} 1508 1509; Make sure that the signbit is cleared. 1510define i32 @test_ninf_only(double %x) { 1511; CHECK-LABEL: @test_ninf_only( 1512; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[X:%.*]], 0xFFF0000000000000 1513; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1514; CHECK: if.then: 1515; CHECK-NEXT: ret i32 0 1516; CHECK: if.else: 1517; CHECK-NEXT: ret i32 0 1518; 1519 %cmp = fcmp oeq double %x, 0xFFF0000000000000 1520 br i1 %cmp, label %if.then, label %if.else 1521 1522if.then: 1523 %cast = bitcast double %x to i64 1524 %trunc = trunc i64 %cast to i32 1525 ret i32 %trunc 1526 1527if.else: 1528 ret i32 0 1529} 1530 1531define i1 @test_simplify_icmp(i32 %x) { 1532; CHECK-LABEL: @test_simplify_icmp( 1533; CHECK-NEXT: ret i1 false 1534; 1535 %cast1 = uitofp i32 %x to double 1536 %cast2 = bitcast double %cast1 to i64 1537 %mask = and i64 %cast2, -140737488355328 1538 %cmp = icmp eq i64 %mask, -1970324836974592 1539 ret i1 %cmp 1540} 1541 1542define i32 @test_snan_quiet_bit1(float nofpclass(sub norm inf qnan) %x) { 1543; CHECK-LABEL: @test_snan_quiet_bit1( 1544; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 1545; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 4194304 1546; CHECK-NEXT: ret i32 [[MASKED]] 1547; 1548 %bits = bitcast float %x to i32 1549 %masked = and i32 %bits, 4194304 1550 ret i32 %masked 1551} 1552 1553define i32 @test_snan_quiet_bit2(float nofpclass(sub norm inf qnan) %x) { 1554; CHECK-LABEL: @test_snan_quiet_bit2( 1555; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 1556; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 2097152 1557; CHECK-NEXT: ret i32 [[MASKED]] 1558; 1559 %bits = bitcast float %x to i32 1560 %masked = and i32 %bits, 2097152 1561 ret i32 %masked 1562} 1563 1564define i32 @test_qnan_quiet_bit1(float nofpclass(sub norm inf snan) %x) { 1565; CHECK-LABEL: @test_qnan_quiet_bit1( 1566; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 1567; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 4194304 1568; CHECK-NEXT: ret i32 [[MASKED]] 1569; 1570 %bits = bitcast float %x to i32 1571 %masked = and i32 %bits, 4194304 1572 ret i32 %masked 1573} 1574 1575define i32 @test_qnan_quiet_bit2(float nofpclass(sub norm inf snan) %x) { 1576; CHECK-LABEL: @test_qnan_quiet_bit2( 1577; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32 1578; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 2097152 1579; CHECK-NEXT: ret i32 [[MASKED]] 1580; 1581 %bits = bitcast float %x to i32 1582 %masked = and i32 %bits, 2097152 1583 ret i32 %masked 1584} 1585 1586define i16 @test_simplify_mask(i32 %ui, float %x) { 1587; CHECK-LABEL: @test_simplify_mask( 1588; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[UI:%.*]] to float 1589; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[CONV]] 1590; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]] 1591; CHECK: if.end: 1592; CHECK-NEXT: ret i16 31744 1593; CHECK: if.else: 1594; CHECK-NEXT: ret i16 0 1595; 1596 %conv = uitofp i32 %ui to float 1597 %cmp = fcmp olt float %x, %conv 1598 br i1 %cmp, label %if.else, label %if.end 1599 1600if.end: 1601 %cast = bitcast float %conv to i32 1602 %shr = lshr i32 %cast, 16 1603 %trunc = trunc i32 %shr to i16 1604 %and = and i16 %trunc, -32768 1605 %or = or disjoint i16 %and, 31744 1606 ret i16 %or 1607 1608if.else: 1609 ret i16 0 1610} 1611 1612; TODO: %cmp always evaluates to false 1613 1614define i1 @test_simplify_icmp2(double %x) { 1615; CHECK-LABEL: @test_simplify_icmp2( 1616; CHECK-NEXT: [[ABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) 1617; CHECK-NEXT: [[COND:%.*]] = fcmp oeq double [[ABS]], 0x7FF0000000000000 1618; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1619; CHECK: if.then: 1620; CHECK-NEXT: [[CAST:%.*]] = bitcast double [[X]] to i64 1621; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CAST]], 3458764513820540928 1622; CHECK-NEXT: ret i1 [[CMP]] 1623; CHECK: if.else: 1624; CHECK-NEXT: ret i1 false 1625; 1626 %abs = tail call double @llvm.fabs.f64(double %x) 1627 %cond = fcmp oeq double %abs, 0x7FF0000000000000 1628 br i1 %cond, label %if.then, label %if.else 1629 1630if.then: 1631 %cast = bitcast double %x to i64 1632 %cmp = icmp eq i64 %cast, 3458764513820540928 1633 ret i1 %cmp 1634 1635if.else: 1636 ret i1 false 1637} 1638 1639define i32 @test_snan_only(float nofpclass(qnan sub norm zero inf) %x) { 1640; CHECK-LABEL: @test_snan_only( 1641; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 1642; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 1643; CHECK-NEXT: ret i32 [[AND]] 1644; 1645 %y = bitcast float %x to i32 1646 %and = and i32 %y, 4194304 1647 ret i32 %and 1648} 1649 1650define i32 @test_qnan_only(float nofpclass(snan sub norm zero inf) %x) { 1651; CHECK-LABEL: @test_qnan_only( 1652; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 1653; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 1654; CHECK-NEXT: ret i32 [[AND]] 1655; 1656 %y = bitcast float %x to i32 1657 %and = and i32 %y, 4194304 1658 ret i32 %and 1659} 1660 1661; Make sure that we don't crash when the use of x is unreachable. 1662define i64 @pr92084(double %x) { 1663; CHECK-LABEL: @pr92084( 1664; CHECK-NEXT: [[CMP:%.*]] = fcmp uno double [[X:%.*]], 0.000000e+00 1665; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]] 1666; CHECK: if.then1: 1667; CHECK-NEXT: br i1 true, label [[IF_ELSE]], label [[IF_THEN2:%.*]] 1668; CHECK: if.then2: 1669; CHECK-NEXT: ret i64 poison 1670; CHECK: if.else: 1671; CHECK-NEXT: ret i64 0 1672; 1673 %cmp = fcmp uno double %x, 0.000000e+00 1674 br i1 %cmp, label %if.then1, label %if.else 1675 1676if.then1: 1677 br i1 %cmp, label %if.else, label %if.then2 1678 1679if.then2: 1680 %cast = bitcast double %x to i64 1681 %and = and i64 %cast, 1 1682 ret i64 %and 1683 1684if.else: 1685 ret i64 0 1686} 1687 1688define i32 @test_none(float nofpclass(all) %x) { 1689; CHECK-LABEL: @test_none( 1690; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32 1691; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304 1692; CHECK-NEXT: ret i32 [[AND]] 1693; 1694 %y = bitcast float %x to i32 1695 %and = and i32 %y, 4194304 1696 ret i32 %and 1697} 1698 1699; We cannot make assumptions about the sign of result of sqrt 1700; when the input is a negative value (except for -0). 1701define i1 @pr92217() { 1702; CHECK-LABEL: @pr92217( 1703; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000) 1704; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32 1705; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0 1706; CHECK-NEXT: ret i1 [[CMP]] 1707; 1708 %x = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000) 1709 %y = bitcast float %x to i32 1710 %cmp = icmp slt i32 %y, 0 1711 ret i1 %cmp 1712} 1713 1714define i1 @sqrt_negative_input(float nofpclass(nan zero pnorm psub pinf) %a) { 1715; CHECK-LABEL: @sqrt_negative_input( 1716; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]]) 1717; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32 1718; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0 1719; CHECK-NEXT: ret i1 [[CMP]] 1720; 1721 %x = call float @llvm.sqrt.f32(float %a) 1722 %y = bitcast float %x to i32 1723 %cmp = icmp slt i32 %y, 0 1724 ret i1 %cmp 1725} 1726 1727define i1 @sqrt_negative_input_nnan(float nofpclass(nan zero pnorm psub pinf) %a) { 1728; CHECK-LABEL: @sqrt_negative_input_nnan( 1729; CHECK-NEXT: ret i1 false 1730; 1731 %x = call nnan float @llvm.sqrt.f32(float %a) 1732 %y = bitcast float %x to i32 1733 %cmp = icmp slt i32 %y, 0 1734 ret i1 %cmp 1735} 1736 1737define i8 @test_icmp_add(i8 %n, i8 %n2, i8 %other) { 1738; CHECK-LABEL: @test_icmp_add( 1739; CHECK-NEXT: entry: 1740; CHECK-NEXT: [[N_ADD:%.*]] = add nuw i8 [[N:%.*]], [[N2:%.*]] 1741; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 32 1742; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1743; CHECK: if.then: 1744; CHECK-NEXT: ret i8 0 1745; CHECK: if.else: 1746; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1747; 1748entry: 1749 %n_add = add nuw i8 %n, %n2 1750 %cmp = icmp ult i8 %n_add, 32 1751 br i1 %cmp, label %if.then, label %if.else 1752 1753if.then: 1754 %r = and i8 %n, 32 1755 ret i8 %r 1756 1757if.else: 1758 ret i8 %other 1759} 1760 1761define i8 @test_icmp_add_fail_nsw(i8 %n, i8 %n2, i8 %other) { 1762; CHECK-LABEL: @test_icmp_add_fail_nsw( 1763; CHECK-NEXT: entry: 1764; CHECK-NEXT: [[N_ADD:%.*]] = add nsw i8 [[N:%.*]], [[N2:%.*]] 1765; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 32 1766; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1767; CHECK: if.then: 1768; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 1769; CHECK-NEXT: ret i8 [[R]] 1770; CHECK: if.else: 1771; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1772; 1773entry: 1774 %n_add = add nsw i8 %n, %n2 1775 %cmp = icmp ult i8 %n_add, 32 1776 br i1 %cmp, label %if.then, label %if.else 1777 1778if.then: 1779 %r = and i8 %n, 32 1780 ret i8 %r 1781 1782if.else: 1783 ret i8 %other 1784} 1785 1786define i8 @test_icmp_add2(i8 %n, i8 %n2, i8 %other) { 1787; CHECK-LABEL: @test_icmp_add2( 1788; CHECK-NEXT: entry: 1789; CHECK-NEXT: [[N_ADD:%.*]] = add nuw nsw i8 [[N:%.*]], [[N2:%.*]] 1790; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_ADD]], 14 1791; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1792; CHECK: if.then: 1793; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1794; CHECK: if.else: 1795; CHECK-NEXT: ret i8 0 1796; 1797entry: 1798 %n_add = add nsw nuw i8 %n, %n2 1799 %cmp = icmp uge i8 %n_add, 15 1800 br i1 %cmp, label %if.then, label %if.else 1801 1802if.then: 1803 ret i8 %other 1804if.else: 1805 %r = and i8 %n, 32 1806 ret i8 %r 1807 1808} 1809 1810define i8 @test_icmp_add_fail_bad_range(i8 %n, i8 %n2, i8 %other) { 1811; CHECK-LABEL: @test_icmp_add_fail_bad_range( 1812; CHECK-NEXT: entry: 1813; CHECK-NEXT: [[N_ADD:%.*]] = add nuw i8 [[N:%.*]], [[N2:%.*]] 1814; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 33 1815; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1816; CHECK: if.then: 1817; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 1818; CHECK-NEXT: ret i8 [[R]] 1819; CHECK: if.else: 1820; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1821; 1822entry: 1823 %n_add = add nuw i8 %n, %n2 1824 %cmp = icmp ule i8 %n_add, 32 1825 br i1 %cmp, label %if.then, label %if.else 1826 1827if.then: 1828 %r = and i8 %n, 32 1829 ret i8 %r 1830 1831if.else: 1832 ret i8 %other 1833} 1834 1835define i8 @test_icmp_add_fail_bad_pred(i8 %n, i8 %n2, i8 %other) { 1836; CHECK-LABEL: @test_icmp_add_fail_bad_pred( 1837; CHECK-NEXT: entry: 1838; CHECK-NEXT: [[N_ADD:%.*]] = add nuw i8 [[N:%.*]], [[N2:%.*]] 1839; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_ADD]], 32 1840; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1841; CHECK: if.then: 1842; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 1843; CHECK-NEXT: ret i8 [[R]] 1844; CHECK: if.else: 1845; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1846; 1847entry: 1848 %n_add = add nuw i8 %n, %n2 1849 %cmp = icmp ugt i8 %n_add, 32 1850 br i1 %cmp, label %if.then, label %if.else 1851 1852if.then: 1853 %r = and i8 %n, 32 1854 ret i8 %r 1855 1856if.else: 1857 ret i8 %other 1858} 1859 1860define i8 @test_icmp_sub(i8 %n, i8 %n2, i8 %other) { 1861; CHECK-LABEL: @test_icmp_sub( 1862; CHECK-NEXT: entry: 1863; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]] 1864; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_SUB]], -33 1865; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1866; CHECK: if.then: 1867; CHECK-NEXT: ret i8 32 1868; CHECK: if.else: 1869; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1870; 1871entry: 1872 %n_sub = sub nuw i8 %n, %n2 1873 %cmp = icmp ugt i8 %n_sub, 223 1874 br i1 %cmp, label %if.then, label %if.else 1875 1876if.then: 1877 %r = and i8 %n, 32 1878 ret i8 %r 1879 1880if.else: 1881 ret i8 %other 1882} 1883 1884define i8 @test_icmp_sub_fail_wrong_arg(i8 %n, i8 %n2, i8 %other) { 1885; CHECK-LABEL: @test_icmp_sub_fail_wrong_arg( 1886; CHECK-NEXT: entry: 1887; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]] 1888; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_SUB]], -33 1889; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1890; CHECK: if.then: 1891; CHECK-NEXT: [[R:%.*]] = and i8 [[N2]], 32 1892; CHECK-NEXT: ret i8 [[R]] 1893; CHECK: if.else: 1894; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1895; 1896entry: 1897 %n_sub = sub nuw i8 %n, %n2 1898 %cmp = icmp ugt i8 %n_sub, 223 1899 br i1 %cmp, label %if.then, label %if.else 1900 1901if.then: 1902 %r = and i8 %n2, 32 1903 ret i8 %r 1904 1905if.else: 1906 ret i8 %other 1907} 1908 1909define i8 @test_icmp_sub2(i8 %n, i8 %n2, i8 %other) { 1910; CHECK-LABEL: @test_icmp_sub2( 1911; CHECK-NEXT: entry: 1912; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]] 1913; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_SUB]], -31 1914; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1915; CHECK: if.then: 1916; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1917; CHECK: if.else: 1918; CHECK-NEXT: ret i8 32 1919; 1920entry: 1921 %n_sub = sub nuw i8 %n, %n2 1922 %cmp = icmp ule i8 %n_sub, 224 1923 br i1 %cmp, label %if.then, label %if.else 1924 1925if.then: 1926 ret i8 %other 1927if.else: 1928 %r = and i8 %n, 32 1929 ret i8 %r 1930 1931} 1932 1933define i8 @test_icmp_sub2_fail_nsw(i8 %n, i8 %n2, i8 %other) { 1934; CHECK-LABEL: @test_icmp_sub2_fail_nsw( 1935; CHECK-NEXT: entry: 1936; CHECK-NEXT: [[N_SUB:%.*]] = sub nsw i8 [[N:%.*]], [[N2:%.*]] 1937; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_SUB]], -31 1938; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1939; CHECK: if.then: 1940; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1941; CHECK: if.else: 1942; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 1943; CHECK-NEXT: ret i8 [[R]] 1944; 1945entry: 1946 %n_sub = sub nsw i8 %n, %n2 1947 %cmp = icmp ule i8 %n_sub, 224 1948 br i1 %cmp, label %if.then, label %if.else 1949 1950if.then: 1951 ret i8 %other 1952if.else: 1953 %r = and i8 %n, 32 1954 ret i8 %r 1955 1956} 1957 1958 1959define i8 @test_icmp_sub_fail_bad_range(i8 %n, i8 %n2, i8 %other) { 1960; CHECK-LABEL: @test_icmp_sub_fail_bad_range( 1961; CHECK-NEXT: entry: 1962; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]] 1963; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_SUB]], -34 1964; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1965; CHECK: if.then: 1966; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 1967; CHECK-NEXT: ret i8 [[R]] 1968; CHECK: if.else: 1969; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1970; 1971entry: 1972 %n_sub = sub nuw i8 %n, %n2 1973 %cmp = icmp uge i8 %n_sub, 223 1974 br i1 %cmp, label %if.then, label %if.else 1975 1976if.then: 1977 %r = and i8 %n, 32 1978 ret i8 %r 1979 1980if.else: 1981 ret i8 %other 1982} 1983 1984define i8 @test_icmp_sub_fail_bad_pred(i8 %n, i8 %n2, i8 %other) { 1985; CHECK-LABEL: @test_icmp_sub_fail_bad_pred( 1986; CHECK-NEXT: entry: 1987; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]] 1988; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[N_SUB]], 31 1989; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1990; CHECK: if.then: 1991; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32 1992; CHECK-NEXT: ret i8 [[R]] 1993; CHECK: if.else: 1994; CHECK-NEXT: ret i8 [[OTHER:%.*]] 1995; 1996entry: 1997 %n_sub = sub nuw i8 %n, %n2 1998 %cmp = icmp sge i8 %n_sub, 32 1999 br i1 %cmp, label %if.then, label %if.else 2000 2001if.then: 2002 %r = and i8 %n, 32 2003 ret i8 %r 2004 2005if.else: 2006 ret i8 %other 2007} 2008 2009define i8 @simplifydemanded_context(i8 %x, i8 %y) { 2010; CHECK-LABEL: @simplifydemanded_context( 2011; CHECK-NEXT: call void @dummy() 2012; CHECK-NEXT: [[X_LOBITS:%.*]] = and i8 [[X:%.*]], 3 2013; CHECK-NEXT: [[PRECOND:%.*]] = icmp eq i8 [[X_LOBITS]], 0 2014; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) 2015; CHECK-NEXT: ret i8 0 2016; 2017 %and1 = and i8 %x, 1 2018 call void @dummy() ; may unwind 2019 %x.lobits = and i8 %x, 3 2020 %precond = icmp eq i8 %x.lobits, 0 2021 call void @llvm.assume(i1 %precond) 2022 %and2 = and i8 %and1, %y 2023 ret i8 %and2 2024} 2025 2026define i16 @pr97330(i1 %c, ptr %p1, ptr %p2) { 2027; CHECK-LABEL: @pr97330( 2028; CHECK-NEXT: entry: 2029; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[IF:%.*]] 2030; CHECK: if: 2031; CHECK-NEXT: unreachable 2032; CHECK: exit: 2033; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P1:%.*]], align 8 2034; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[V]] to i16 2035; CHECK-NEXT: ret i16 [[CONV]] 2036; 2037entry: 2038 %v = load i64, ptr %p1, align 8 2039 %conv = trunc i64 %v to i16 2040 br i1 %c, label %exit, label %if 2041 2042if: 2043 %cmp = icmp ne i16 %conv, 1 2044 %conv2 = zext i1 %cmp to i32 2045 store i32 %conv2, ptr %p2, align 4 2046 %cmp2 = icmp eq i64 %v, 1 2047 call void @llvm.assume(i1 %cmp2) 2048 unreachable 2049 2050exit: 2051 ret i16 %conv 2052} 2053 2054define i1 @mul_nuw_nsw_nonneg_const(i8 %x) { 2055; CHECK-LABEL: @mul_nuw_nsw_nonneg_const( 2056; CHECK-NEXT: ret i1 true 2057; 2058 %mul = mul nuw nsw i8 %x, 3 2059 %cmp = icmp sgt i8 %mul, -1 2060 ret i1 %cmp 2061} 2062 2063define i1 @mul_nuw_nsw_nonneg_const_missing_nuw(i8 %x) { 2064; CHECK-LABEL: @mul_nuw_nsw_nonneg_const_missing_nuw( 2065; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1 2066; CHECK-NEXT: ret i1 [[CMP]] 2067; 2068 %mul = mul nsw i8 %x, 3 2069 %cmp = icmp sgt i8 %mul, -1 2070 ret i1 %cmp 2071} 2072 2073define i1 @mul_nuw_nsw_nonneg_const_missing_nsw(i8 %x) { 2074; CHECK-LABEL: @mul_nuw_nsw_nonneg_const_missing_nsw( 2075; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[X:%.*]], 3 2076; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[MUL]], -1 2077; CHECK-NEXT: ret i1 [[CMP]] 2078; 2079 %mul = mul nuw i8 %x, 3 2080 %cmp = icmp sgt i8 %mul, -1 2081 ret i1 %cmp 2082} 2083 2084define i1 @mul_nuw_nsw_nonneg_can_be_one(i8 %x, i8 %y) { 2085; CHECK-LABEL: @mul_nuw_nsw_nonneg_can_be_one( 2086; CHECK-NEXT: [[Y_NNEG:%.*]] = and i8 [[Y:%.*]], 127 2087; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y_NNEG]] 2088; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[MUL]], -1 2089; CHECK-NEXT: ret i1 [[CMP]] 2090; 2091 %y.nneg = and i8 %y, 127 2092 %mul = mul nuw nsw i8 %x, %y.nneg 2093 %cmp = icmp sgt i8 %mul, -1 2094 ret i1 %cmp 2095} 2096 2097define i1 @mul_nuw_nsw_nonneg_cant_be_one(i8 %x, i8 %y) { 2098; CHECK-LABEL: @mul_nuw_nsw_nonneg_cant_be_one( 2099; CHECK-NEXT: ret i1 true 2100; 2101 %y.nneg = and i8 %y, 127 2102 %y.nneg.not.one = or i8 %y.nneg, 2 2103 %mul = mul nuw nsw i8 %x, %y.nneg.not.one 2104 %cmp = icmp sgt i8 %mul, -1 2105 ret i1 %cmp 2106} 2107 2108define i1 @mul_nuw_nsw_nonneg_cant_be_one_commuted(i8 %x, i8 %y) { 2109; CHECK-LABEL: @mul_nuw_nsw_nonneg_cant_be_one_commuted( 2110; CHECK-NEXT: ret i1 true 2111; 2112 %y.nneg = and i8 %y, 127 2113 %y.nneg.not.one = or i8 %y.nneg, 2 2114 %mul = mul nuw nsw i8 %y.nneg.not.one, %x 2115 %cmp = icmp sgt i8 %mul, -1 2116 ret i1 %cmp 2117} 2118 2119declare void @dummy() 2120declare void @use(i1) 2121declare void @sink(i8) 2122