1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 5 6define i32 @test1(i32 %X) { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31 9; CHECK-NEXT: ret i32 [[X_LOBIT]] 10; 11 %a = icmp slt i32 %X, 0 12 %b = zext i1 %a to i32 13 ret i32 %b 14} 15 16define <2 x i32> @test1vec(<2 x i32> %X) { 17; CHECK-LABEL: @test1vec( 18; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 31> 19; CHECK-NEXT: ret <2 x i32> [[X_LOBIT]] 20; 21 %a = icmp slt <2 x i32> %X, zeroinitializer 22 %b = zext <2 x i1> %a to <2 x i32> 23 ret <2 x i32> %b 24} 25 26define i32 @test2(i32 %X) { 27; CHECK-LABEL: @test2( 28; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31 29; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = xor i32 [[X_LOBIT]], 1 30; CHECK-NEXT: ret i32 [[X_LOBIT_NOT]] 31; 32 %a = icmp ult i32 %X, -2147483648 33 %b = zext i1 %a to i32 34 ret i32 %b 35} 36 37define <2 x i32> @test2vec(<2 x i32> %X) { 38; CHECK-LABEL: @test2vec( 39; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 31> 40; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = xor <2 x i32> [[X_LOBIT]], <i32 1, i32 1> 41; CHECK-NEXT: ret <2 x i32> [[X_LOBIT_NOT]] 42; 43 %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648> 44 %b = zext <2 x i1> %a to <2 x i32> 45 ret <2 x i32> %b 46} 47 48define i32 @test3(i32 %X) { 49; CHECK-LABEL: @test3( 50; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31 51; CHECK-NEXT: ret i32 [[X_LOBIT]] 52; 53 %a = icmp slt i32 %X, 0 54 %b = sext i1 %a to i32 55 ret i32 %b 56} 57 58define i32 @test4(i32 %X) { 59; CHECK-LABEL: @test4( 60; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31 61; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = xor i32 [[X_LOBIT]], -1 62; CHECK-NEXT: ret i32 [[X_LOBIT_NOT]] 63; 64 %a = icmp ult i32 %X, -2147483648 65 %b = sext i1 %a to i32 66 ret i32 %b 67} 68 69; PR4837 70define <2 x i1> @test5_eq(<2 x i64> %x) { 71; CHECK-LABEL: @test5_eq( 72; CHECK-NEXT: ret <2 x i1> undef 73; 74 %V = icmp eq <2 x i64> %x, undef 75 ret <2 x i1> %V 76} 77define <2 x i1> @test5_ne(<2 x i64> %x) { 78; CHECK-LABEL: @test5_ne( 79; CHECK-NEXT: ret <2 x i1> undef 80; 81 %V = icmp ne <2 x i64> %x, undef 82 ret <2 x i1> %V 83} 84define <2 x i1> @test5_ugt(<2 x i64> %x) { 85; CHECK-LABEL: @test5_ugt( 86; CHECK-NEXT: ret <2 x i1> zeroinitializer 87; 88 %V = icmp ugt <2 x i64> %x, undef 89 ret <2 x i1> %V 90} 91define <2 x i1> @test5_zero() { 92; CHECK-LABEL: @test5_zero( 93; CHECK-NEXT: ret <2 x i1> undef 94; 95 %V = icmp eq <2 x i64> zeroinitializer, undef 96 ret <2 x i1> %V 97} 98 99define i32 @test6(i32 %a, i32 %b) { 100; CHECK-LABEL: @test6( 101; CHECK-NEXT: [[E:%.*]] = ashr i32 [[A:%.*]], 31 102; CHECK-NEXT: [[F:%.*]] = and i32 [[E]], [[B:%.*]] 103; CHECK-NEXT: ret i32 [[F]] 104; 105 %c = icmp sle i32 %a, -1 106 %d = zext i1 %c to i32 107 %e = sub i32 0, %d 108 %f = and i32 %e, %b 109 ret i32 %f 110} 111 112 113define i1 @test7(i32 %x) { 114; CHECK-LABEL: @test7( 115; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0 116; CHECK-NEXT: ret i1 [[B]] 117; 118 %a = add i32 %x, -1 119 %b = icmp ult i32 %a, %x 120 ret i1 %b 121} 122 123define <2 x i1> @test7_vec(<2 x i32> %x) { 124; CHECK-LABEL: @test7_vec( 125; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 126; CHECK-NEXT: ret <2 x i1> [[B]] 127; 128 %a = add <2 x i32> %x, <i32 -1, i32 -1> 129 %b = icmp ult <2 x i32> %a, %x 130 ret <2 x i1> %b 131} 132 133define i1 @test8(i32 %x) { 134; CHECK-LABEL: @test8( 135; CHECK-NEXT: ret i1 false 136; 137 %a = add i32 %x, -1 138 %b = icmp eq i32 %a, %x 139 ret i1 %b 140} 141 142define <2 x i1> @test8_vec(<2 x i32> %x) { 143; CHECK-LABEL: @test8_vec( 144; CHECK-NEXT: ret <2 x i1> zeroinitializer 145; 146 %a = add <2 x i32> %x, <i32 -1, i32 -1> 147 %b = icmp eq <2 x i32> %a, %x 148 ret <2 x i1> %b 149} 150 151define i1 @test9(i32 %x) { 152; CHECK-LABEL: @test9( 153; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 [[X:%.*]], 1 154; CHECK-NEXT: ret i1 [[B]] 155; 156 %a = add i32 %x, -2 157 %b = icmp ugt i32 %x, %a 158 ret i1 %b 159} 160 161define <2 x i1> @test9_vec(<2 x i32> %x) { 162; CHECK-LABEL: @test9_vec( 163; CHECK-NEXT: [[B:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 1, i32 1> 164; CHECK-NEXT: ret <2 x i1> [[B]] 165; 166 %a = add <2 x i32> %x, <i32 -2, i32 -2> 167 %b = icmp ugt <2 x i32> %x, %a 168 ret <2 x i1> %b 169} 170 171define i1 @test9b(i32 %x) { 172; CHECK-LABEL: @test9b( 173; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 2 174; CHECK-NEXT: ret i1 [[B]] 175; 176 %a = add i32 %x, -2 177 %b = icmp ugt i32 %a, %x 178 ret i1 %b 179} 180 181define <2 x i1> @test9b_vec(<2 x i32> %x) { 182; CHECK-LABEL: @test9b_vec( 183; CHECK-NEXT: [[B:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 2, i32 2> 184; CHECK-NEXT: ret <2 x i1> [[B]] 185; 186 %a = add <2 x i32> %x, <i32 -2, i32 -2> 187 %b = icmp ugt <2 x i32> %a, %x 188 ret <2 x i1> %b 189} 190 191define i1 @test10(i32 %x) { 192; CHECK-LABEL: @test10( 193; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], -2147483648 194; CHECK-NEXT: ret i1 [[B]] 195; 196 %a = add i32 %x, -1 197 %b = icmp slt i32 %a, %x 198 ret i1 %b 199} 200 201define <2 x i1> @test10_vec(<2 x i32> %x) { 202; CHECK-LABEL: @test10_vec( 203; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648> 204; CHECK-NEXT: ret <2 x i1> [[B]] 205; 206 %a = add <2 x i32> %x, <i32 -1, i32 -1> 207 %b = icmp slt <2 x i32> %a, %x 208 ret <2 x i1> %b 209} 210 211define i1 @test10b(i32 %x) { 212; CHECK-LABEL: @test10b( 213; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X:%.*]], -2147483648 214; CHECK-NEXT: ret i1 [[B]] 215; 216 %a = add i32 %x, -1 217 %b = icmp sgt i32 %a, %x 218 ret i1 %b 219} 220 221define <2 x i1> @test10b_vec(<2 x i32> %x) { 222; CHECK-LABEL: @test10b_vec( 223; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648> 224; CHECK-NEXT: ret <2 x i1> [[B]] 225; 226 %a = add <2 x i32> %x, <i32 -1, i32 -1> 227 %b = icmp sgt <2 x i32> %a, %x 228 ret <2 x i1> %b 229} 230 231define i1 @test11(i32 %x) { 232; CHECK-LABEL: @test11( 233; CHECK-NEXT: ret i1 true 234; 235 %a = add nsw i32 %x, 8 236 %b = icmp slt i32 %x, %a 237 ret i1 %b 238} 239 240define <2 x i1> @test11_vec(<2 x i32> %x) { 241; CHECK-LABEL: @test11_vec( 242; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 243; 244 %a = add nsw <2 x i32> %x, <i32 8, i32 8> 245 %b = icmp slt <2 x i32> %x, %a 246 ret <2 x i1> %b 247} 248 249; PR6195 250define i1 @test12(i1 %A) { 251; CHECK-LABEL: @test12( 252; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true 253; CHECK-NEXT: ret i1 [[NOT_A]] 254; 255 %S = select i1 %A, i64 -4294967295, i64 8589934591 256 %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S 257 ret i1 %B 258} 259 260; PR6481 261define i1 @test13(i8 %X) { 262; CHECK-LABEL: @test13( 263; CHECK-NEXT: ret i1 false 264; 265 %cmp = icmp slt i8 undef, %X 266 ret i1 %cmp 267} 268 269define i1 @test14(i8 %X) { 270; CHECK-LABEL: @test14( 271; CHECK-NEXT: ret i1 false 272; 273 %cmp = icmp slt i8 undef, -128 274 ret i1 %cmp 275} 276 277define i1 @test15() { 278; CHECK-LABEL: @test15( 279; CHECK-NEXT: ret i1 undef 280; 281 %cmp = icmp eq i8 undef, -128 282 ret i1 %cmp 283} 284 285define i1 @test16() { 286; CHECK-LABEL: @test16( 287; CHECK-NEXT: ret i1 undef 288; 289 %cmp = icmp ne i8 undef, -128 290 ret i1 %cmp 291} 292 293define i1 @test17(i32 %x) { 294; CHECK-LABEL: @test17( 295; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3 296; CHECK-NEXT: ret i1 [[CMP]] 297; 298 %shl = shl i32 1, %x 299 %and = and i32 %shl, 8 300 %cmp = icmp eq i32 %and, 0 301 ret i1 %cmp 302} 303 304define <2 x i1> @test17vec(<2 x i32> %x) { 305; CHECK-LABEL: @test17vec( 306; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3> 307; CHECK-NEXT: ret <2 x i1> [[CMP]] 308; 309 %shl = shl <2 x i32> <i32 1, i32 1>, %x 310 %and = and <2 x i32> %shl, <i32 8, i32 8> 311 %cmp = icmp eq <2 x i32> %and, zeroinitializer 312 ret <2 x i1> %cmp 313} 314 315define i1 @test17a(i32 %x) { 316; CHECK-LABEL: @test17a( 317; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2 318; CHECK-NEXT: ret i1 [[CMP]] 319; 320 %shl = shl i32 1, %x 321 %and = and i32 %shl, 7 322 %cmp = icmp eq i32 %and, 0 323 ret i1 %cmp 324} 325 326define <2 x i1> @test17a_vec(<2 x i32> %x) { 327; CHECK-LABEL: @test17a_vec( 328; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 2, i32 2> 329; CHECK-NEXT: ret <2 x i1> [[CMP]] 330; 331 %shl = shl <2 x i32> <i32 1, i32 1>, %x 332 %and = and <2 x i32> %shl, <i32 7, i32 7> 333 %cmp = icmp eq <2 x i32> %and, zeroinitializer 334 ret <2 x i1> %cmp 335} 336 337define i1 @test18_eq(i32 %x) { 338; CHECK-LABEL: @test18_eq( 339; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3 340; CHECK-NEXT: ret i1 [[CMP]] 341; 342 %sh = lshr i32 8, %x 343 %and = and i32 %sh, 1 344 %cmp = icmp eq i32 %and, 0 345 ret i1 %cmp 346} 347 348define <2 x i1> @test18_eq_vec(<2 x i32> %x) { 349; CHECK-LABEL: @test18_eq_vec( 350; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3> 351; CHECK-NEXT: ret <2 x i1> [[CMP]] 352; 353 %sh = lshr <2 x i32> <i32 8, i32 8>, %x 354 %and = and <2 x i32> %sh, <i32 1, i32 1> 355 %cmp = icmp eq <2 x i32> %and, zeroinitializer 356 ret <2 x i1> %cmp 357} 358 359define i1 @test18_ne(i32 %x) { 360; CHECK-LABEL: @test18_ne( 361; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3 362; CHECK-NEXT: ret i1 [[CMP]] 363; 364 %sh = lshr i32 8, %x 365 %and = and i32 %sh, 1 366 %cmp = icmp ne i32 %and, 0 367 ret i1 %cmp 368} 369 370define <2 x i1> @test18_ne_vec(<2 x i32> %x) { 371; CHECK-LABEL: @test18_ne_vec( 372; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3> 373; CHECK-NEXT: ret <2 x i1> [[CMP]] 374; 375 %sh = lshr <2 x i32> <i32 8, i32 8>, %x 376 %and = and <2 x i32> %sh, <i32 1, i32 1> 377 %cmp = icmp ne <2 x i32> %and, zeroinitializer 378 ret <2 x i1> %cmp 379} 380 381define i1 @test19(i32 %x) { 382; CHECK-LABEL: @test19( 383; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3 384; CHECK-NEXT: ret i1 [[CMP]] 385; 386 %shl = shl i32 1, %x 387 %and = and i32 %shl, 8 388 %cmp = icmp eq i32 %and, 8 389 ret i1 %cmp 390} 391 392define <2 x i1> @test19vec(<2 x i32> %x) { 393; CHECK-LABEL: @test19vec( 394; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3> 395; CHECK-NEXT: ret <2 x i1> [[CMP]] 396; 397 %shl = shl <2 x i32> <i32 1, i32 1>, %x 398 %and = and <2 x i32> %shl, <i32 8, i32 8> 399 %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8> 400 ret <2 x i1> %cmp 401} 402 403define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) { 404; CHECK-LABEL: @cmp_and_signbit_vec( 405; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i3> [[X:%.*]], zeroinitializer 406; CHECK-NEXT: ret <2 x i1> [[CMP]] 407; 408 %and = and <2 x i3> %x, <i3 4, i3 4> 409 %cmp = icmp ne <2 x i3> %and, zeroinitializer 410 ret <2 x i1> %cmp 411} 412 413define i1 @test20(i32 %x) { 414; CHECK-LABEL: @test20( 415; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3 416; CHECK-NEXT: ret i1 [[CMP]] 417; 418 %shl = shl i32 1, %x 419 %and = and i32 %shl, 8 420 %cmp = icmp ne i32 %and, 0 421 ret i1 %cmp 422} 423 424define <2 x i1> @test20vec(<2 x i32> %x) { 425; CHECK-LABEL: @test20vec( 426; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3> 427; CHECK-NEXT: ret <2 x i1> [[CMP]] 428; 429 %shl = shl <2 x i32> <i32 1, i32 1>, %x 430 %and = and <2 x i32> %shl, <i32 8, i32 8> 431 %cmp = icmp ne <2 x i32> %and, zeroinitializer 432 ret <2 x i1> %cmp 433} 434 435define i1 @test20a(i32 %x) { 436; CHECK-LABEL: @test20a( 437; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3 438; CHECK-NEXT: ret i1 [[CMP]] 439; 440 %shl = shl i32 1, %x 441 %and = and i32 %shl, 7 442 %cmp = icmp ne i32 %and, 0 443 ret i1 %cmp 444} 445 446define <2 x i1> @test20a_vec(<2 x i32> %x) { 447; CHECK-LABEL: @test20a_vec( 448; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 3, i32 3> 449; CHECK-NEXT: ret <2 x i1> [[CMP]] 450; 451 %shl = shl <2 x i32> <i32 1, i32 1>, %x 452 %and = and <2 x i32> %shl, <i32 7, i32 7> 453 %cmp = icmp ne <2 x i32> %and, zeroinitializer 454 ret <2 x i1> %cmp 455} 456 457define i1 @test21(i8 %x, i8 %y) { 458; CHECK-LABEL: @test21( 459; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3 460; CHECK-NEXT: ret i1 [[B]] 461; 462 %A = or i8 %x, 1 463 %B = icmp ugt i8 %A, 3 464 ret i1 %B 465} 466 467define i1 @test22(i8 %x, i8 %y) { 468; CHECK-LABEL: @test22( 469; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 4 470; CHECK-NEXT: ret i1 [[B]] 471; 472 %A = or i8 %x, 1 473 %B = icmp ult i8 %A, 4 474 ret i1 %B 475} 476 477; PR2740 478define i1 @test23(i32 %x) { 479; CHECK-LABEL: @test23( 480; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[X:%.*]], 1328634634 481; CHECK-NEXT: ret i1 [[I4]] 482; 483 %i3 = sdiv i32 %x, -1328634635 484 %i4 = icmp eq i32 %i3, -1 485 ret i1 %i4 486} 487 488define <2 x i1> @test23vec(<2 x i32> %x) { 489; CHECK-LABEL: @test23vec( 490; CHECK-NEXT: [[I4:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 1328634634, i32 1328634634> 491; CHECK-NEXT: ret <2 x i1> [[I4]] 492; 493 %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635> 494 %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1> 495 ret <2 x i1> %i4 496} 497 498@X = global [1000 x i32] zeroinitializer 499 500; PR8882 501define i1 @test24(i64 %i) { 502; CHECK-LABEL: @test24( 503; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[I:%.*]], 1000 504; CHECK-NEXT: ret i1 [[CMP]] 505; 506 %p1 = getelementptr inbounds i32, i32* getelementptr inbounds ([1000 x i32], [1000 x i32]* @X, i64 0, i64 0), i64 %i 507 %cmp = icmp eq i32* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32]* @X, i64 1, i64 0) 508 ret i1 %cmp 509} 510 511; Note: offs can be negative, LLVM used to make an incorrect assumption that 512; unsigned overflow does not happen during offset computation 513define i1 @test24_neg_offs(i32* %p, i64 %offs) { 514; CHECK-LABEL: @test24_neg_offs( 515; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OFFS:%.*]], -2 516; CHECK-NEXT: ret i1 [[CMP]] 517; 518 %p1 = getelementptr inbounds i32, i32* %p, i64 %offs 519 %conv1 = ptrtoint i32* %p to i64 520 %conv2 = ptrtoint i32* %p1 to i64 521 %delta = sub i64 %conv1, %conv2 522 %cmp = icmp eq i64 %delta, 8 523 ret i1 %cmp 524} 525 526@X_as1 = addrspace(1) global [1000 x i32] zeroinitializer 527 528define i1 @test24_as1(i64 %i) { 529; CHECK-LABEL: @test24_as1( 530; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16 531; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 1000 532; CHECK-NEXT: ret i1 [[CMP]] 533; 534 %p1 = getelementptr inbounds i32, i32 addrspace(1)* getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 0, i64 0), i64 %i 535 %cmp = icmp eq i32 addrspace(1)* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 1, i64 0) 536 ret i1 %cmp 537} 538 539; X - Z > Y - Z -> X > Y if there is no overflow. 540define i1 @test27(i32 %x, i32 %y, i32 %z) { 541; CHECK-LABEL: @test27( 542; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 543; CHECK-NEXT: ret i1 [[C]] 544; 545 %lhs = sub nsw i32 %x, %z 546 %rhs = sub nsw i32 %y, %z 547 %c = icmp sgt i32 %lhs, %rhs 548 ret i1 %c 549} 550 551define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) { 552; CHECK-LABEL: @test27_extra_uses( 553; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]] 554; CHECK-NEXT: call void @foo(i32 [[LHS]]) 555; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]] 556; CHECK-NEXT: call void @foo(i32 [[RHS]]) 557; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X]], [[Y]] 558; CHECK-NEXT: ret i1 [[C]] 559; 560 %lhs = sub nsw i32 %x, %z 561 call void @foo(i32 %lhs) 562 %rhs = sub nsw i32 %y, %z 563 call void @foo(i32 %rhs) 564 %c = icmp sgt i32 %lhs, %rhs 565 ret i1 %c 566} 567 568; X - Z > Y - Z -> X > Y if there is no overflow. 569define i1 @test28(i32 %x, i32 %y, i32 %z) { 570; CHECK-LABEL: @test28( 571; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 572; CHECK-NEXT: ret i1 [[C]] 573; 574 %lhs = sub nuw i32 %x, %z 575 %rhs = sub nuw i32 %y, %z 576 %c = icmp ugt i32 %lhs, %rhs 577 ret i1 %c 578} 579 580define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) { 581; CHECK-LABEL: @test28_extra_uses( 582; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]] 583; CHECK-NEXT: call void @foo(i32 [[LHS]]) 584; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]] 585; CHECK-NEXT: call void @foo(i32 [[RHS]]) 586; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]] 587; CHECK-NEXT: ret i1 [[C]] 588; 589 %lhs = sub nuw i32 %x, %z 590 call void @foo(i32 %lhs) 591 %rhs = sub nuw i32 %y, %z 592 call void @foo(i32 %rhs) 593 %c = icmp ugt i32 %lhs, %rhs 594 ret i1 %c 595} 596 597; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969 598 599define i1 @ugt_sub(i32 %xsrc, i32 %y) { 600; CHECK-LABEL: @ugt_sub( 601; CHECK-NEXT: [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42 602; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]] 603; CHECK-NEXT: ret i1 [[CMP]] 604; 605 %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization 606 %sub = sub i32 %x, %y 607 %cmp = icmp ugt i32 %sub, %x 608 ret i1 %cmp 609} 610 611; Swap operands and predicate. Try a vector type to verify that works too. 612 613define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) { 614; CHECK-LABEL: @ult_sub( 615; CHECK-NEXT: [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42> 616; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]] 617; CHECK-NEXT: ret <2 x i1> [[CMP]] 618; 619 %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization 620 %sub = sub <2 x i8> %x, %y 621 %cmp = icmp ult <2 x i8> %x, %sub 622 ret <2 x i1> %cmp 623} 624 625; X - Y > X -> 0 > Y if there is no overflow. 626define i1 @test33(i32 %x, i32 %y) { 627; CHECK-LABEL: @test33( 628; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0 629; CHECK-NEXT: ret i1 [[C]] 630; 631 %lhs = sub nsw i32 %x, %y 632 %c = icmp sgt i32 %lhs, %x 633 ret i1 %c 634} 635 636; X - Y > X -> 0 > Y if there is no overflow. 637define i1 @test34(i32 %x, i32 %y) { 638; CHECK-LABEL: @test34( 639; CHECK-NEXT: ret i1 false 640; 641 %lhs = sub nuw i32 %x, %y 642 %c = icmp ugt i32 %lhs, %x 643 ret i1 %c 644} 645 646; X > X - Y -> Y > 0 if there is no overflow. 647define i1 @test35(i32 %x, i32 %y) { 648; CHECK-LABEL: @test35( 649; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0 650; CHECK-NEXT: ret i1 [[C]] 651; 652 %rhs = sub nsw i32 %x, %y 653 %c = icmp sgt i32 %x, %rhs 654 ret i1 %c 655} 656 657; X > X - Y -> Y > 0 if there is no overflow. 658define i1 @test36(i32 %x, i32 %y) { 659; CHECK-LABEL: @test36( 660; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0 661; CHECK-NEXT: ret i1 [[C]] 662; 663 %rhs = sub nuw i32 %x, %y 664 %c = icmp ugt i32 %x, %rhs 665 ret i1 %c 666} 667 668; X - Y > X - Z -> Z > Y if there is no overflow. 669define i1 @test37(i32 %x, i32 %y, i32 %z) { 670; CHECK-LABEL: @test37( 671; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]] 672; CHECK-NEXT: ret i1 [[C]] 673; 674 %lhs = sub nsw i32 %x, %y 675 %rhs = sub nsw i32 %x, %z 676 %c = icmp sgt i32 %lhs, %rhs 677 ret i1 %c 678} 679 680define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) { 681; CHECK-LABEL: @test37_extra_uses( 682; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 683; CHECK-NEXT: call void @foo(i32 [[LHS]]) 684; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]] 685; CHECK-NEXT: call void @foo(i32 [[RHS]]) 686; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]] 687; CHECK-NEXT: ret i1 [[C]] 688; 689 %lhs = sub nsw i32 %x, %y 690 call void @foo(i32 %lhs) 691 %rhs = sub nsw i32 %x, %z 692 call void @foo(i32 %rhs) 693 %c = icmp sgt i32 %lhs, %rhs 694 ret i1 %c 695} 696 697; TODO: Min/max pattern should not prevent the fold. 698 699define i32 @neg_max_s32(i32 %x, i32 %y) { 700; CHECK-LABEL: @neg_max_s32( 701; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]] 702; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C]], i32 [[Y]], i32 [[X]] 703; CHECK-NEXT: ret i32 [[S_V]] 704; 705 %nx = sub nsw i32 0, %x 706 %ny = sub nsw i32 0, %y 707 %c = icmp slt i32 %nx, %ny 708 %s = select i1 %c, i32 %ny, i32 %nx 709 %r = sub nsw i32 0, %s 710 ret i32 %r 711} 712 713define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) { 714; CHECK-LABEL: @neg_max_v4s32( 715; CHECK-NEXT: [[C:%.*]] = icmp sgt <4 x i32> [[Y:%.*]], [[X:%.*]] 716; CHECK-NEXT: [[S_V:%.*]] = select <4 x i1> [[C]], <4 x i32> [[X]], <4 x i32> [[Y]] 717; CHECK-NEXT: ret <4 x i32> [[S_V]] 718; 719 %nx = sub nsw <4 x i32> zeroinitializer, %x 720 %ny = sub nsw <4 x i32> zeroinitializer, %y 721 %c = icmp sgt <4 x i32> %nx, %ny 722 %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny 723 %r = sub <4 x i32> zeroinitializer, %s 724 ret <4 x i32> %r 725} 726 727; X - Y > X - Z -> Z > Y if there is no overflow. 728define i1 @test38(i32 %x, i32 %y, i32 %z) { 729; CHECK-LABEL: @test38( 730; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]] 731; CHECK-NEXT: ret i1 [[C]] 732; 733 %lhs = sub nuw i32 %x, %y 734 %rhs = sub nuw i32 %x, %z 735 %c = icmp ugt i32 %lhs, %rhs 736 ret i1 %c 737} 738 739define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) { 740; CHECK-LABEL: @test38_extra_uses( 741; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]] 742; CHECK-NEXT: call void @foo(i32 [[LHS]]) 743; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]] 744; CHECK-NEXT: call void @foo(i32 [[RHS]]) 745; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]] 746; CHECK-NEXT: ret i1 [[C]] 747; 748 %lhs = sub nuw i32 %x, %y 749 call void @foo(i32 %lhs) 750 %rhs = sub nuw i32 %x, %z 751 call void @foo(i32 %rhs) 752 %c = icmp ugt i32 %lhs, %rhs 753 ret i1 %c 754} 755 756; PR9343 #1 757define i1 @test39(i32 %X, i32 %Y) { 758; CHECK-LABEL: @test39( 759; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X:%.*]], 0 760; CHECK-NEXT: ret i1 [[B]] 761; 762 %A = ashr exact i32 %X, %Y 763 %B = icmp eq i32 %A, 0 764 ret i1 %B 765} 766 767define <2 x i1> @test39vec(<2 x i32> %X, <2 x i32> %Y) { 768; CHECK-LABEL: @test39vec( 769; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer 770; CHECK-NEXT: ret <2 x i1> [[B]] 771; 772 %A = ashr exact <2 x i32> %X, %Y 773 %B = icmp eq <2 x i32> %A, zeroinitializer 774 ret <2 x i1> %B 775} 776 777define i1 @test40(i32 %X, i32 %Y) { 778; CHECK-LABEL: @test40( 779; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0 780; CHECK-NEXT: ret i1 [[B]] 781; 782 %A = lshr exact i32 %X, %Y 783 %B = icmp ne i32 %A, 0 784 ret i1 %B 785} 786 787define <2 x i1> @test40vec(<2 x i32> %X, <2 x i32> %Y) { 788; CHECK-LABEL: @test40vec( 789; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 790; CHECK-NEXT: ret <2 x i1> [[B]] 791; 792 %A = lshr exact <2 x i32> %X, %Y 793 %B = icmp ne <2 x i32> %A, zeroinitializer 794 ret <2 x i1> %B 795} 796 797define i1 @shr_exact(i132 %x) { 798; CHECK-LABEL: @shr_exact( 799; CHECK-NEXT: [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32 800; CHECK-NEXT: ret i1 [[CMP]] 801; 802 %sh = ashr exact i132 %x, 4 803 %cmp = icmp eq i132 %sh, 2 804 ret i1 %cmp 805} 806 807define <2 x i1> @shr_exact_vec(<2 x i132> %x) { 808; CHECK-LABEL: @shr_exact_vec( 809; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], <i132 32, i132 32> 810; CHECK-NEXT: ret <2 x i1> [[CMP]] 811; 812 %sh = lshr exact <2 x i132> %x, <i132 4, i132 4> 813 %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2> 814 ret <2 x i1> %cmp 815} 816 817; PR9343 #3 818define i1 @test41(i32 %X, i32 %Y) { 819; CHECK-LABEL: @test41( 820; CHECK-NEXT: ret i1 true 821; 822 %A = urem i32 %X, %Y 823 %B = icmp ugt i32 %Y, %A 824 ret i1 %B 825} 826 827define i1 @test42(i32 %X, i32 %Y) { 828; CHECK-LABEL: @test42( 829; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1 830; CHECK-NEXT: ret i1 [[B]] 831; 832 %A = srem i32 %X, %Y 833 %B = icmp slt i32 %A, %Y 834 ret i1 %B 835} 836 837define i1 @test43(i32 %X, i32 %Y) { 838; CHECK-LABEL: @test43( 839; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0 840; CHECK-NEXT: ret i1 [[B]] 841; 842 %A = srem i32 %X, %Y 843 %B = icmp slt i32 %Y, %A 844 ret i1 %B 845} 846 847define i1 @test44(i32 %X, i32 %Y) { 848; CHECK-LABEL: @test44( 849; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1 850; CHECK-NEXT: ret i1 [[B]] 851; 852 %A = srem i32 %X, %Y 853 %B = icmp slt i32 %A, %Y 854 ret i1 %B 855} 856 857define i1 @test45(i32 %X, i32 %Y) { 858; CHECK-LABEL: @test45( 859; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0 860; CHECK-NEXT: ret i1 [[B]] 861; 862 %A = srem i32 %X, %Y 863 %B = icmp slt i32 %Y, %A 864 ret i1 %B 865} 866 867; PR9343 #4 868define i1 @test46(i32 %X, i32 %Y, i32 %Z) { 869; CHECK-LABEL: @test46( 870; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 871; CHECK-NEXT: ret i1 [[C]] 872; 873 %A = ashr exact i32 %X, %Z 874 %B = ashr exact i32 %Y, %Z 875 %C = icmp ult i32 %A, %B 876 ret i1 %C 877} 878 879; PR9343 #5 880define i1 @test47(i32 %X, i32 %Y, i32 %Z) { 881; CHECK-LABEL: @test47( 882; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 883; CHECK-NEXT: ret i1 [[C]] 884; 885 %A = ashr exact i32 %X, %Z 886 %B = ashr exact i32 %Y, %Z 887 %C = icmp ugt i32 %A, %B 888 ret i1 %C 889} 890 891; PR9343 #8 892define i1 @test48(i32 %X, i32 %Y, i32 %Z) { 893; CHECK-LABEL: @test48( 894; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 895; CHECK-NEXT: ret i1 [[C]] 896; 897 %A = sdiv exact i32 %X, %Z 898 %B = sdiv exact i32 %Y, %Z 899 %C = icmp eq i32 %A, %B 900 ret i1 %C 901} 902 903; The above transform only works for equality predicates. 904 905define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) { 906; CHECK-LABEL: @PR32949( 907; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]] 908; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]] 909; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]] 910; CHECK-NEXT: ret i1 [[C]] 911; 912 %A = sdiv exact i32 %X, %Z 913 %B = sdiv exact i32 %Y, %Z 914 %C = icmp sgt i32 %A, %B 915 ret i1 %C 916} 917 918; PR8469 919define <2 x i1> @test49(<2 x i32> %tmp3) { 920; CHECK-LABEL: @test49( 921; CHECK-NEXT: entry: 922; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 923; 924entry: 925 %tmp11 = and <2 x i32> %tmp3, <i32 3, i32 3> 926 %cmp = icmp ult <2 x i32> %tmp11, <i32 4, i32 4> 927 ret <2 x i1> %cmp 928} 929 930; PR9343 #7 931define i1 @test50(i16 %X, i32 %Y) { 932; CHECK-LABEL: @test50( 933; CHECK-NEXT: ret i1 true 934; 935 %A = zext i16 %X to i32 936 %B = srem i32 %A, %Y 937 %C = icmp sgt i32 %B, -1 938 ret i1 %C 939} 940 941define i1 @test51(i32 %X, i32 %Y) { 942; CHECK-LABEL: @test51( 943; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], -2147483648 944; CHECK-NEXT: [[B:%.*]] = srem i32 [[A]], [[Y:%.*]] 945; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[B]], -1 946; CHECK-NEXT: ret i1 [[C]] 947; 948 %A = and i32 %X, 2147483648 949 %B = srem i32 %A, %Y 950 %C = icmp sgt i32 %B, -1 951 ret i1 %C 952} 953 954define i1 @test52(i32 %x1) { 955; CHECK-LABEL: @test52( 956; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935 957; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863 958; CHECK-NEXT: ret i1 [[TMP2]] 959; 960 %conv = and i32 %x1, 255 961 %cmp = icmp eq i32 %conv, 127 962 %tmp2 = lshr i32 %x1, 16 963 %tmp3 = trunc i32 %tmp2 to i8 964 %cmp15 = icmp eq i8 %tmp3, 76 965 966 %A = and i1 %cmp, %cmp15 967 ret i1 %A 968} 969 970define i1 @test52b(i128 %x1) { 971; CHECK-LABEL: @test52b( 972; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935 973; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863 974; CHECK-NEXT: ret i1 [[TMP2]] 975; 976 %conv = and i128 %x1, 255 977 %cmp = icmp eq i128 %conv, 127 978 %tmp2 = lshr i128 %x1, 16 979 %tmp3 = trunc i128 %tmp2 to i8 980 %cmp15 = icmp eq i8 %tmp3, 76 981 982 %A = and i1 %cmp, %cmp15 983 ret i1 %A 984} 985 986; PR9838 987define i1 @test53(i32 %a, i32 %b) { 988; CHECK-LABEL: @test53( 989; CHECK-NEXT: [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30 990; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[B:%.*]], 30 991; CHECK-NEXT: [[Z:%.*]] = icmp eq i32 [[X]], [[Y]] 992; CHECK-NEXT: ret i1 [[Z]] 993; 994 %x = sdiv exact i32 %a, 30 995 %y = sdiv i32 %b, 30 996 %z = icmp eq i32 %x, %y 997 ret i1 %z 998} 999 1000define i1 @test54(i8 %a) { 1001; CHECK-LABEL: @test54( 1002; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], -64 1003; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP1]], -128 1004; CHECK-NEXT: ret i1 [[RET]] 1005; 1006 %ext = zext i8 %a to i32 1007 %and = and i32 %ext, 192 1008 %ret = icmp eq i32 %and, 128 1009 ret i1 %ret 1010} 1011 1012define i1 @test55(i32 %a) { 1013; CHECK-LABEL: @test55( 1014; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123 1015; CHECK-NEXT: ret i1 [[CMP]] 1016; 1017 %sub = sub i32 0, %a 1018 %cmp = icmp eq i32 %sub, 123 1019 ret i1 %cmp 1020} 1021 1022define <2 x i1> @test55vec(<2 x i32> %a) { 1023; CHECK-LABEL: @test55vec( 1024; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -123, i32 -123> 1025; CHECK-NEXT: ret <2 x i1> [[CMP]] 1026; 1027 %sub = sub <2 x i32> zeroinitializer, %a 1028 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123> 1029 ret <2 x i1> %cmp 1030} 1031 1032define i1 @test56(i32 %a) { 1033; CHECK-LABEL: @test56( 1034; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113 1035; CHECK-NEXT: ret i1 [[CMP]] 1036; 1037 %sub = sub i32 10, %a 1038 %cmp = icmp eq i32 %sub, 123 1039 ret i1 %cmp 1040} 1041 1042define <2 x i1> @test56vec(<2 x i32> %a) { 1043; CHECK-LABEL: @test56vec( 1044; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -113, i32 -113> 1045; CHECK-NEXT: ret <2 x i1> [[CMP]] 1046; 1047 %sub = sub <2 x i32> <i32 10, i32 10>, %a 1048 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123> 1049 ret <2 x i1> %cmp 1050} 1051 1052; PR10267 Don't make icmps more expensive when no other inst is subsumed. 1053declare void @foo(i32) 1054define i1 @test57(i32 %a) { 1055; CHECK-LABEL: @test57( 1056; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2 1057; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 1058; CHECK-NEXT: call void @foo(i32 [[AND]]) 1059; CHECK-NEXT: ret i1 [[CMP]] 1060; 1061 %and = and i32 %a, -2 1062 %cmp = icmp ne i32 %and, 0 1063 call void @foo(i32 %and) 1064 ret i1 %cmp 1065} 1066 1067; rdar://problem/10482509 1068define zeroext i1 @cmpabs1(i64 %val) { 1069; CHECK-LABEL: @cmpabs1( 1070; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0 1071; CHECK-NEXT: ret i1 [[TOBOOL]] 1072; 1073 %sub = sub nsw i64 0, %val 1074 %cmp = icmp slt i64 %val, 0 1075 %sub.val = select i1 %cmp, i64 %sub, i64 %val 1076 %tobool = icmp ne i64 %sub.val, 0 1077 ret i1 %tobool 1078} 1079 1080define zeroext i1 @cmpabs2(i64 %val) { 1081; CHECK-LABEL: @cmpabs2( 1082; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0 1083; CHECK-NEXT: ret i1 [[TOBOOL]] 1084; 1085 %sub = sub nsw i64 0, %val 1086 %cmp = icmp slt i64 %val, 0 1087 %sub.val = select i1 %cmp, i64 %val, i64 %sub 1088 %tobool = icmp ne i64 %sub.val, 0 1089 ret i1 %tobool 1090} 1091 1092define void @test58() { 1093; CHECK-LABEL: @test58( 1094; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592) 1095; CHECK-NEXT: ret void 1096; 1097 %cast = bitcast <1 x i64> <i64 36029346783166592> to i64 1098 %call = call i32 @test58_d( i64 %cast) 1099 ret void 1100} 1101declare i32 @test58_d(i64) 1102 1103define i1 @test59(i8* %foo) { 1104; CHECK-LABEL: @test59( 1105; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, i8* [[FOO:%.*]], i64 8 1106; CHECK-NEXT: [[USE:%.*]] = ptrtoint i8* [[GEP1]] to i64 1107; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]]) 1108; CHECK-NEXT: ret i1 true 1109; 1110 %bit = bitcast i8* %foo to i32* 1111 %gep1 = getelementptr inbounds i32, i32* %bit, i64 2 1112 %gep2 = getelementptr inbounds i8, i8* %foo, i64 10 1113 %cast1 = bitcast i32* %gep1 to i8* 1114 %cmp = icmp ult i8* %cast1, %gep2 1115 %use = ptrtoint i8* %cast1 to i64 1116 %call = call i32 @test58_d(i64 %use) 1117 ret i1 %cmp 1118} 1119 1120define i1 @test59_as1(i8 addrspace(1)* %foo) { 1121; CHECK-LABEL: @test59_as1( 1122; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[FOO:%.*]], i16 8 1123; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[GEP1]] to i16 1124; CHECK-NEXT: [[USE:%.*]] = zext i16 [[TMP1]] to i64 1125; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]]) 1126; CHECK-NEXT: ret i1 true 1127; 1128 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* 1129 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 2 1130 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 10 1131 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)* 1132 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 1133 %use = ptrtoint i8 addrspace(1)* %cast1 to i64 1134 %call = call i32 @test58_d(i64 %use) 1135 ret i1 %cmp 1136} 1137 1138define i1 @test60(i8* %foo, i64 %i, i64 %j) { 1139; CHECK-LABEL: @test60( 1140; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2 1141; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]] 1142; CHECK-NEXT: ret i1 [[TMP1]] 1143; 1144 %bit = bitcast i8* %foo to i32* 1145 %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i 1146 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 1147 %cast1 = bitcast i32* %gep1 to i8* 1148 %cmp = icmp ult i8* %cast1, %gep2 1149 ret i1 %cmp 1150} 1151 1152define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) { 1153; CHECK-LABEL: @test60_as1( 1154; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16 1155; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i16 1156; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[TMP1]], 2 1157; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP2]] 1158; CHECK-NEXT: ret i1 [[TMP3]] 1159; 1160 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* 1161 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 %i 1162 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 %j 1163 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)* 1164 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 1165 ret i1 %cmp 1166} 1167 1168; Same as test60, but look through an addrspacecast instead of a 1169; bitcast. This uses the same sized addrspace. 1170define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) { 1171; CHECK-LABEL: @test60_addrspacecast( 1172; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2 1173; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]] 1174; CHECK-NEXT: ret i1 [[TMP1]] 1175; 1176 %bit = addrspacecast i8* %foo to i32 addrspace(3)* 1177 %gep1 = getelementptr inbounds i32, i32 addrspace(3)* %bit, i64 %i 1178 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 1179 %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8* 1180 %cmp = icmp ult i8* %cast1, %gep2 1181 ret i1 %cmp 1182} 1183 1184define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) { 1185; CHECK-LABEL: @test60_addrspacecast_smaller( 1186; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2 1187; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16 1188; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]] 1189; CHECK-NEXT: ret i1 [[TMP2]] 1190; 1191 %bit = addrspacecast i8* %foo to i32 addrspace(1)* 1192 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i 1193 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 1194 %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8* 1195 %cmp = icmp ult i8* %cast1, %gep2 1196 ret i1 %cmp 1197} 1198 1199define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) { 1200; CHECK-LABEL: @test60_addrspacecast_larger( 1201; CHECK-NEXT: [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16 1202; CHECK-NEXT: [[TMP1:%.*]] = shl i16 [[I_TR]], 2 1203; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]] 1204; CHECK-NEXT: ret i1 [[TMP2]] 1205; 1206 %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)* 1207 %gep1 = getelementptr inbounds i32, i32 addrspace(2)* %bit, i32 %i 1208 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j 1209 %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)* 1210 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 1211 ret i1 %cmp 1212} 1213 1214define i1 @test61(i8* %foo, i64 %i, i64 %j) { 1215; CHECK-LABEL: @test61( 1216; CHECK-NEXT: [[BIT:%.*]] = bitcast i8* [[FOO:%.*]] to i32* 1217; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, i32* [[BIT]], i64 [[I:%.*]] 1218; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, i8* [[FOO]], i64 [[J:%.*]] 1219; CHECK-NEXT: [[CAST1:%.*]] = bitcast i32* [[GEP1]] to i8* 1220; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8* [[GEP2]], [[CAST1]] 1221; CHECK-NEXT: ret i1 [[CMP]] 1222; 1223 %bit = bitcast i8* %foo to i32* 1224 %gep1 = getelementptr i32, i32* %bit, i64 %i 1225 %gep2 = getelementptr i8, i8* %foo, i64 %j 1226 %cast1 = bitcast i32* %gep1 to i8* 1227 %cmp = icmp ult i8* %cast1, %gep2 1228 ret i1 %cmp 1229; Don't transform non-inbounds GEPs. 1230} 1231 1232define i1 @test61_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) { 1233; CHECK-LABEL: @test61_as1( 1234; CHECK-NEXT: [[BIT:%.*]] = bitcast i8 addrspace(1)* [[FOO:%.*]] to i32 addrspace(1)* 1235; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, i32 addrspace(1)* [[BIT]], i16 [[I:%.*]] 1236; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, i8 addrspace(1)* [[FOO]], i16 [[J:%.*]] 1237; CHECK-NEXT: [[CAST1:%.*]] = bitcast i32 addrspace(1)* [[GEP1]] to i8 addrspace(1)* 1238; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 addrspace(1)* [[GEP2]], [[CAST1]] 1239; CHECK-NEXT: ret i1 [[CMP]] 1240; 1241 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* 1242 %gep1 = getelementptr i32, i32 addrspace(1)* %bit, i16 %i 1243 %gep2 = getelementptr i8, i8 addrspace(1)* %foo, i16 %j 1244 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)* 1245 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 1246 ret i1 %cmp 1247; Don't transform non-inbounds GEPs. 1248} 1249 1250define i1 @test62(i8* %a) { 1251; CHECK-LABEL: @test62( 1252; CHECK-NEXT: ret i1 true 1253; 1254 %arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1 1255 %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10 1256 %cmp = icmp slt i8* %arrayidx1, %arrayidx2 1257 ret i1 %cmp 1258} 1259 1260define i1 @test62_as1(i8 addrspace(1)* %a) { 1261; CHECK-LABEL: @test62_as1( 1262; CHECK-NEXT: ret i1 true 1263; 1264 %arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1 1265 %arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10 1266 %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2 1267 ret i1 %cmp 1268} 1269 1270define i1 @test63(i8 %a, i32 %b) { 1271; CHECK-LABEL: @test63( 1272; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 1273; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]] 1274; CHECK-NEXT: ret i1 [[C]] 1275; 1276 %z = zext i8 %a to i32 1277 %t = and i32 %b, 255 1278 %c = icmp eq i32 %z, %t 1279 ret i1 %c 1280} 1281 1282define i1 @test64(i8 %a, i32 %b) { 1283; CHECK-LABEL: @test64( 1284; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 1285; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]] 1286; CHECK-NEXT: ret i1 [[C]] 1287; 1288 %t = and i32 %b, 255 1289 %z = zext i8 %a to i32 1290 %c = icmp eq i32 %t, %z 1291 ret i1 %c 1292} 1293 1294define i1 @test65(i64 %A, i64 %B) { 1295; CHECK-LABEL: @test65( 1296; CHECK-NEXT: ret i1 true 1297; 1298 %s1 = add i64 %A, %B 1299 %s2 = add i64 %A, %B 1300 %cmp = icmp eq i64 %s1, %s2 1301 ret i1 %cmp 1302} 1303 1304define i1 @test66(i64 %A, i64 %B) { 1305; CHECK-LABEL: @test66( 1306; CHECK-NEXT: ret i1 true 1307; 1308 %s1 = add i64 %A, %B 1309 %s2 = add i64 %B, %A 1310 %cmp = icmp eq i64 %s1, %s2 1311 ret i1 %cmp 1312} 1313 1314define i1 @test67(i32 %x) { 1315; CHECK-LABEL: @test67( 1316; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96 1317; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 1318; CHECK-NEXT: ret i1 [[CMP]] 1319; 1320 %and = and i32 %x, 127 1321 %cmp = icmp sgt i32 %and, 31 1322 ret i1 %cmp 1323} 1324 1325define i1 @test67inverse(i32 %x) { 1326; CHECK-LABEL: @test67inverse( 1327; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96 1328; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 1329; CHECK-NEXT: ret i1 [[CMP]] 1330; 1331 %and = and i32 %x, 127 1332 %cmp = icmp sle i32 %and, 31 1333 ret i1 %cmp 1334} 1335 1336; The test above relies on 3 different folds. 1337; This test only checks the last of those (icmp ugt -> icmp ne). 1338 1339define <2 x i1> @test67vec(<2 x i32> %x) { 1340; CHECK-LABEL: @test67vec( 1341; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96> 1342; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer 1343; CHECK-NEXT: ret <2 x i1> [[CMP]] 1344; 1345 %and = and <2 x i32> %x, <i32 96, i32 96> 1346 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31> 1347 ret <2 x i1> %cmp 1348} 1349 1350define <2 x i1> @test67vec2(<2 x i32> %x) { 1351; CHECK-LABEL: @test67vec2( 1352; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96> 1353; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer 1354; CHECK-NEXT: ret <2 x i1> [[CMP]] 1355; 1356 %and = and <2 x i32> %x, <i32 127, i32 127> 1357 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31> 1358 ret <2 x i1> %cmp 1359} 1360 1361define <2 x i1> @test67vecinverse(<2 x i32> %x) { 1362; CHECK-LABEL: @test67vecinverse( 1363; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96> 1364; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer 1365; CHECK-NEXT: ret <2 x i1> [[CMP]] 1366; 1367 %and = and <2 x i32> %x, <i32 96, i32 96> 1368 %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31> 1369 ret <2 x i1> %cmp 1370} 1371 1372define i1 @test68(i32 %x) { 1373; CHECK-LABEL: @test68( 1374; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 127 1375; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[AND]], 30 1376; CHECK-NEXT: ret i1 [[CMP]] 1377; 1378 %and = and i32 %x, 127 1379 %cmp = icmp sgt i32 %and, 30 1380 ret i1 %cmp 1381} 1382 1383; PR15940 1384define i1 @test70(i32 %X) { 1385; CHECK-LABEL: @test70( 1386; CHECK-NEXT: [[A:%.*]] = srem i32 5, [[X:%.*]] 1387; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A]], 2 1388; CHECK-NEXT: ret i1 [[C]] 1389; 1390 %A = srem i32 5, %X 1391 %B = add i32 %A, 2 1392 %C = icmp ne i32 %B, 4 1393 ret i1 %C 1394} 1395 1396define <2 x i1> @test70vec(<2 x i32> %X) { 1397; CHECK-LABEL: @test70vec( 1398; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2> 1399; CHECK-NEXT: ret <2 x i1> [[C]] 1400; 1401 %B = add <2 x i32> %X, <i32 2, i32 2> 1402 %C = icmp ne <2 x i32> %B, <i32 4, i32 4> 1403 ret <2 x i1> %C 1404} 1405 1406define i1 @icmp_sext16trunc(i32 %x) { 1407; CHECK-LABEL: @icmp_sext16trunc( 1408; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16 1409; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36 1410; CHECK-NEXT: ret i1 [[CMP]] 1411; 1412 %trunc = trunc i32 %x to i16 1413 %sext = sext i16 %trunc to i32 1414 %cmp = icmp slt i32 %sext, 36 1415 ret i1 %cmp 1416} 1417 1418define i1 @icmp_sext8trunc(i32 %x) { 1419; CHECK-LABEL: @icmp_sext8trunc( 1420; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 1421; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36 1422; CHECK-NEXT: ret i1 [[CMP]] 1423; 1424 %trunc = trunc i32 %x to i8 1425 %sext = sext i8 %trunc to i32 1426 %cmp = icmp slt i32 %sext, 36 1427 ret i1 %cmp 1428} 1429 1430; Vectors should fold the same way. 1431define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) { 1432; CHECK-LABEL: @icmp_sext8trunc_vec( 1433; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8> 1434; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], <i8 36, i8 36> 1435; CHECK-NEXT: ret <2 x i1> [[CMP]] 1436; 1437 %trunc = trunc <2 x i32> %x to <2 x i8> 1438 %sext = sext <2 x i8> %trunc to <2 x i32> 1439 %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36> 1440 ret <2 x i1> %cmp 1441} 1442 1443define i1 @icmp_shl16(i32 %x) { 1444; CHECK-LABEL: @icmp_shl16( 1445; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16 1446; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36 1447; CHECK-NEXT: ret i1 [[CMP]] 1448; 1449 %shl = shl i32 %x, 16 1450 %cmp = icmp slt i32 %shl, 2359296 1451 ret i1 %cmp 1452} 1453 1454; D25952: Don't create illegal types like i15 in InstCombine 1455 1456define i1 @icmp_shl17(i32 %x) { 1457; CHECK-LABEL: @icmp_shl17( 1458; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 17 1459; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296 1460; CHECK-NEXT: ret i1 [[CMP]] 1461; 1462 %shl = shl i32 %x, 17 1463 %cmp = icmp slt i32 %shl, 2359296 1464 ret i1 %cmp 1465} 1466 1467define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) { 1468; CHECK-LABEL: @icmp_shl16_vec( 1469; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16> 1470; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], <i16 36, i16 36> 1471; CHECK-NEXT: ret <2 x i1> [[CMP]] 1472; 1473 %shl = shl <2 x i32> %x, <i32 16, i32 16> 1474 %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296> 1475 ret <2 x i1> %cmp 1476} 1477 1478define i1 @icmp_shl24(i32 %x) { 1479; CHECK-LABEL: @icmp_shl24( 1480; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 1481; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36 1482; CHECK-NEXT: ret i1 [[CMP]] 1483; 1484 %shl = shl i32 %x, 24 1485 %cmp = icmp slt i32 %shl, 603979776 1486 ret i1 %cmp 1487} 1488 1489define i1 @icmp_shl_eq(i32 %x) { 1490; CHECK-LABEL: @icmp_shl_eq( 1491; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727 1492; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0 1493; CHECK-NEXT: ret i1 [[CMP]] 1494; 1495 %mul = shl i32 %x, 5 1496 %cmp = icmp eq i32 %mul, 0 1497 ret i1 %cmp 1498} 1499 1500define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) { 1501; CHECK-LABEL: @icmp_shl_eq_vec( 1502; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727> 1503; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer 1504; CHECK-NEXT: ret <2 x i1> [[CMP]] 1505; 1506 %mul = shl <2 x i32> %x, <i32 5, i32 5> 1507 %cmp = icmp eq <2 x i32> %mul, zeroinitializer 1508 ret <2 x i1> %cmp 1509} 1510 1511define i1 @icmp_shl_nsw_ne(i32 %x) { 1512; CHECK-LABEL: @icmp_shl_nsw_ne( 1513; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0 1514; CHECK-NEXT: ret i1 [[CMP]] 1515; 1516 %mul = shl nsw i32 %x, 7 1517 %cmp = icmp ne i32 %mul, 0 1518 ret i1 %cmp 1519} 1520 1521define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) { 1522; CHECK-LABEL: @icmp_shl_nsw_ne_vec( 1523; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 1524; CHECK-NEXT: ret <2 x i1> [[CMP]] 1525; 1526 %mul = shl nsw <2 x i32> %x, <i32 7, i32 7> 1527 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1528 ret <2 x i1> %cmp 1529} 1530 1531define i1 @icmp_shl_ne(i32 %x) { 1532; CHECK-LABEL: @icmp_shl_ne( 1533; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431 1534; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0 1535; CHECK-NEXT: ret i1 [[CMP]] 1536; 1537 %mul = shl i32 %x, 7 1538 %cmp = icmp ne i32 %mul, 0 1539 ret i1 %cmp 1540} 1541 1542define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) { 1543; CHECK-LABEL: @icmp_shl_ne_vec( 1544; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 33554431, i32 33554431> 1545; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer 1546; CHECK-NEXT: ret <2 x i1> [[CMP]] 1547; 1548 %mul = shl <2 x i32> %x, <i32 7, i32 7> 1549 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1550 ret <2 x i1> %cmp 1551} 1552 1553define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) { 1554; CHECK-LABEL: @icmp_shl_nuw_ne_vec( 1555; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2> 1556; CHECK-NEXT: ret <2 x i1> [[CMP]] 1557; 1558 %shl = shl nuw <2 x i32> %x, <i32 7, i32 7> 1559 %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256> 1560 ret <2 x i1> %cmp 1561} 1562 1563; If the (mul x, C) preserved the sign and this is sign test, 1564; compare the LHS operand instead 1565define i1 @icmp_mul_nsw(i32 %x) { 1566; CHECK-LABEL: @icmp_mul_nsw( 1567; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0 1568; CHECK-NEXT: ret i1 [[CMP]] 1569; 1570 %mul = mul nsw i32 %x, 12 1571 %cmp = icmp sgt i32 %mul, 0 1572 ret i1 %cmp 1573} 1574 1575define i1 @icmp_mul_nsw1(i32 %x) { 1576; CHECK-LABEL: @icmp_mul_nsw1( 1577; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 1578; CHECK-NEXT: ret i1 [[CMP]] 1579; 1580 %mul = mul nsw i32 %x, 12 1581 %cmp = icmp sle i32 %mul, -1 1582 ret i1 %cmp 1583} 1584 1585define i1 @icmp_mul_nsw_neg(i32 %x) { 1586; CHECK-LABEL: @icmp_mul_nsw_neg( 1587; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1 1588; CHECK-NEXT: ret i1 [[CMP]] 1589; 1590 %mul = mul nsw i32 %x, -12 1591 %cmp = icmp sge i32 %mul, 0 1592 ret i1 %cmp 1593} 1594 1595define i1 @icmp_mul_nsw_neg1(i32 %x) { 1596; CHECK-LABEL: @icmp_mul_nsw_neg1( 1597; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 1598; CHECK-NEXT: ret i1 [[CMP]] 1599; 1600 %mul = mul nsw i32 %x, -12 1601 %cmp = icmp sge i32 %mul, 1 1602 ret i1 %cmp 1603} 1604 1605define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) { 1606; CHECK-LABEL: @icmp_mul_nsw_neg1_vec( 1607; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer 1608; CHECK-NEXT: ret <2 x i1> [[CMP]] 1609; 1610 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12> 1611 %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1> 1612 ret <2 x i1> %cmp 1613} 1614 1615define i1 @icmp_mul_nsw_0(i32 %x) { 1616; CHECK-LABEL: @icmp_mul_nsw_0( 1617; CHECK-NEXT: ret i1 false 1618; 1619 %mul = mul nsw i32 %x, 0 1620 %cmp = icmp sgt i32 %mul, 0 1621 ret i1 %cmp 1622} 1623 1624define i1 @icmp_mul(i32 %x) { 1625; CHECK-LABEL: @icmp_mul( 1626; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X:%.*]], -12 1627; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1 1628; CHECK-NEXT: ret i1 [[CMP]] 1629; 1630 %mul = mul i32 %x, -12 1631 %cmp = icmp sge i32 %mul, 0 1632 ret i1 %cmp 1633} 1634 1635; Checks for icmp (eq|ne) (mul x, C), 0 1636define i1 @icmp_mul_neq0(i32 %x) { 1637; CHECK-LABEL: @icmp_mul_neq0( 1638; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0 1639; CHECK-NEXT: ret i1 [[CMP]] 1640; 1641 %mul = mul nsw i32 %x, -12 1642 %cmp = icmp ne i32 %mul, 0 1643 ret i1 %cmp 1644} 1645 1646define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) { 1647; CHECK-LABEL: @icmp_mul_neq0_vec( 1648; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 1649; CHECK-NEXT: ret <2 x i1> [[CMP]] 1650; 1651 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12> 1652 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1653 ret <2 x i1> %cmp 1654} 1655 1656define i1 @icmp_mul_eq0(i32 %x) { 1657; CHECK-LABEL: @icmp_mul_eq0( 1658; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 1659; CHECK-NEXT: ret i1 [[CMP]] 1660; 1661 %mul = mul nsw i32 %x, 12 1662 %cmp = icmp eq i32 %mul, 0 1663 ret i1 %cmp 1664} 1665 1666define i1 @icmp_mul0_eq0(i32 %x) { 1667; CHECK-LABEL: @icmp_mul0_eq0( 1668; CHECK-NEXT: ret i1 true 1669; 1670 %mul = mul i32 %x, 0 1671 %cmp = icmp eq i32 %mul, 0 1672 ret i1 %cmp 1673} 1674 1675define i1 @icmp_mul0_ne0(i32 %x) { 1676; CHECK-LABEL: @icmp_mul0_ne0( 1677; CHECK-NEXT: ret i1 false 1678; 1679 %mul = mul i32 %x, 0 1680 %cmp = icmp ne i32 %mul, 0 1681 ret i1 %cmp 1682} 1683 1684define i1 @icmp_sub1_sge(i32 %x, i32 %y) { 1685; CHECK-LABEL: @icmp_sub1_sge( 1686; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 1687; CHECK-NEXT: ret i1 [[CMP]] 1688; 1689 %sub = add nsw i32 %x, -1 1690 %cmp = icmp sge i32 %sub, %y 1691 ret i1 %cmp 1692} 1693 1694define i1 @icmp_add1_sgt(i32 %x, i32 %y) { 1695; CHECK-LABEL: @icmp_add1_sgt( 1696; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]] 1697; CHECK-NEXT: ret i1 [[CMP]] 1698; 1699 %add = add nsw i32 %x, 1 1700 %cmp = icmp sgt i32 %add, %y 1701 ret i1 %cmp 1702} 1703 1704define i1 @icmp_sub1_slt(i32 %x, i32 %y) { 1705; CHECK-LABEL: @icmp_sub1_slt( 1706; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]] 1707; CHECK-NEXT: ret i1 [[CMP]] 1708; 1709 %sub = add nsw i32 %x, -1 1710 %cmp = icmp slt i32 %sub, %y 1711 ret i1 %cmp 1712} 1713 1714define i1 @icmp_add1_sle(i32 %x, i32 %y) { 1715; CHECK-LABEL: @icmp_add1_sle( 1716; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 1717; CHECK-NEXT: ret i1 [[CMP]] 1718; 1719 %add = add nsw i32 %x, 1 1720 %cmp = icmp sle i32 %add, %y 1721 ret i1 %cmp 1722} 1723 1724define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) { 1725; CHECK-LABEL: @icmp_add20_sge_add57( 1726; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37 1727; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X:%.*]] 1728; CHECK-NEXT: ret i1 [[CMP]] 1729; 1730 %1 = add nsw i32 %x, 20 1731 %2 = add nsw i32 %y, 57 1732 %cmp = icmp sge i32 %1, %2 1733 ret i1 %cmp 1734} 1735 1736define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) { 1737; CHECK-LABEL: @icmp_sub57_sge_sub20( 1738; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37 1739; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]] 1740; CHECK-NEXT: ret i1 [[CMP]] 1741; 1742 %1 = add nsw i32 %x, -57 1743 %2 = add nsw i32 %y, -20 1744 %cmp = icmp sge i32 %1, %2 1745 ret i1 %cmp 1746} 1747 1748define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) { 1749; CHECK-LABEL: @icmp_and_shl_neg_ne_0( 1750; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]] 1751; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]] 1752; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 1753; CHECK-NEXT: ret i1 [[CMP]] 1754; 1755 %neg = xor i32 %A, -1 1756 %shl = shl i32 1, %B 1757 %and = and i32 %shl, %neg 1758 %cmp = icmp ne i32 %and, 0 1759 ret i1 %cmp 1760} 1761 1762define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) { 1763; CHECK-LABEL: @icmp_and_shl_neg_eq_0( 1764; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]] 1765; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]] 1766; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0 1767; CHECK-NEXT: ret i1 [[CMP]] 1768; 1769 %neg = xor i32 %A, -1 1770 %shl = shl i32 1, %B 1771 %and = and i32 %shl, %neg 1772 %cmp = icmp eq i32 %and, 0 1773 ret i1 %cmp 1774} 1775 1776define i1 @icmp_add_and_shr_ne_0(i32 %X) { 1777; CHECK-LABEL: @icmp_add_and_shr_ne_0( 1778; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240 1779; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224 1780; CHECK-NEXT: ret i1 [[TOBOOL]] 1781; 1782 %shr = lshr i32 %X, 4 1783 %and = and i32 %shr, 15 1784 %add = add i32 %and, -14 1785 %tobool = icmp ne i32 %add, 0 1786 ret i1 %tobool 1787} 1788 1789define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) { 1790; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec( 1791; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240> 1792; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[AND]], <i32 224, i32 224> 1793; CHECK-NEXT: ret <2 x i1> [[TOBOOL]] 1794; 1795 %shr = lshr <2 x i32> %X, <i32 4, i32 4> 1796 %and = and <2 x i32> %shr, <i32 15, i32 15> 1797 %add = add <2 x i32> %and, <i32 -14, i32 -14> 1798 %tobool = icmp ne <2 x i32> %add, zeroinitializer 1799 ret <2 x i1> %tobool 1800} 1801 1802; Variation of the above with an extra use of the shift 1803define i1 @icmp_and_shr_multiuse(i32 %X) { 1804; CHECK-LABEL: @icmp_and_shr_multiuse( 1805; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240 1806; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496 1807; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224 1808; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432 1809; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] 1810; CHECK-NEXT: ret i1 [[AND3]] 1811; 1812 %shr = lshr i32 %X, 4 1813 %and = and i32 %shr, 15 1814 %and2 = and i32 %shr, 31 ; second use of the shift 1815 %tobool = icmp ne i32 %and, 14 1816 %tobool2 = icmp ne i32 %and2, 27 1817 %and3 = and i1 %tobool, %tobool2 1818 ret i1 %and3 1819} 1820 1821; Variation of the above with an ashr 1822define i1 @icmp_and_ashr_multiuse(i32 %X) { 1823; CHECK-LABEL: @icmp_and_ashr_multiuse( 1824; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240 1825; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496 1826; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224 1827; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432 1828; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] 1829; CHECK-NEXT: ret i1 [[AND3]] 1830; 1831 %shr = ashr i32 %X, 4 1832 %and = and i32 %shr, 15 1833 %and2 = and i32 %shr, 31 ; second use of the shift 1834 %tobool = icmp ne i32 %and, 14 1835 %tobool2 = icmp ne i32 %and2, 27 1836 %and3 = and i1 %tobool, %tobool2 1837 ret i1 %and3 1838} 1839 1840define i1 @icmp_lshr_and_overshift(i8 %X) { 1841; CHECK-LABEL: @icmp_lshr_and_overshift( 1842; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31 1843; CHECK-NEXT: ret i1 [[TOBOOL]] 1844; 1845 %shr = lshr i8 %X, 5 1846 %and = and i8 %shr, 15 1847 %tobool = icmp ne i8 %and, 0 1848 ret i1 %tobool 1849} 1850 1851; We shouldn't simplify this because the and uses bits that are shifted in. 1852define i1 @icmp_ashr_and_overshift(i8 %X) { 1853; CHECK-LABEL: @icmp_ashr_and_overshift( 1854; CHECK-NEXT: [[SHR:%.*]] = ashr i8 [[X:%.*]], 5 1855; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHR]], 15 1856; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0 1857; CHECK-NEXT: ret i1 [[TOBOOL]] 1858; 1859 %shr = ashr i8 %X, 5 1860 %and = and i8 %shr, 15 1861 %tobool = icmp ne i8 %and, 0 1862 ret i1 %tobool 1863} 1864 1865; PR16244 1866define i1 @test71(i8* %x) { 1867; CHECK-LABEL: @test71( 1868; CHECK-NEXT: ret i1 false 1869; 1870 %a = getelementptr i8, i8* %x, i64 8 1871 %b = getelementptr inbounds i8, i8* %x, i64 8 1872 %c = icmp ugt i8* %a, %b 1873 ret i1 %c 1874} 1875 1876define i1 @test71_as1(i8 addrspace(1)* %x) { 1877; CHECK-LABEL: @test71_as1( 1878; CHECK-NEXT: ret i1 false 1879; 1880 %a = getelementptr i8, i8 addrspace(1)* %x, i64 8 1881 %b = getelementptr inbounds i8, i8 addrspace(1)* %x, i64 8 1882 %c = icmp ugt i8 addrspace(1)* %a, %b 1883 ret i1 %c 1884} 1885 1886define i1 @icmp_shl_1_V_ult_32(i32 %V) { 1887; CHECK-LABEL: @icmp_shl_1_V_ult_32( 1888; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 1889; CHECK-NEXT: ret i1 [[CMP]] 1890; 1891 %shl = shl i32 1, %V 1892 %cmp = icmp ult i32 %shl, 32 1893 ret i1 %cmp 1894} 1895 1896define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) { 1897; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec( 1898; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5> 1899; CHECK-NEXT: ret <2 x i1> [[CMP]] 1900; 1901 %shl = shl <2 x i32> <i32 1, i32 1>, %V 1902 %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32> 1903 ret <2 x i1> %cmp 1904} 1905 1906define i1 @icmp_shl_1_V_eq_32(i32 %V) { 1907; CHECK-LABEL: @icmp_shl_1_V_eq_32( 1908; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5 1909; CHECK-NEXT: ret i1 [[CMP]] 1910; 1911 %shl = shl i32 1, %V 1912 %cmp = icmp eq i32 %shl, 32 1913 ret i1 %cmp 1914} 1915 1916define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) { 1917; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec( 1918; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 5, i32 5> 1919; CHECK-NEXT: ret <2 x i1> [[CMP]] 1920; 1921 %shl = shl <2 x i32> <i32 1, i32 1>, %V 1922 %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32> 1923 ret <2 x i1> %cmp 1924} 1925 1926define i1 @icmp_shl_1_V_ult_30(i32 %V) { 1927; CHECK-LABEL: @icmp_shl_1_V_ult_30( 1928; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 1929; CHECK-NEXT: ret i1 [[CMP]] 1930; 1931 %shl = shl i32 1, %V 1932 %cmp = icmp ult i32 %shl, 30 1933 ret i1 %cmp 1934} 1935 1936define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) { 1937; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec( 1938; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5> 1939; CHECK-NEXT: ret <2 x i1> [[CMP]] 1940; 1941 %shl = shl <2 x i32> <i32 1, i32 1>, %V 1942 %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30> 1943 ret <2 x i1> %cmp 1944} 1945 1946define i1 @icmp_shl_1_V_ugt_30(i32 %V) { 1947; CHECK-LABEL: @icmp_shl_1_V_ugt_30( 1948; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4 1949; CHECK-NEXT: ret i1 [[CMP]] 1950; 1951 %shl = shl i32 1, %V 1952 %cmp = icmp ugt i32 %shl, 30 1953 ret i1 %cmp 1954} 1955 1956define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) { 1957; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec( 1958; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4> 1959; CHECK-NEXT: ret <2 x i1> [[CMP]] 1960; 1961 %shl = shl <2 x i32> <i32 1, i32 1>, %V 1962 %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30> 1963 ret <2 x i1> %cmp 1964} 1965 1966define i1 @icmp_shl_1_V_ule_30(i32 %V) { 1967; CHECK-LABEL: @icmp_shl_1_V_ule_30( 1968; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 1969; CHECK-NEXT: ret i1 [[CMP]] 1970; 1971 %shl = shl i32 1, %V 1972 %cmp = icmp ule i32 %shl, 30 1973 ret i1 %cmp 1974} 1975 1976define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) { 1977; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec( 1978; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5> 1979; CHECK-NEXT: ret <2 x i1> [[CMP]] 1980; 1981 %shl = shl <2 x i32> <i32 1, i32 1>, %V 1982 %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30> 1983 ret <2 x i1> %cmp 1984} 1985 1986define i1 @icmp_shl_1_V_uge_30(i32 %V) { 1987; CHECK-LABEL: @icmp_shl_1_V_uge_30( 1988; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4 1989; CHECK-NEXT: ret i1 [[CMP]] 1990; 1991 %shl = shl i32 1, %V 1992 %cmp = icmp uge i32 %shl, 30 1993 ret i1 %cmp 1994} 1995 1996define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) { 1997; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec( 1998; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4> 1999; CHECK-NEXT: ret <2 x i1> [[CMP]] 2000; 2001 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2002 %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30> 2003 ret <2 x i1> %cmp 2004} 2005 2006define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) { 2007; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648( 2008; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31 2009; CHECK-NEXT: ret i1 [[CMP]] 2010; 2011 %shl = shl i32 1, %V 2012 %cmp = icmp uge i32 %shl, 2147483648 2013 ret i1 %cmp 2014} 2015 2016define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) { 2017; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec( 2018; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 31, i32 31> 2019; CHECK-NEXT: ret <2 x i1> [[CMP]] 2020; 2021 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2022 %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648> 2023 ret <2 x i1> %cmp 2024} 2025 2026define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) { 2027; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648( 2028; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31 2029; CHECK-NEXT: ret i1 [[CMP]] 2030; 2031 %shl = shl i32 1, %V 2032 %cmp = icmp ult i32 %shl, 2147483648 2033 ret i1 %cmp 2034} 2035 2036define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) { 2037; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec( 2038; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], <i32 31, i32 31> 2039; CHECK-NEXT: ret <2 x i1> [[CMP]] 2040; 2041 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2042 %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648> 2043 ret <2 x i1> %cmp 2044} 2045 2046define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) { 2047; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B( 2048; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1 2049; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]] 2050; CHECK-NEXT: ret i1 [[TMP2]] 2051; 2052 %1 = icmp eq i64 %b, 0 2053 %2 = icmp ult i64 %a, %b 2054 %3 = or i1 %1, %2 2055 ret i1 %3 2056} 2057 2058define i1 @icmp_add_ult_2(i32 %X) { 2059; CHECK-LABEL: @icmp_add_ult_2( 2060; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2061; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14 2062; CHECK-NEXT: ret i1 [[CMP]] 2063; 2064 %add = add i32 %X, -14 2065 %cmp = icmp ult i32 %add, 2 2066 ret i1 %cmp 2067} 2068 2069define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) { 2070; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec( 2071; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2072; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14> 2073; CHECK-NEXT: ret <2 x i1> [[CMP]] 2074; 2075 %add = add <2 x i32> %X, <i32 -14, i32 -14> 2076 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2> 2077 ret <2 x i1> %cmp 2078} 2079 2080define i1 @icmp_sub_3_X_ult_2(i32 %X) { 2081; CHECK-LABEL: @icmp_sub_3_X_ult_2( 2082; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], 1 2083; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3 2084; CHECK-NEXT: ret i1 [[CMP]] 2085; 2086 %add = sub i32 3, %X 2087 %cmp = icmp ult i32 %add, 2 2088 ret i1 %cmp 2089} 2090 2091define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) { 2092; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec( 2093; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1> 2094; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 3, i32 3> 2095; CHECK-NEXT: ret <2 x i1> [[CMP]] 2096; 2097 %add = sub <2 x i32> <i32 3, i32 3>, %X 2098 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2> 2099 ret <2 x i1> %cmp 2100} 2101 2102define i1 @icmp_add_X_-14_uge_2(i32 %X) { 2103; CHECK-LABEL: @icmp_add_X_-14_uge_2( 2104; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2105; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14 2106; CHECK-NEXT: ret i1 [[CMP]] 2107; 2108 %add = add i32 %X, -14 2109 %cmp = icmp uge i32 %add, 2 2110 ret i1 %cmp 2111} 2112 2113define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) { 2114; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec( 2115; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2116; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14> 2117; CHECK-NEXT: ret <2 x i1> [[CMP]] 2118; 2119 %add = add <2 x i32> %X, <i32 -14, i32 -14> 2120 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2> 2121 ret <2 x i1> %cmp 2122} 2123 2124define i1 @icmp_sub_3_X_uge_2(i32 %X) { 2125; CHECK-LABEL: @icmp_sub_3_X_uge_2( 2126; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], 1 2127; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 3 2128; CHECK-NEXT: ret i1 [[CMP]] 2129; 2130 %add = sub i32 3, %X 2131 %cmp = icmp uge i32 %add, 2 2132 ret i1 %cmp 2133} 2134 2135define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) { 2136; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec( 2137; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1> 2138; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 3, i32 3> 2139; CHECK-NEXT: ret <2 x i1> [[CMP]] 2140; 2141 %add = sub <2 x i32> <i32 3, i32 3>, %X 2142 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2> 2143 ret <2 x i1> %cmp 2144} 2145 2146define i1 @icmp_and_X_-16_eq-16(i32 %X) { 2147; CHECK-LABEL: @icmp_and_X_-16_eq-16( 2148; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17 2149; CHECK-NEXT: ret i1 [[CMP]] 2150; 2151 %and = and i32 %X, -16 2152 %cmp = icmp eq i32 %and, -16 2153 ret i1 %cmp 2154} 2155 2156define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) { 2157; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec( 2158; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17> 2159; CHECK-NEXT: ret <2 x i1> [[CMP]] 2160; 2161 %and = and <2 x i32> %X, <i32 -16, i32 -16> 2162 %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16> 2163 ret <2 x i1> %cmp 2164} 2165 2166define i1 @icmp_and_X_-16_ne-16(i32 %X) { 2167; CHECK-LABEL: @icmp_and_X_-16_ne-16( 2168; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16 2169; CHECK-NEXT: ret i1 [[CMP]] 2170; 2171 %and = and i32 %X, -16 2172 %cmp = icmp ne i32 %and, -16 2173 ret i1 %cmp 2174} 2175 2176define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) { 2177; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec( 2178; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16> 2179; CHECK-NEXT: ret <2 x i1> [[CMP]] 2180; 2181 %and = and <2 x i32> %X, <i32 -16, i32 -16> 2182 %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16> 2183 ret <2 x i1> %cmp 2184} 2185 2186; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524 2187; X | C == C --> X <=u C (when C+1 is PowerOf2). 2188 2189define i1 @or1_eq1(i32 %x) { 2190; CHECK-LABEL: @or1_eq1( 2191; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2 2192; CHECK-NEXT: ret i1 [[T1]] 2193; 2194 %t0 = or i32 %x, 1 2195 %t1 = icmp eq i32 %t0, 1 2196 ret i1 %t1 2197} 2198 2199; X | C == C --> X <=u C (when C+1 is PowerOf2). 2200 2201define <2 x i1> @or3_eq3_vec(<2 x i8> %x) { 2202; CHECK-LABEL: @or3_eq3_vec( 2203; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4> 2204; CHECK-NEXT: ret <2 x i1> [[T1]] 2205; 2206 %t0 = or <2 x i8> %x, <i8 3, i8 3> 2207 %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3> 2208 ret <2 x i1> %t1 2209} 2210 2211; X | C != C --> X >u C (when C+1 is PowerOf2). 2212 2213define i1 @or7_ne7(i32 %x) { 2214; CHECK-LABEL: @or7_ne7( 2215; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7 2216; CHECK-NEXT: ret i1 [[T1]] 2217; 2218 %t0 = or i32 %x, 7 2219 %t1 = icmp ne i32 %t0, 7 2220 ret i1 %t1 2221} 2222 2223; X | C != C --> X >u C (when C+1 is PowerOf2). 2224 2225define <2 x i1> @or63_ne63_vec(<2 x i8> %x) { 2226; CHECK-LABEL: @or63_ne63_vec( 2227; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63> 2228; CHECK-NEXT: ret <2 x i1> [[T1]] 2229; 2230 %t0 = or <2 x i8> %x, <i8 63, i8 63> 2231 %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63> 2232 ret <2 x i1> %t1 2233} 2234 2235; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611 2236; X | C == C --> (X & ~C) == 0 2237 2238define i1 @orC_eqC(i32 %x) { 2239; CHECK-LABEL: @orC_eqC( 2240; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 2241; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[TMP1]], 0 2242; CHECK-NEXT: ret i1 [[T1]] 2243; 2244 %t0 = or i32 %x, 42 2245 %t1 = icmp eq i32 %t0, 42 2246 ret i1 %t1 2247} 2248 2249; X | C == C --> (X & ~C) == 0 2250 2251define <2 x i1> @orC_eqC_vec(<2 x i8> %x) { 2252; CHECK-LABEL: @orC_eqC_vec( 2253; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44> 2254; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer 2255; CHECK-NEXT: ret <2 x i1> [[T1]] 2256; 2257 %t0 = or <2 x i8> %x, <i8 43, i8 43> 2258 %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43> 2259 ret <2 x i1> %t1 2260} 2261 2262; X | C != C --> (X & ~C) != 0 2263 2264define i1 @orC_neC(i32 %x) { 2265; CHECK-LABEL: @orC_neC( 2266; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 41 2267; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[TMP1]], 0 2268; CHECK-NEXT: ret i1 [[T1]] 2269; 2270 %t0 = or i32 %x, -42 2271 %t1 = icmp ne i32 %t0, -42 2272 ret i1 %t1 2273} 2274 2275; X | C != C --> (X & ~C) != 0 2276 2277define <2 x i1> @orC_neC_vec(<2 x i8> %x) { 2278; CHECK-LABEL: @orC_neC_vec( 2279; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42> 2280; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer 2281; CHECK-NEXT: ret <2 x i1> [[T1]] 2282; 2283 %t0 = or <2 x i8> %x, <i8 -43, i8 -43> 2284 %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43> 2285 ret <2 x i1> %t1 2286} 2287 2288define i1 @shrink_constant(i32 %X) { 2289; CHECK-LABEL: @shrink_constant( 2290; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], -12 2291; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[XOR]], 4 2292; CHECK-NEXT: ret i1 [[CMP]] 2293; 2294 %xor = xor i32 %X, -9 2295 %cmp = icmp ult i32 %xor, 4 2296 ret i1 %cmp 2297} 2298 2299define <2 x i1> @shrink_constant_vec(<2 x i32> %X) { 2300; CHECK-LABEL: @shrink_constant_vec( 2301; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12> 2302; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4> 2303; CHECK-NEXT: ret <2 x i1> [[CMP]] 2304; 2305 %xor = xor <2 x i32> %X, <i32 -9, i32 -9> 2306 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4> 2307 ret <2 x i1> %cmp 2308} 2309 2310; This test requires 3 different transforms to get to the result. 2311define i1 @icmp_sub_-1_X_ult_4(i32 %X) { 2312; CHECK-LABEL: @icmp_sub_-1_X_ult_4( 2313; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5 2314; CHECK-NEXT: ret i1 [[CMP]] 2315; 2316 %sub = sub i32 -1, %X 2317 %cmp = icmp ult i32 %sub, 4 2318 ret i1 %cmp 2319} 2320 2321define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) { 2322; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec( 2323; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5> 2324; CHECK-NEXT: ret <2 x i1> [[CMP]] 2325; 2326 %xor = xor <2 x i32> %X, <i32 -4, i32 -4> 2327 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4> 2328 ret <2 x i1> %cmp 2329} 2330 2331define i1 @icmp_sub_-1_X_uge_4(i32 %X) { 2332; CHECK-LABEL: @icmp_sub_-1_X_uge_4( 2333; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4 2334; CHECK-NEXT: ret i1 [[CMP]] 2335; 2336 %sub = sub i32 -1, %X 2337 %cmp = icmp uge i32 %sub, 4 2338 ret i1 %cmp 2339} 2340 2341define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) { 2342; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec( 2343; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4> 2344; CHECK-NEXT: ret <2 x i1> [[CMP]] 2345; 2346 %xor = xor <2 x i32> %X, <i32 -4, i32 -4> 2347 %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4> 2348 ret <2 x i1> %cmp 2349} 2350 2351define <2 x i1> @xor_ult(<2 x i8> %x) { 2352; CHECK-LABEL: @xor_ult( 2353; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3> 2354; CHECK-NEXT: ret <2 x i1> [[R]] 2355; 2356 %xor = xor <2 x i8> %x, <i8 -4, i8 -4> 2357 %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4> 2358 ret <2 x i1> %r 2359} 2360 2361define i1 @xor_ult_extra_use(i8 %x, i8* %p) { 2362; CHECK-LABEL: @xor_ult_extra_use( 2363; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32 2364; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1 2365; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31 2366; CHECK-NEXT: ret i1 [[R]] 2367; 2368 %xor = xor i8 %x, -32 2369 store i8 %xor, i8* %p 2370 %r = icmp ult i8 %xor, -32 2371 ret i1 %r 2372} 2373 2374define <2 x i1> @xor_ugt(<2 x i8> %x) { 2375; CHECK-LABEL: @xor_ugt( 2376; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7> 2377; CHECK-NEXT: ret <2 x i1> [[R]] 2378; 2379 %xor = xor <2 x i8> %x, <i8 7, i8 7> 2380 %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7> 2381 ret <2 x i1> %r 2382} 2383 2384define i1 @xor_ugt_extra_use(i8 %x, i8* %p) { 2385; CHECK-LABEL: @xor_ugt_extra_use( 2386; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63 2387; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1 2388; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63 2389; CHECK-NEXT: ret i1 [[R]] 2390; 2391 %xor = xor i8 %x, 63 2392 store i8 %xor, i8* %p 2393 %r = icmp ugt i8 %xor, 63 2394 ret i1 %r 2395} 2396 2397define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) { 2398; CHECK-LABEL: @icmp_swap_operands_for_cse( 2399; CHECK-NEXT: entry: 2400; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 2401; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]] 2402; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2403; CHECK: true: 2404; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[SUB]], 1 2405; CHECK-NEXT: br label [[END:%.*]] 2406; CHECK: false: 2407; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SUB]], 16 2408; CHECK-NEXT: br label [[END]] 2409; CHECK: end: 2410; CHECK-NEXT: [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ] 2411; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2412; CHECK-NEXT: ret i1 [[RES]] 2413; 2414entry: 2415 %sub = sub i32 %X, %Y 2416 %cmp = icmp ugt i32 %Y, %X 2417 br i1 %cmp, label %true, label %false 2418true: 2419 %restrue = trunc i32 %sub to i1 2420 br label %end 2421false: 2422 %shift = lshr i32 %sub, 4 2423 %resfalse = trunc i32 %shift to i1 2424 br label %end 2425end: 2426 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2427 ret i1 %res 2428} 2429 2430define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) { 2431; CHECK-LABEL: @icmp_swap_operands_for_cse2( 2432; CHECK-NEXT: entry: 2433; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2434; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2435; CHECK: true: 2436; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]] 2437; CHECK-NEXT: [[SUB1:%.*]] = sub i32 [[X]], [[Y]] 2438; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]] 2439; CHECK-NEXT: br label [[END:%.*]] 2440; CHECK: false: 2441; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]] 2442; CHECK-NEXT: br label [[END]] 2443; CHECK: end: 2444; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ] 2445; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1 2446; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2447; CHECK-NEXT: ret i1 [[RES]] 2448; 2449entry: 2450 %cmp = icmp ugt i32 %Y, %X 2451 br i1 %cmp, label %true, label %false 2452true: 2453 %sub = sub i32 %X, %Y 2454 %sub1 = sub i32 %X, %Y 2455 %add = add i32 %sub, %sub1 2456 %restrue = trunc i32 %add to i1 2457 br label %end 2458false: 2459 %sub2 = sub i32 %Y, %X 2460 %resfalse = trunc i32 %sub2 to i1 2461 br label %end 2462end: 2463 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2464 ret i1 %res 2465} 2466 2467define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) { 2468; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse( 2469; CHECK-NEXT: entry: 2470; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]] 2471; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2472; CHECK: true: 2473; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]] 2474; CHECK-NEXT: br label [[END:%.*]] 2475; CHECK: false: 2476; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]] 2477; CHECK-NEXT: br label [[END]] 2478; CHECK: end: 2479; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ] 2480; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1 2481; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2482; CHECK-NEXT: ret i1 [[RES]] 2483; 2484entry: 2485 %cmp = icmp ugt i32 %Y, %X 2486 br i1 %cmp, label %true, label %false 2487true: 2488 %sub = sub i32 %X, %Y 2489 %restrue = trunc i32 %sub to i1 2490 br label %end 2491false: 2492 %sub2 = sub i32 %Y, %X 2493 %resfalse = trunc i32 %sub2 to i1 2494 br label %end 2495end: 2496 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2497 ret i1 %res 2498} 2499 2500define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) { 2501; CHECK-LABEL: @icmp_lshr_lshr_eq( 2502; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 2503; CHECK-NEXT: [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824 2504; CHECK-NEXT: ret i1 [[Z]] 2505; 2506 %x = lshr i32 %a, 30 2507 %y = lshr i32 %b, 30 2508 %z = icmp eq i32 %x, %y 2509 ret i1 %z 2510} 2511 2512define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) { 2513; CHECK-LABEL: @icmp_ashr_ashr_ne( 2514; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 2515; CHECK-NEXT: [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255 2516; CHECK-NEXT: ret i1 [[Z]] 2517; 2518 %x = ashr i32 %a, 8 2519 %y = ashr i32 %b, 8 2520 %z = icmp ne i32 %x, %y 2521 ret i1 %z 2522} 2523 2524define i1 @icmp_neg_cst_slt(i32 %a) { 2525; CHECK-LABEL: @icmp_neg_cst_slt( 2526; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10 2527; CHECK-NEXT: ret i1 [[TMP1]] 2528; 2529 %1 = sub nsw i32 0, %a 2530 %2 = icmp slt i32 %1, -10 2531 ret i1 %2 2532} 2533 2534define i1 @icmp_and_or_lshr(i32 %x, i32 %y) { 2535; CHECK-LABEL: @icmp_and_or_lshr( 2536; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]] 2537; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1 2538; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]] 2539; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0 2540; CHECK-NEXT: ret i1 [[RET]] 2541; 2542 %shf = lshr i32 %x, %y 2543 %or = or i32 %shf, %x 2544 %and = and i32 %or, 1 2545 %ret = icmp ne i32 %and, 0 2546 ret i1 %ret 2547} 2548 2549define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) { 2550; CHECK-LABEL: @icmp_and_or_lshr_vec( 2551; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]] 2552; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]] 2553; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1> 2554; CHECK-NEXT: ret <2 x i1> [[RET]] 2555; 2556 %shf = lshr <2 x i32> %x, %y 2557 %or = or <2 x i32> %shf, %x 2558 %and = and <2 x i32> %or, <i32 1, i32 1> 2559 %ret = icmp ne <2 x i32> %and, zeroinitializer 2560 ret <2 x i1> %ret 2561} 2562 2563define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) { 2564; CHECK-LABEL: @icmp_and_or_lshr_vec_commute( 2565; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2566; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]] 2567; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]] 2568; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1> 2569; CHECK-NEXT: ret <2 x i1> [[RET]] 2570; 2571 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2572 %shf = lshr <2 x i32> %x, %y 2573 %or = or <2 x i32> %x, %shf 2574 %and = and <2 x i32> %or, <i32 1, i32 1> 2575 %ret = icmp ne <2 x i32> %and, zeroinitializer 2576 ret <2 x i1> %ret 2577} 2578 2579define i1 @icmp_and_or_lshr_cst(i32 %x) { 2580; CHECK-LABEL: @icmp_and_or_lshr_cst( 2581; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], 3 2582; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND1]], 0 2583; CHECK-NEXT: ret i1 [[RET]] 2584; 2585 %shf = lshr i32 %x, 1 2586 %or = or i32 %shf, %x 2587 %and = and i32 %or, 1 2588 %ret = icmp ne i32 %and, 0 2589 ret i1 %ret 2590} 2591 2592define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) { 2593; CHECK-LABEL: @icmp_and_or_lshr_cst_vec( 2594; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3> 2595; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2596; CHECK-NEXT: ret <2 x i1> [[RET]] 2597; 2598 %shf = lshr <2 x i32> %x, <i32 1, i32 1> 2599 %or = or <2 x i32> %shf, %x 2600 %and = and <2 x i32> %or, <i32 1, i32 1> 2601 %ret = icmp ne <2 x i32> %and, zeroinitializer 2602 ret <2 x i1> %ret 2603} 2604 2605define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) { 2606; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute( 2607; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2608; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3> 2609; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2610; CHECK-NEXT: ret <2 x i1> [[RET]] 2611; 2612 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2613 %shf = lshr <2 x i32> %x, <i32 1, i32 1> 2614 %or = or <2 x i32> %x, %shf 2615 %and = and <2 x i32> %or, <i32 1, i32 1> 2616 %ret = icmp ne <2 x i32> %and, zeroinitializer 2617 ret <2 x i1> %ret 2618} 2619 2620define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) { 2621; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2( 2622; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29 2623; CHECK-NEXT: ret i1 [[CMP]] 2624; 2625 %shl = shl i32 4, %a 2626 %cmp = icmp eq i32 %shl, 0 2627 ret i1 %cmp 2628} 2629 2630define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) { 2631; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec( 2632; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29> 2633; CHECK-NEXT: ret <2 x i1> [[CMP]] 2634; 2635 %shl = shl <2 x i32> <i32 4, i32 4>, %a 2636 %cmp = icmp eq <2 x i32> %shl, zeroinitializer 2637 ret <2 x i1> %cmp 2638} 2639 2640define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) { 2641; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4( 2642; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30 2643; CHECK-NEXT: ret i1 [[CMP]] 2644; 2645 %shl = shl i32 -2, %a 2646 %cmp = icmp eq i32 %shl, 0 2647 ret i1 %cmp 2648} 2649 2650define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) { 2651; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive( 2652; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 2653; CHECK-NEXT: ret i1 [[CMP]] 2654; 2655 %shl = shl i32 50, %a 2656 %cmp = icmp eq i32 %shl, 50 2657 ret i1 %cmp 2658} 2659 2660define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) { 2661; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative( 2662; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 2663; CHECK-NEXT: ret i1 [[CMP]] 2664; 2665 %shl = shl i32 -50, %a 2666 %cmp = icmp eq i32 %shl, -50 2667 ret i1 %cmp 2668} 2669 2670define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) { 2671; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1( 2672; CHECK-NEXT: ret i1 false 2673; 2674 %shl = shl i32 50, %a 2675 %cmp = icmp eq i32 %shl, 25 2676 ret i1 %cmp 2677} 2678 2679define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) { 2680; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2( 2681; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1 2682; CHECK-NEXT: ret i1 [[CMP]] 2683; 2684 %shl = shl i32 25, %a 2685 %cmp = icmp eq i32 %shl, 50 2686 ret i1 %cmp 2687} 2688 2689define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) { 2690; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3( 2691; CHECK-NEXT: ret i1 false 2692; 2693 %shl = shl i32 26, %a 2694 %cmp = icmp eq i32 %shl, 50 2695 ret i1 %cmp 2696} 2697 2698define i1 @icmp_sgt_zero_add_nsw(i32 %a) { 2699; CHECK-LABEL: @icmp_sgt_zero_add_nsw( 2700; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1 2701; CHECK-NEXT: ret i1 [[CMP]] 2702; 2703 %add = add nsw i32 %a, 1 2704 %cmp = icmp sgt i32 %add, 0 2705 ret i1 %cmp 2706} 2707 2708define i1 @icmp_sge_zero_add_nsw(i32 %a) { 2709; CHECK-LABEL: @icmp_sge_zero_add_nsw( 2710; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2 2711; CHECK-NEXT: ret i1 [[CMP]] 2712; 2713 %add = add nsw i32 %a, 1 2714 %cmp = icmp sge i32 %add, 0 2715 ret i1 %cmp 2716} 2717 2718define i1 @icmp_sle_zero_add_nsw(i32 %a) { 2719; CHECK-LABEL: @icmp_sle_zero_add_nsw( 2720; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0 2721; CHECK-NEXT: ret i1 [[CMP]] 2722; 2723 %add = add nsw i32 %a, 1 2724 %cmp = icmp sle i32 %add, 0 2725 ret i1 %cmp 2726} 2727 2728define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) { 2729; CHECK-LABEL: @icmp_cmpxchg_strong( 2730; CHECK-NEXT: [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst 2731; CHECK-NEXT: [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1 2732; CHECK-NEXT: ret i1 [[ICMP]] 2733; 2734 %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst 2735 %xtrc = extractvalue { i32, i1 } %xchg, 0 2736 %icmp = icmp eq i32 %xtrc, %old_val 2737 ret i1 %icmp 2738} 2739 2740define i1 @f1(i64 %a, i64 %b) { 2741; CHECK-LABEL: @f1( 2742; CHECK-NEXT: [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]] 2743; CHECK-NEXT: ret i1 [[V]] 2744; 2745 %t = sub nsw i64 %a, %b 2746 %v = icmp sge i64 %t, 0 2747 ret i1 %v 2748} 2749 2750define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) { 2751; CHECK-LABEL: @f1_vec( 2752; CHECK-NEXT: [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]] 2753; CHECK-NEXT: ret <2 x i1> [[V]] 2754; 2755 %t = sub nsw <2 x i64> %a, %b 2756 %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1> 2757 ret <2 x i1> %v 2758} 2759 2760define i1 @f2(i64 %a, i64 %b) { 2761; CHECK-LABEL: @f2( 2762; CHECK-NEXT: [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]] 2763; CHECK-NEXT: ret i1 [[V]] 2764; 2765 %t = sub nsw i64 %a, %b 2766 %v = icmp sgt i64 %t, 0 2767 ret i1 %v 2768} 2769 2770define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) { 2771; CHECK-LABEL: @f2_vec( 2772; CHECK-NEXT: [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]] 2773; CHECK-NEXT: ret <2 x i1> [[V]] 2774; 2775 %t = sub nsw <2 x i64> %a, %b 2776 %v = icmp sgt <2 x i64> %t, zeroinitializer 2777 ret <2 x i1> %v 2778} 2779 2780define i1 @f3(i64 %a, i64 %b) { 2781; CHECK-LABEL: @f3( 2782; CHECK-NEXT: [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]] 2783; CHECK-NEXT: ret i1 [[V]] 2784; 2785 %t = sub nsw i64 %a, %b 2786 %v = icmp slt i64 %t, 0 2787 ret i1 %v 2788} 2789 2790define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) { 2791; CHECK-LABEL: @f3_vec( 2792; CHECK-NEXT: [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]] 2793; CHECK-NEXT: ret <2 x i1> [[V]] 2794; 2795 %t = sub nsw <2 x i64> %a, %b 2796 %v = icmp slt <2 x i64> %t, zeroinitializer 2797 ret <2 x i1> %v 2798} 2799 2800define i1 @f4(i64 %a, i64 %b) { 2801; CHECK-LABEL: @f4( 2802; CHECK-NEXT: [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]] 2803; CHECK-NEXT: ret i1 [[V]] 2804; 2805 %t = sub nsw i64 %a, %b 2806 %v = icmp sle i64 %t, 0 2807 ret i1 %v 2808} 2809 2810define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) { 2811; CHECK-LABEL: @f4_vec( 2812; CHECK-NEXT: [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]] 2813; CHECK-NEXT: ret <2 x i1> [[V]] 2814; 2815 %t = sub nsw <2 x i64> %a, %b 2816 %v = icmp slt <2 x i64> %t, <i64 1, i64 1> 2817 ret <2 x i1> %v 2818} 2819 2820define i32 @f5(i8 %a, i8 %b) { 2821; CHECK-LABEL: @f5( 2822; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 2823; CHECK-NEXT: [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32 2824; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]] 2825; CHECK-NEXT: [[CMP4:%.*]] = icmp slt i32 [[SUB]], 0 2826; CHECK-NEXT: [[SUB7:%.*]] = sub nsw i32 0, [[SUB]] 2827; CHECK-NEXT: [[SUB7_SUB:%.*]] = select i1 [[CMP4]], i32 [[SUB7]], i32 [[SUB]] 2828; CHECK-NEXT: ret i32 [[SUB7_SUB]] 2829; 2830 %conv = zext i8 %a to i32 2831 %conv3 = zext i8 %b to i32 2832 %sub = sub nsw i32 %conv, %conv3 2833 %cmp4 = icmp slt i32 %sub, 0 2834 %sub7 = sub nsw i32 0, %sub 2835 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub 2836 ret i32 %sub7.sub 2837} 2838 2839define i32 @f6(i32 %a, i32 %b) { 2840; CHECK-LABEL: @f6( 2841; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 2842; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255 2843; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0 2844; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0 2845; CHECK-NEXT: ret i32 [[S]] 2846; 2847 %sext = shl i32 %a, 24 2848 %conv = ashr i32 %sext, 24 2849 %sext6 = shl i32 %b, 24 2850 %conv4 = ashr i32 %sext6, 24 2851 %cmp = icmp eq i32 %conv, %conv4 2852 %s = select i1 %cmp, i32 10000, i32 0 2853 ret i32 %s 2854} 2855 2856define i32 @f7(i32 %a, i32 %b) { 2857; CHECK-LABEL: @f7( 2858; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 2859; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 511 2860; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0 2861; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 0, i32 10000 2862; CHECK-NEXT: ret i32 [[S]] 2863; 2864 %sext = shl i32 %a, 23 2865 %sext6 = shl i32 %b, 23 2866 %cmp = icmp ne i32 %sext, %sext6 2867 %s = select i1 %cmp, i32 10000, i32 0 2868 ret i32 %s 2869} 2870 2871define i1 @f8(i32 %val, i32 %lim) { 2872; CHECK-LABEL: @f8( 2873; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0 2874; CHECK-NEXT: ret i1 [[R]] 2875; 2876 %lim.sub = add i32 %lim, -1 2877 %val.and = and i32 %val, %lim.sub 2878 %r = icmp ult i32 %val.and, %lim 2879 ret i1 %r 2880} 2881 2882define i1 @f9(i32 %val, i32 %lim) { 2883; CHECK-LABEL: @f9( 2884; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0 2885; CHECK-NEXT: ret i1 [[R]] 2886; 2887 %lim.sub = sub i32 %lim, 1 2888 %val.and = and i32 %val, %lim.sub 2889 %r = icmp ult i32 %val.and, %lim 2890 ret i1 %r 2891} 2892 2893define i1 @f10(i16 %p) { 2894; CHECK-LABEL: @f10( 2895; CHECK-NEXT: [[CMP580:%.*]] = icmp uge i16 [[P:%.*]], mul (i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16), i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16)) 2896; CHECK-NEXT: ret i1 [[CMP580]] 2897; 2898 %cmp580 = icmp ule i16 mul (i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16), i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16)), %p 2899 ret i1 %cmp580 2900} 2901 2902; Note: fptosi is used in various tests below to ensure that operand complexity 2903; canonicalization does not kick in, which would make some of the tests 2904; equivalent to one another. 2905 2906define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) { 2907; CHECK-LABEL: @cmp_sgt_rhs_dec( 2908; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 2909; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]] 2910; CHECK-NEXT: ret i1 [[CMP]] 2911; 2912 %conv = fptosi float %x to i32 2913 %dec = sub nsw i32 %i, 1 2914 %cmp = icmp sgt i32 %conv, %dec 2915 ret i1 %cmp 2916} 2917 2918define i1 @cmp_sle_rhs_dec(float %x, i32 %i) { 2919; CHECK-LABEL: @cmp_sle_rhs_dec( 2920; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 2921; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]] 2922; CHECK-NEXT: ret i1 [[CMP]] 2923; 2924 %conv = fptosi float %x to i32 2925 %dec = sub nsw i32 %i, 1 2926 %cmp = icmp sle i32 %conv, %dec 2927 ret i1 %cmp 2928} 2929 2930define i1 @cmp_sge_rhs_inc(float %x, i32 %i) { 2931; CHECK-LABEL: @cmp_sge_rhs_inc( 2932; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 2933; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]] 2934; CHECK-NEXT: ret i1 [[CMP]] 2935; 2936 %conv = fptosi float %x to i32 2937 %inc = add nsw i32 %i, 1 2938 %cmp = icmp sge i32 %conv, %inc 2939 ret i1 %cmp 2940} 2941 2942define i1 @cmp_slt_rhs_inc(float %x, i32 %i) { 2943; CHECK-LABEL: @cmp_slt_rhs_inc( 2944; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 2945; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]] 2946; CHECK-NEXT: ret i1 [[CMP]] 2947; 2948 %conv = fptosi float %x to i32 2949 %inc = add nsw i32 %i, 1 2950 %cmp = icmp slt i32 %conv, %inc 2951 ret i1 %cmp 2952} 2953 2954define i1 @PR26407(i32 %x, i32 %y) { 2955; CHECK-LABEL: @PR26407( 2956; CHECK-NEXT: [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647 2957; CHECK-NEXT: [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647 2958; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]] 2959; CHECK-NEXT: ret i1 [[CMP]] 2960; 2961 %addx = add i32 %x, 2147483647 2962 %addy = add i32 %y, 2147483647 2963 %cmp = icmp uge i32 %addx, %addy 2964 ret i1 %cmp 2965} 2966 2967define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) { 2968; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq( 2969; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 2970; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43 2971; CHECK-NEXT: ret i1 [[CMP]] 2972; 2973 %or = or i32 %x, 42 2974 %cmp = icmp eq i32 %or, -1 2975 ret i1 %cmp 2976} 2977 2978define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) { 2979; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec( 2980; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43> 2981; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43> 2982; CHECK-NEXT: ret <2 x i1> [[CMP]] 2983; 2984 %or = or <2 x i32> %x, <i32 42, i32 42> 2985 %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1> 2986 ret <2 x i1> %cmp 2987} 2988 2989define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) { 2990; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne( 2991; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 2992; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43 2993; CHECK-NEXT: ret i1 [[CMP]] 2994; 2995 %or = or i32 %x, 42 2996 %cmp = icmp ne i32 %or, -1 2997 ret i1 %cmp 2998} 2999 3000; When canonicalizing to 'gt/lt', make sure the constant is correct. 3001 3002define i1 @PR27792(i128 %a) { 3003; CHECK-LABEL: @PR27792( 3004; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1 3005; CHECK-NEXT: ret i1 [[CMP]] 3006; 3007 %cmp = icmp sge i128 %a, 0 3008 ret i1 %cmp 3009} 3010 3011define i1 @PR27792_2(i128 %a) { 3012; CHECK-LABEL: @PR27792_2( 3013; CHECK-NEXT: [[B:%.*]] = icmp ne i128 [[A:%.*]], 0 3014; CHECK-NEXT: ret i1 [[B]] 3015; 3016 %b = icmp uge i128 %a, 1 3017 ret i1 %b 3018} 3019 3020define i1 @ugtMaxSignedVal(i8 %a) { 3021; CHECK-LABEL: @ugtMaxSignedVal( 3022; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0 3023; CHECK-NEXT: ret i1 [[CMP]] 3024; 3025 %cmp = icmp ugt i8 %a, 127 3026 ret i1 %cmp 3027} 3028 3029define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) { 3030; CHECK-LABEL: @ugtMaxSignedValVec( 3031; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer 3032; CHECK-NEXT: ret <2 x i1> [[CMP]] 3033; 3034 %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127> 3035 ret <2 x i1> %cmp 3036} 3037 3038define i1 @ugtKnownBits(i8 %a) { 3039; CHECK-LABEL: @ugtKnownBits( 3040; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 17 3041; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 17 3042; CHECK-NEXT: ret i1 [[CMP]] 3043; 3044 %b = and i8 %a, 17 3045 %cmp = icmp ugt i8 %b, 16 3046 ret i1 %cmp 3047} 3048 3049define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) { 3050; CHECK-LABEL: @ugtKnownBitsVec( 3051; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17> 3052; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17> 3053; CHECK-NEXT: ret <2 x i1> [[CMP]] 3054; 3055 %b = and <2 x i8> %a, <i8 17, i8 17> 3056 %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16> 3057 ret <2 x i1> %cmp 3058} 3059 3060define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) { 3061; CHECK-LABEL: @or_ptrtoint_mismatch( 3062; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null 3063; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null 3064; CHECK-NEXT: [[B:%.*]] = and i1 [[TMP1]], [[TMP2]] 3065; CHECK-NEXT: ret i1 [[B]] 3066; 3067 3068 %pp = ptrtoint i8* %p to i64 3069 %qq = ptrtoint i32* %q to i64 3070 %o = or i64 %pp, %qq 3071 %b = icmp eq i64 %o, 0 3072 ret i1 %b 3073} 3074 3075define i1 @icmp_add1_ugt(i32 %x, i32 %y) { 3076; CHECK-LABEL: @icmp_add1_ugt( 3077; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 3078; CHECK-NEXT: ret i1 [[CMP]] 3079; 3080 %add = add nuw i32 %x, 1 3081 %cmp = icmp ugt i32 %add, %y 3082 ret i1 %cmp 3083} 3084 3085define i1 @icmp_add1_ule(i32 %x, i32 %y) { 3086; CHECK-LABEL: @icmp_add1_ule( 3087; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 3088; CHECK-NEXT: ret i1 [[CMP]] 3089; 3090 %add = add nuw i32 %x, 1 3091 %cmp = icmp ule i32 %add, %y 3092 ret i1 %cmp 3093} 3094 3095define i1 @cmp_uge_rhs_inc(float %x, i32 %i) { 3096; CHECK-LABEL: @cmp_uge_rhs_inc( 3097; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3098; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]] 3099; CHECK-NEXT: ret i1 [[CMP]] 3100; 3101 %conv = fptosi float %x to i32 3102 %inc = add nuw i32 %i, 1 3103 %cmp = icmp uge i32 %conv, %inc 3104 ret i1 %cmp 3105} 3106 3107define i1 @cmp_ult_rhs_inc(float %x, i32 %i) { 3108; CHECK-LABEL: @cmp_ult_rhs_inc( 3109; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3110; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]] 3111; CHECK-NEXT: ret i1 [[CMP]] 3112; 3113 %conv = fptosi float %x to i32 3114 %inc = add nuw i32 %i, 1 3115 %cmp = icmp ult i32 %conv, %inc 3116 ret i1 %cmp 3117} 3118 3119define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) { 3120; CHECK-LABEL: @cmp_sge_lhs_inc( 3121; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[X:%.*]], 1 3122; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]] 3123; CHECK-NEXT: ret i1 [[CMP]] 3124; 3125 %inc = add nsw i32 %x, 1 3126 %cmp = icmp sge i32 %inc, %y 3127 ret i1 %cmp 3128} 3129 3130define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) { 3131; CHECK-LABEL: @cmp_uge_lhs_inc( 3132; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[X:%.*]], 1 3133; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]] 3134; CHECK-NEXT: ret i1 [[CMP]] 3135; 3136 %inc = add nuw i32 %x, 1 3137 %cmp = icmp uge i32 %inc, %y 3138 ret i1 %cmp 3139} 3140 3141define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) { 3142; CHECK-LABEL: @cmp_sgt_lhs_dec( 3143; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1 3144; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]] 3145; CHECK-NEXT: ret i1 [[CMP]] 3146; 3147 %dec = sub nsw i32 %x, 1 3148 %cmp = icmp sgt i32 %dec, %y 3149 ret i1 %cmp 3150} 3151 3152define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) { 3153; CHECK-LABEL: @cmp_ugt_lhs_dec( 3154; CHECK-NEXT: [[DEC:%.*]] = add i32 [[X:%.*]], -1 3155; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]] 3156; CHECK-NEXT: ret i1 [[CMP]] 3157; 3158 %dec = sub nuw i32 %x, 1 3159 %cmp = icmp ugt i32 %dec, %y 3160 ret i1 %cmp 3161} 3162 3163define i1 @cmp_sle_rhs_inc(float %x, i32 %y) { 3164; CHECK-LABEL: @cmp_sle_rhs_inc( 3165; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3166; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1 3167; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]] 3168; CHECK-NEXT: ret i1 [[CMP]] 3169; 3170 %conv = fptosi float %x to i32 3171 %inc = add nsw i32 %y, 1 3172 %cmp = icmp sle i32 %conv, %inc 3173 ret i1 %cmp 3174} 3175 3176define i1 @cmp_ule_rhs_inc(float %x, i32 %y) { 3177; CHECK-LABEL: @cmp_ule_rhs_inc( 3178; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3179; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1 3180; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]] 3181; CHECK-NEXT: ret i1 [[CMP]] 3182; 3183 %conv = fptosi float %x to i32 3184 %inc = add nuw i32 %y, 1 3185 %cmp = icmp ule i32 %conv, %inc 3186 ret i1 %cmp 3187} 3188 3189define i1 @cmp_slt_rhs_dec(float %x, i32 %y) { 3190; CHECK-LABEL: @cmp_slt_rhs_dec( 3191; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3192; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1 3193; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]] 3194; CHECK-NEXT: ret i1 [[CMP]] 3195; 3196 %conv = fptosi float %x to i32 3197 %dec = sub nsw i32 %y, 1 3198 %cmp = icmp slt i32 %conv, %dec 3199 ret i1 %cmp 3200} 3201 3202define i1 @cmp_ult_rhs_dec(float %x, i32 %y) { 3203; CHECK-LABEL: @cmp_ult_rhs_dec( 3204; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3205; CHECK-NEXT: [[DEC:%.*]] = add i32 [[Y:%.*]], -1 3206; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]] 3207; CHECK-NEXT: ret i1 [[CMP]] 3208; 3209 %conv = fptosi float %x to i32 3210 %dec = sub nuw i32 %y, 1 3211 %cmp = icmp ult i32 %conv, %dec 3212 ret i1 %cmp 3213} 3214 3215define i1 @eq_add_constants(i32 %x, i32 %y) { 3216; CHECK-LABEL: @eq_add_constants( 3217; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 3218; CHECK-NEXT: ret i1 [[C]] 3219; 3220 %A = add i32 %x, 5 3221 %B = add i32 %y, 5 3222 %C = icmp eq i32 %A, %B 3223 ret i1 %C 3224} 3225 3226define i1 @eq_mul_constants(i32 %x, i32 %y) { 3227; CHECK-LABEL: @eq_mul_constants( 3228; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 3229; CHECK-NEXT: ret i1 [[C]] 3230; 3231 %A = mul i32 %x, 5 3232 %B = mul i32 %y, 5 3233 %C = icmp eq i32 %A, %B 3234 ret i1 %C 3235} 3236 3237define <2 x i1> @eq_mul_constants_splat(<2 x i32> %x, <2 x i32> %y) { 3238; CHECK-LABEL: @eq_mul_constants_splat( 3239; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]] 3240; CHECK-NEXT: ret <2 x i1> [[C]] 3241; 3242 %A = mul <2 x i32> %x, <i32 5, i32 5> 3243 %B = mul <2 x i32> %y, <i32 5, i32 5> 3244 %C = icmp ne <2 x i32> %A, %B 3245 ret <2 x i1> %C 3246} 3247 3248; If the multiply constant has any trailing zero bits, we get something completely different. 3249; We mask off the high bits of each input and then convert: 3250; (X&Z) == (Y&Z) -> (X^Y) & Z == 0 3251 3252define i1 @eq_mul_constants_with_tz(i32 %x, i32 %y) { 3253; CHECK-LABEL: @eq_mul_constants_with_tz( 3254; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 3255; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823 3256; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[TMP2]], 0 3257; CHECK-NEXT: ret i1 [[C]] 3258; 3259 %A = mul i32 %x, 12 3260 %B = mul i32 %y, 12 3261 %C = icmp ne i32 %A, %B 3262 ret i1 %C 3263} 3264 3265define <2 x i1> @eq_mul_constants_with_tz_splat(<2 x i32> %x, <2 x i32> %y) { 3266; CHECK-LABEL: @eq_mul_constants_with_tz_splat( 3267; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]] 3268; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 1073741823, i32 1073741823> 3269; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer 3270; CHECK-NEXT: ret <2 x i1> [[C]] 3271; 3272 %A = mul <2 x i32> %x, <i32 12, i32 12> 3273 %B = mul <2 x i32> %y, <i32 12, i32 12> 3274 %C = icmp eq <2 x i32> %A, %B 3275 ret <2 x i1> %C 3276} 3277 3278declare i32 @llvm.bswap.i32(i32) 3279 3280define i1 @bswap_ne(i32 %x, i32 %y) { 3281; CHECK-LABEL: @bswap_ne( 3282; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 3283; CHECK-NEXT: ret i1 [[CMP]] 3284; 3285 %swapx = call i32 @llvm.bswap.i32(i32 %x) 3286 %swapy = call i32 @llvm.bswap.i32(i32 %y) 3287 %cmp = icmp ne i32 %swapx, %swapy 3288 ret i1 %cmp 3289} 3290 3291declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>) 3292 3293define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) { 3294; CHECK-LABEL: @bswap_vec_eq( 3295; CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]] 3296; CHECK-NEXT: ret <8 x i1> [[CMP]] 3297; 3298 %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x) 3299 %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y) 3300 %cmp = icmp eq <8 x i16> %swapx, %swapy 3301 ret <8 x i1> %cmp 3302} 3303 3304declare i64 @llvm.bitreverse.i64(i64) 3305 3306define i1 @bitreverse_eq(i64 %x, i64 %y) { 3307; CHECK-LABEL: @bitreverse_eq( 3308; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] 3309; CHECK-NEXT: ret i1 [[CMP]] 3310; 3311 %revx = call i64 @llvm.bitreverse.i64(i64 %x) 3312 %revy = call i64 @llvm.bitreverse.i64(i64 %y) 3313 %cmp = icmp eq i64 %revx, %revy 3314 ret i1 %cmp 3315} 3316 3317declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>) 3318 3319define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) { 3320; CHECK-LABEL: @bitreverse_vec_ne( 3321; CHECK-NEXT: [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]] 3322; CHECK-NEXT: ret <8 x i1> [[CMP]] 3323; 3324 %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x) 3325 %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y) 3326 %cmp = icmp ne <8 x i16> %revx, %revy 3327 ret <8 x i1> %cmp 3328} 3329 3330; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7. 3331; They should all simplify to equality compares. 3332define i1 @knownbits1(i8 %a, i8 %b) { 3333; CHECK-LABEL: @knownbits1( 3334; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3335; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3336; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3337; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3338; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]] 3339; CHECK-NEXT: ret i1 [[C]] 3340; 3341 %a1 = and i8 %a, 5 3342 %a2 = or i8 %a1, 4 3343 %b1 = and i8 %b, 7 3344 %b2 = or i8 %b1, 5 3345 %c = icmp uge i8 %a2, %b2 3346 ret i1 %c 3347} 3348 3349define i1 @knownbits2(i8 %a, i8 %b) { 3350; CHECK-LABEL: @knownbits2( 3351; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3352; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3353; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3354; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3355; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]] 3356; CHECK-NEXT: ret i1 [[C]] 3357; 3358 %a1 = and i8 %a, 5 3359 %a2 = or i8 %a1, 4 3360 %b1 = and i8 %b, 7 3361 %b2 = or i8 %b1, 5 3362 %c = icmp ult i8 %a2, %b2 3363 ret i1 %c 3364} 3365 3366define i1 @knownbits3(i8 %a, i8 %b) { 3367; CHECK-LABEL: @knownbits3( 3368; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3369; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3370; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3371; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3372; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B2]], [[A2]] 3373; CHECK-NEXT: ret i1 [[C]] 3374; 3375 %a1 = and i8 %a, 5 3376 %a2 = or i8 %a1, 4 3377 %b1 = and i8 %b, 7 3378 %b2 = or i8 %b1, 5 3379 %c = icmp ule i8 %b2, %a2 3380 ret i1 %c 3381} 3382 3383define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) { 3384; CHECK-LABEL: @knownbits4( 3385; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1> 3386; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4> 3387; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2> 3388; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5> 3389; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]] 3390; CHECK-NEXT: ret <2 x i1> [[C]] 3391; 3392 %a1 = and <2 x i8> %a, <i8 5, i8 5> 3393 %a2 = or <2 x i8> %a1, <i8 4, i8 4> 3394 %b1 = and <2 x i8> %b, <i8 7, i8 7> 3395 %b2 = or <2 x i8> %b1, <i8 5, i8 5> 3396 %c = icmp ugt <2 x i8> %b2, %a2 3397 ret <2 x i1> %c 3398} 3399 3400; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative. 3401; The other is known to be a value 5-7. These should simplify to equality comparisons. 3402define i1 @knownbits5(i8 %a, i8 %b) { 3403; CHECK-LABEL: @knownbits5( 3404; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3405; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3406; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3407; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3408; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]] 3409; CHECK-NEXT: ret i1 [[C]] 3410; 3411 %a1 = and i8 %a, 133 3412 %a2 = or i8 %a1, 4 3413 %b1 = and i8 %b, 7 3414 %b2 = or i8 %b1, 5 3415 %c = icmp sge i8 %a2, %b2 3416 ret i1 %c 3417} 3418 3419define i1 @knownbits6(i8 %a, i8 %b) { 3420; CHECK-LABEL: @knownbits6( 3421; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3422; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3423; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3424; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3425; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]] 3426; CHECK-NEXT: ret i1 [[C]] 3427; 3428 %a1 = and i8 %a, 133 3429 %a2 = or i8 %a1, 4 3430 %b1 = and i8 %b, 7 3431 %b2 = or i8 %b1, 5 3432 %c = icmp slt i8 %a2, %b2 3433 ret i1 %c 3434} 3435 3436define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) { 3437; CHECK-LABEL: @knownbits7( 3438; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127> 3439; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4> 3440; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2> 3441; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5> 3442; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]] 3443; CHECK-NEXT: ret <2 x i1> [[C]] 3444; 3445 %a1 = and <2 x i8> %a, <i8 133, i8 133> 3446 %a2 = or <2 x i8> %a1, <i8 4, i8 4> 3447 %b1 = and <2 x i8> %b, <i8 7, i8 7> 3448 %b2 = or <2 x i8> %b1, <i8 5, i8 5> 3449 %c = icmp sle <2 x i8> %b2, %a2 3450 ret <2 x i1> %c 3451} 3452 3453define i1 @knownbits8(i8 %a, i8 %b) { 3454; CHECK-LABEL: @knownbits8( 3455; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3456; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3457; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3458; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3459; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[B2]], [[A2]] 3460; CHECK-NEXT: ret i1 [[C]] 3461; 3462 %a1 = and i8 %a, 133 3463 %a2 = or i8 %a1, 4 3464 %b1 = and i8 %b, 7 3465 %b2 = or i8 %b1, 5 3466 %c = icmp sgt i8 %b2, %a2 3467 ret i1 %c 3468} 3469 3470; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom 3471define i32 @abs_preserve(i32 %x) { 3472; CHECK-LABEL: @abs_preserve( 3473; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X:%.*]], 1 3474; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A]], 0 3475; CHECK-NEXT: [[NEGA:%.*]] = sub i32 0, [[A]] 3476; CHECK-NEXT: [[ABS:%.*]] = select i1 [[C]], i32 [[NEGA]], i32 [[A]] 3477; CHECK-NEXT: ret i32 [[ABS]] 3478; 3479 %a = mul nsw i32 %x, 2 3480 %c = icmp sge i32 %a, 0 3481 %nega = sub i32 0, %a 3482 %abs = select i1 %c, i32 %a, i32 %nega 3483 ret i32 %abs 3484} 3485 3486; Don't crash by assuming the compared values are integers. 3487 3488declare void @llvm.assume(i1) 3489define i1 @PR35794(i32* %a) { 3490; CHECK-LABEL: @PR35794( 3491; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null 3492; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 3493; CHECK-NEXT: ret i1 true 3494; 3495 %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*) 3496 %maskcond = icmp eq i32* %a, null 3497 tail call void @llvm.assume(i1 %maskcond) 3498 ret i1 %cmp 3499} 3500 3501; Don't crash by assuming the compared values are integers. 3502define <2 x i1> @PR36583(<2 x i8*>) { 3503; CHECK-LABEL: @PR36583( 3504; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer 3505; CHECK-NEXT: ret <2 x i1> [[RES]] 3506; 3507 %cast = ptrtoint <2 x i8*> %0 to <2 x i64> 3508 %res = icmp eq <2 x i64> %cast, zeroinitializer 3509 ret <2 x i1> %res 3510} 3511 3512; fold (icmp pred (sub (0, X)) C1) for vec type 3513define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) { 3514; CHECK-LABEL: @Op1Negated_Vec( 3515; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]] 3516; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer 3517; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> [[X]] 3518; CHECK-NEXT: ret <2 x i32> [[COND]] 3519; 3520 %sub = sub nsw <2 x i32> zeroinitializer, %x 3521 %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1> 3522 %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x 3523 ret <2 x i32> %cond 3524} 3525