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