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