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:%.*]] = add i64 [[B:%.*]], -1 2236; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]] 2237; CHECK-NEXT: ret i1 [[TMP2]] 2238; 2239 %1 = icmp eq i64 %b, 0 2240 %2 = icmp ult i64 %a, %b 2241 %3 = select i1 %1, i1 true, i1 %2 2242 ret i1 %3 2243} 2244 2245define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) { 2246; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform( 2247; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1> 2248; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]] 2249; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2250; 2251 %1 = icmp eq <2 x i64> %b, zeroinitializer 2252 %2 = icmp ult <2 x i64> %a, %b 2253 %3 = or <2 x i1> %1, %2 2254 ret <2 x i1> %3 2255} 2256 2257define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_undef(<2 x i64> %a, <2 x i64> %b) { 2258; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_undef( 2259; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1> 2260; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]] 2261; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2262; 2263 %1 = icmp eq <2 x i64> %b, <i64 0, i64 undef> 2264 %2 = icmp ult <2 x i64> %a, %b 2265 %3 = or <2 x i1> %1, %2 2266 ret <2 x i1> %3 2267} 2268 2269define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) { 2270; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0( 2271; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]] 2272; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0 2273; CHECK-NEXT: ret i1 [[TMP2]] 2274; 2275 %1 = icmp ne i64 %a, 0 2276 %2 = icmp ne i64 %b, 0 2277 %3 = or i1 %1, %2 2278 ret i1 %3 2279} 2280 2281define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) { 2282; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_logical( 2283; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]] 2284; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0 2285; CHECK-NEXT: ret i1 [[TMP2]] 2286; 2287 %1 = icmp ne i64 %a, 0 2288 %2 = icmp ne i64 %b, 0 2289 %3 = select i1 %1, i1 true, i1 %2 2290 ret i1 %3 2291} 2292 2293define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) { 2294; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform( 2295; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]] 2296; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer 2297; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2298; 2299 %1 = icmp ne <2 x i64> %a, zeroinitializer 2300 %2 = icmp ne <2 x i64> %b, zeroinitializer 2301 %3 = or <2 x i1> %1, %2 2302 ret <2 x i1> %3 2303} 2304 2305define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_undef(<2 x i64> %a, <2 x i64> %b) { 2306; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_undef( 2307; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]] 2308; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer 2309; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2310; 2311 %1 = icmp ne <2 x i64> %a, <i64 0, i64 undef> 2312 %2 = icmp ne <2 x i64> %b, <i64 0, i64 undef> 2313 %3 = or <2 x i1> %1, %2 2314 ret <2 x i1> %3 2315} 2316 2317define i1 @icmp_add_ult_2(i32 %X) { 2318; CHECK-LABEL: @icmp_add_ult_2( 2319; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2320; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14 2321; CHECK-NEXT: ret i1 [[CMP]] 2322; 2323 %add = add i32 %X, -14 2324 %cmp = icmp ult i32 %add, 2 2325 ret i1 %cmp 2326} 2327 2328define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) { 2329; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec( 2330; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2331; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14> 2332; CHECK-NEXT: ret <2 x i1> [[CMP]] 2333; 2334 %add = add <2 x i32> %X, <i32 -14, i32 -14> 2335 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2> 2336 ret <2 x i1> %cmp 2337} 2338 2339define i1 @icmp_sub_3_X_ult_2(i32 %X) { 2340; CHECK-LABEL: @icmp_sub_3_X_ult_2( 2341; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2342; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 2 2343; CHECK-NEXT: ret i1 [[CMP]] 2344; 2345 %add = sub i32 3, %X 2346 %cmp = icmp ult i32 %add, 2 2347 ret i1 %cmp 2348} 2349 2350define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) { 2351; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec( 2352; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2353; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 2, i32 2> 2354; CHECK-NEXT: ret <2 x i1> [[CMP]] 2355; 2356 %add = sub <2 x i32> <i32 3, i32 3>, %X 2357 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2> 2358 ret <2 x i1> %cmp 2359} 2360 2361define i1 @icmp_add_X_-14_uge_2(i32 %X) { 2362; CHECK-LABEL: @icmp_add_X_-14_uge_2( 2363; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2364; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14 2365; CHECK-NEXT: ret i1 [[CMP]] 2366; 2367 %add = add i32 %X, -14 2368 %cmp = icmp uge i32 %add, 2 2369 ret i1 %cmp 2370} 2371 2372define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) { 2373; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec( 2374; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2375; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14> 2376; CHECK-NEXT: ret <2 x i1> [[CMP]] 2377; 2378 %add = add <2 x i32> %X, <i32 -14, i32 -14> 2379 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2> 2380 ret <2 x i1> %cmp 2381} 2382 2383define i1 @icmp_sub_3_X_uge_2(i32 %X) { 2384; CHECK-LABEL: @icmp_sub_3_X_uge_2( 2385; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2386; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 2 2387; CHECK-NEXT: ret i1 [[CMP]] 2388; 2389 %add = sub i32 3, %X 2390 %cmp = icmp uge i32 %add, 2 2391 ret i1 %cmp 2392} 2393 2394define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) { 2395; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec( 2396; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2397; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 2, i32 2> 2398; CHECK-NEXT: ret <2 x i1> [[CMP]] 2399; 2400 %add = sub <2 x i32> <i32 3, i32 3>, %X 2401 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2> 2402 ret <2 x i1> %cmp 2403} 2404 2405define i1 @icmp_and_X_-16_eq-16(i32 %X) { 2406; CHECK-LABEL: @icmp_and_X_-16_eq-16( 2407; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17 2408; CHECK-NEXT: ret i1 [[CMP]] 2409; 2410 %and = and i32 %X, -16 2411 %cmp = icmp eq i32 %and, -16 2412 ret i1 %cmp 2413} 2414 2415define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) { 2416; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec( 2417; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17> 2418; CHECK-NEXT: ret <2 x i1> [[CMP]] 2419; 2420 %and = and <2 x i32> %X, <i32 -16, i32 -16> 2421 %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16> 2422 ret <2 x i1> %cmp 2423} 2424 2425define i1 @icmp_and_X_-16_ne-16(i32 %X) { 2426; CHECK-LABEL: @icmp_and_X_-16_ne-16( 2427; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16 2428; CHECK-NEXT: ret i1 [[CMP]] 2429; 2430 %and = and i32 %X, -16 2431 %cmp = icmp ne i32 %and, -16 2432 ret i1 %cmp 2433} 2434 2435define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) { 2436; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec( 2437; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16> 2438; CHECK-NEXT: ret <2 x i1> [[CMP]] 2439; 2440 %and = and <2 x i32> %X, <i32 -16, i32 -16> 2441 %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16> 2442 ret <2 x i1> %cmp 2443} 2444 2445; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524 2446; X | C == C --> X <=u C (when C+1 is PowerOf2). 2447 2448define i1 @or1_eq1(i32 %x) { 2449; CHECK-LABEL: @or1_eq1( 2450; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2 2451; CHECK-NEXT: ret i1 [[T1]] 2452; 2453 %t0 = or i32 %x, 1 2454 %t1 = icmp eq i32 %t0, 1 2455 ret i1 %t1 2456} 2457 2458; X | C == C --> X <=u C (when C+1 is PowerOf2). 2459 2460define <2 x i1> @or3_eq3_vec(<2 x i8> %x) { 2461; CHECK-LABEL: @or3_eq3_vec( 2462; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4> 2463; CHECK-NEXT: ret <2 x i1> [[T1]] 2464; 2465 %t0 = or <2 x i8> %x, <i8 3, i8 3> 2466 %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3> 2467 ret <2 x i1> %t1 2468} 2469 2470; X | C != C --> X >u C (when C+1 is PowerOf2). 2471 2472define i1 @or7_ne7(i32 %x) { 2473; CHECK-LABEL: @or7_ne7( 2474; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7 2475; CHECK-NEXT: ret i1 [[T1]] 2476; 2477 %t0 = or i32 %x, 7 2478 %t1 = icmp ne i32 %t0, 7 2479 ret i1 %t1 2480} 2481 2482; X | C != C --> X >u C (when C+1 is PowerOf2). 2483 2484define <2 x i1> @or63_ne63_vec(<2 x i8> %x) { 2485; CHECK-LABEL: @or63_ne63_vec( 2486; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63> 2487; CHECK-NEXT: ret <2 x i1> [[T1]] 2488; 2489 %t0 = or <2 x i8> %x, <i8 63, i8 63> 2490 %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63> 2491 ret <2 x i1> %t1 2492} 2493 2494; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611 2495; X | C == C --> (X & ~C) == 0 2496 2497define i1 @orC_eqC(i32 %x) { 2498; CHECK-LABEL: @orC_eqC( 2499; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 2500; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[TMP1]], 0 2501; CHECK-NEXT: ret i1 [[T1]] 2502; 2503 %t0 = or i32 %x, 42 2504 %t1 = icmp eq i32 %t0, 42 2505 ret i1 %t1 2506} 2507 2508; X | C == C --> (X & ~C) == 0 2509 2510define <2 x i1> @orC_eqC_vec(<2 x i8> %x) { 2511; CHECK-LABEL: @orC_eqC_vec( 2512; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44> 2513; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer 2514; CHECK-NEXT: ret <2 x i1> [[T1]] 2515; 2516 %t0 = or <2 x i8> %x, <i8 43, i8 43> 2517 %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43> 2518 ret <2 x i1> %t1 2519} 2520 2521; X | C != C --> (X & ~C) != 0 2522 2523define i1 @orC_neC(i32 %x) { 2524; CHECK-LABEL: @orC_neC( 2525; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 41 2526; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[TMP1]], 0 2527; CHECK-NEXT: ret i1 [[T1]] 2528; 2529 %t0 = or i32 %x, -42 2530 %t1 = icmp ne i32 %t0, -42 2531 ret i1 %t1 2532} 2533 2534; X | C != C --> (X & ~C) != 0 2535 2536define <2 x i1> @orC_neC_vec(<2 x i8> %x) { 2537; CHECK-LABEL: @orC_neC_vec( 2538; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42> 2539; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer 2540; CHECK-NEXT: ret <2 x i1> [[T1]] 2541; 2542 %t0 = or <2 x i8> %x, <i8 -43, i8 -43> 2543 %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43> 2544 ret <2 x i1> %t1 2545} 2546 2547define i1 @shrink_constant(i32 %X) { 2548; CHECK-LABEL: @shrink_constant( 2549; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], -12 2550; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[XOR]], 4 2551; CHECK-NEXT: ret i1 [[CMP]] 2552; 2553 %xor = xor i32 %X, -9 2554 %cmp = icmp ult i32 %xor, 4 2555 ret i1 %cmp 2556} 2557 2558define <2 x i1> @shrink_constant_vec(<2 x i32> %X) { 2559; CHECK-LABEL: @shrink_constant_vec( 2560; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12> 2561; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4> 2562; CHECK-NEXT: ret <2 x i1> [[CMP]] 2563; 2564 %xor = xor <2 x i32> %X, <i32 -9, i32 -9> 2565 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4> 2566 ret <2 x i1> %cmp 2567} 2568 2569; This test requires 3 different transforms to get to the result. 2570define i1 @icmp_sub_-1_X_ult_4(i32 %X) { 2571; CHECK-LABEL: @icmp_sub_-1_X_ult_4( 2572; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5 2573; CHECK-NEXT: ret i1 [[CMP]] 2574; 2575 %sub = sub i32 -1, %X 2576 %cmp = icmp ult i32 %sub, 4 2577 ret i1 %cmp 2578} 2579 2580define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) { 2581; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec( 2582; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5> 2583; CHECK-NEXT: ret <2 x i1> [[CMP]] 2584; 2585 %xor = xor <2 x i32> %X, <i32 -4, i32 -4> 2586 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4> 2587 ret <2 x i1> %cmp 2588} 2589 2590define i1 @icmp_sub_-1_X_uge_4(i32 %X) { 2591; CHECK-LABEL: @icmp_sub_-1_X_uge_4( 2592; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4 2593; CHECK-NEXT: ret i1 [[CMP]] 2594; 2595 %sub = sub i32 -1, %X 2596 %cmp = icmp uge i32 %sub, 4 2597 ret i1 %cmp 2598} 2599 2600define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) { 2601; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec( 2602; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4> 2603; CHECK-NEXT: ret <2 x i1> [[CMP]] 2604; 2605 %xor = xor <2 x i32> %X, <i32 -4, i32 -4> 2606 %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4> 2607 ret <2 x i1> %cmp 2608} 2609 2610define <2 x i1> @xor_ult(<2 x i8> %x) { 2611; CHECK-LABEL: @xor_ult( 2612; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3> 2613; CHECK-NEXT: ret <2 x i1> [[R]] 2614; 2615 %xor = xor <2 x i8> %x, <i8 -4, i8 -4> 2616 %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4> 2617 ret <2 x i1> %r 2618} 2619 2620define i1 @xor_ult_extra_use(i8 %x, i8* %p) { 2621; CHECK-LABEL: @xor_ult_extra_use( 2622; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32 2623; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1 2624; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31 2625; CHECK-NEXT: ret i1 [[R]] 2626; 2627 %xor = xor i8 %x, -32 2628 store i8 %xor, i8* %p 2629 %r = icmp ult i8 %xor, -32 2630 ret i1 %r 2631} 2632 2633define <2 x i1> @xor_ugt(<2 x i8> %x) { 2634; CHECK-LABEL: @xor_ugt( 2635; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7> 2636; CHECK-NEXT: ret <2 x i1> [[R]] 2637; 2638 %xor = xor <2 x i8> %x, <i8 7, i8 7> 2639 %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7> 2640 ret <2 x i1> %r 2641} 2642 2643define i1 @xor_ugt_extra_use(i8 %x, i8* %p) { 2644; CHECK-LABEL: @xor_ugt_extra_use( 2645; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63 2646; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1 2647; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63 2648; CHECK-NEXT: ret i1 [[R]] 2649; 2650 %xor = xor i8 %x, 63 2651 store i8 %xor, i8* %p 2652 %r = icmp ugt i8 %xor, 63 2653 ret i1 %r 2654} 2655 2656define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) { 2657; CHECK-LABEL: @icmp_swap_operands_for_cse( 2658; CHECK-NEXT: entry: 2659; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 2660; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]] 2661; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2662; CHECK: true: 2663; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[SUB]], 1 2664; CHECK-NEXT: br label [[END:%.*]] 2665; CHECK: false: 2666; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SUB]], 16 2667; CHECK-NEXT: br label [[END]] 2668; CHECK: end: 2669; CHECK-NEXT: [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ] 2670; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2671; CHECK-NEXT: ret i1 [[RES]] 2672; 2673entry: 2674 %sub = sub i32 %X, %Y 2675 %cmp = icmp ugt i32 %Y, %X 2676 br i1 %cmp, label %true, label %false 2677true: 2678 %restrue = trunc i32 %sub to i1 2679 br label %end 2680false: 2681 %shift = lshr i32 %sub, 4 2682 %resfalse = trunc i32 %shift to i1 2683 br label %end 2684end: 2685 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2686 ret i1 %res 2687} 2688 2689define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) { 2690; CHECK-LABEL: @icmp_swap_operands_for_cse2( 2691; CHECK-NEXT: entry: 2692; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2693; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2694; CHECK: true: 2695; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]] 2696; CHECK-NEXT: [[SUB1:%.*]] = sub i32 [[X]], [[Y]] 2697; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]] 2698; CHECK-NEXT: br label [[END:%.*]] 2699; CHECK: false: 2700; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]] 2701; CHECK-NEXT: br label [[END]] 2702; CHECK: end: 2703; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ] 2704; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1 2705; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2706; CHECK-NEXT: ret i1 [[RES]] 2707; 2708entry: 2709 %cmp = icmp ugt i32 %Y, %X 2710 br i1 %cmp, label %true, label %false 2711true: 2712 %sub = sub i32 %X, %Y 2713 %sub1 = sub i32 %X, %Y 2714 %add = add i32 %sub, %sub1 2715 %restrue = trunc i32 %add to i1 2716 br label %end 2717false: 2718 %sub2 = sub i32 %Y, %X 2719 %resfalse = trunc i32 %sub2 to i1 2720 br label %end 2721end: 2722 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2723 ret i1 %res 2724} 2725 2726define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) { 2727; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse( 2728; CHECK-NEXT: entry: 2729; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]] 2730; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2731; CHECK: true: 2732; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]] 2733; CHECK-NEXT: br label [[END:%.*]] 2734; CHECK: false: 2735; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]] 2736; CHECK-NEXT: br label [[END]] 2737; CHECK: end: 2738; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ] 2739; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1 2740; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2741; CHECK-NEXT: ret i1 [[RES]] 2742; 2743entry: 2744 %cmp = icmp ugt i32 %Y, %X 2745 br i1 %cmp, label %true, label %false 2746true: 2747 %sub = sub i32 %X, %Y 2748 %restrue = trunc i32 %sub to i1 2749 br label %end 2750false: 2751 %sub2 = sub i32 %Y, %X 2752 %resfalse = trunc i32 %sub2 to i1 2753 br label %end 2754end: 2755 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2756 ret i1 %res 2757} 2758 2759define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) { 2760; CHECK-LABEL: @icmp_lshr_lshr_eq( 2761; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 2762; CHECK-NEXT: [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824 2763; CHECK-NEXT: ret i1 [[Z]] 2764; 2765 %x = lshr i32 %a, 30 2766 %y = lshr i32 %b, 30 2767 %z = icmp eq i32 %x, %y 2768 ret i1 %z 2769} 2770 2771define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) { 2772; CHECK-LABEL: @icmp_ashr_ashr_ne( 2773; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 2774; CHECK-NEXT: [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255 2775; CHECK-NEXT: ret i1 [[Z]] 2776; 2777 %x = ashr i32 %a, 8 2778 %y = ashr i32 %b, 8 2779 %z = icmp ne i32 %x, %y 2780 ret i1 %z 2781} 2782 2783define i1 @icmp_neg_cst_slt(i32 %a) { 2784; CHECK-LABEL: @icmp_neg_cst_slt( 2785; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10 2786; CHECK-NEXT: ret i1 [[TMP1]] 2787; 2788 %1 = sub nsw i32 0, %a 2789 %2 = icmp slt i32 %1, -10 2790 ret i1 %2 2791} 2792 2793define i1 @icmp_and_or_lshr(i32 %x, i32 %y) { 2794; CHECK-LABEL: @icmp_and_or_lshr( 2795; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]] 2796; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1 2797; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]] 2798; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0 2799; CHECK-NEXT: ret i1 [[RET]] 2800; 2801 %shf = lshr i32 %x, %y 2802 %or = or i32 %shf, %x 2803 %and = and i32 %or, 1 2804 %ret = icmp ne i32 %and, 0 2805 ret i1 %ret 2806} 2807 2808define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) { 2809; CHECK-LABEL: @icmp_and_or_lshr_vec( 2810; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]] 2811; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]] 2812; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1> 2813; CHECK-NEXT: ret <2 x i1> [[RET]] 2814; 2815 %shf = lshr <2 x i32> %x, %y 2816 %or = or <2 x i32> %shf, %x 2817 %and = and <2 x i32> %or, <i32 1, i32 1> 2818 %ret = icmp ne <2 x i32> %and, zeroinitializer 2819 ret <2 x i1> %ret 2820} 2821 2822define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) { 2823; CHECK-LABEL: @icmp_and_or_lshr_vec_commute( 2824; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2825; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]] 2826; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]] 2827; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1> 2828; CHECK-NEXT: ret <2 x i1> [[RET]] 2829; 2830 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2831 %shf = lshr <2 x i32> %x, %y 2832 %or = or <2 x i32> %x, %shf 2833 %and = and <2 x i32> %or, <i32 1, i32 1> 2834 %ret = icmp ne <2 x i32> %and, zeroinitializer 2835 ret <2 x i1> %ret 2836} 2837 2838define i1 @icmp_and_or_lshr_cst(i32 %x) { 2839; CHECK-LABEL: @icmp_and_or_lshr_cst( 2840; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], 3 2841; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND1]], 0 2842; CHECK-NEXT: ret i1 [[RET]] 2843; 2844 %shf = lshr i32 %x, 1 2845 %or = or i32 %shf, %x 2846 %and = and i32 %or, 1 2847 %ret = icmp ne i32 %and, 0 2848 ret i1 %ret 2849} 2850 2851define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) { 2852; CHECK-LABEL: @icmp_and_or_lshr_cst_vec( 2853; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3> 2854; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2855; CHECK-NEXT: ret <2 x i1> [[RET]] 2856; 2857 %shf = lshr <2 x i32> %x, <i32 1, i32 1> 2858 %or = or <2 x i32> %shf, %x 2859 %and = and <2 x i32> %or, <i32 1, i32 1> 2860 %ret = icmp ne <2 x i32> %and, zeroinitializer 2861 ret <2 x i1> %ret 2862} 2863 2864define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) { 2865; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform( 2866; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 5> 2867; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2868; CHECK-NEXT: ret <2 x i1> [[RET]] 2869; 2870 %shf = lshr <2 x i32> %x, <i32 1, i32 2> 2871 %or = or <2 x i32> %shf, %x 2872 %and = and <2 x i32> %or, <i32 1, i32 1> 2873 %ret = icmp ne <2 x i32> %and, zeroinitializer 2874 ret <2 x i1> %ret 2875} 2876 2877define <2 x i1> @icmp_and_or_lshr_cst_vec_undef(<2 x i32> %x) { 2878; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef( 2879; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 -1> 2880; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2881; CHECK-NEXT: ret <2 x i1> [[RET]] 2882; 2883 %shf = lshr <2 x i32> %x, <i32 1, i32 undef> 2884 %or = or <2 x i32> %shf, %x 2885 %and = and <2 x i32> %or, <i32 1, i32 1> 2886 %ret = icmp ne <2 x i32> %and, zeroinitializer 2887 ret <2 x i1> %ret 2888} 2889 2890define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) { 2891; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute( 2892; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2893; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3> 2894; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2895; CHECK-NEXT: ret <2 x i1> [[RET]] 2896; 2897 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2898 %shf = lshr <2 x i32> %x, <i32 1, i32 1> 2899 %or = or <2 x i32> %x, %shf 2900 %and = and <2 x i32> %or, <i32 1, i32 1> 2901 %ret = icmp ne <2 x i32> %and, zeroinitializer 2902 ret <2 x i1> %ret 2903} 2904 2905define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) { 2906; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform_commute( 2907; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2908; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5> 2909; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2910; CHECK-NEXT: ret <2 x i1> [[RET]] 2911; 2912 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2913 %shf = lshr <2 x i32> %x, <i32 1, i32 2> 2914 %or = or <2 x i32> %x, %shf 2915 %and = and <2 x i32> %or, <i32 1, i32 1> 2916 %ret = icmp ne <2 x i32> %and, zeroinitializer 2917 ret <2 x i1> %ret 2918} 2919 2920define <2 x i1> @icmp_and_or_lshr_cst_vec_undef_commute(<2 x i32> %xp) { 2921; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef_commute( 2922; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2923; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 -1> 2924; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2925; CHECK-NEXT: ret <2 x i1> [[RET]] 2926; 2927 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2928 %shf = lshr <2 x i32> %x, <i32 1, i32 undef> 2929 %or = or <2 x i32> %x, %shf 2930 %and = and <2 x i32> %or, <i32 1, i32 1> 2931 %ret = icmp ne <2 x i32> %and, zeroinitializer 2932 ret <2 x i1> %ret 2933} 2934 2935define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) { 2936; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2( 2937; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29 2938; CHECK-NEXT: ret i1 [[CMP]] 2939; 2940 %shl = shl i32 4, %a 2941 %cmp = icmp eq i32 %shl, 0 2942 ret i1 %cmp 2943} 2944 2945define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) { 2946; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec( 2947; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29> 2948; CHECK-NEXT: ret <2 x i1> [[CMP]] 2949; 2950 %shl = shl <2 x i32> <i32 4, i32 4>, %a 2951 %cmp = icmp eq <2 x i32> %shl, zeroinitializer 2952 ret <2 x i1> %cmp 2953} 2954 2955define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) { 2956; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform( 2957; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A:%.*]] 2958; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer 2959; CHECK-NEXT: ret <2 x i1> [[CMP]] 2960; 2961 %shl = shl <2 x i32> <i32 4, i32 5>, %a 2962 %cmp = icmp eq <2 x i32> %shl, zeroinitializer 2963 ret <2 x i1> %cmp 2964} 2965 2966define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) { 2967; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4( 2968; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30 2969; CHECK-NEXT: ret i1 [[CMP]] 2970; 2971 %shl = shl i32 -2, %a 2972 %cmp = icmp eq i32 %shl, 0 2973 ret i1 %cmp 2974} 2975 2976define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) { 2977; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive( 2978; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 2979; CHECK-NEXT: ret i1 [[CMP]] 2980; 2981 %shl = shl i32 50, %a 2982 %cmp = icmp eq i32 %shl, 50 2983 ret i1 %cmp 2984} 2985 2986define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) { 2987; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative( 2988; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 2989; CHECK-NEXT: ret i1 [[CMP]] 2990; 2991 %shl = shl i32 -50, %a 2992 %cmp = icmp eq i32 %shl, -50 2993 ret i1 %cmp 2994} 2995 2996define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) { 2997; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1( 2998; CHECK-NEXT: ret i1 false 2999; 3000 %shl = shl i32 50, %a 3001 %cmp = icmp eq i32 %shl, 25 3002 ret i1 %cmp 3003} 3004 3005define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) { 3006; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2( 3007; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1 3008; CHECK-NEXT: ret i1 [[CMP]] 3009; 3010 %shl = shl i32 25, %a 3011 %cmp = icmp eq i32 %shl, 50 3012 ret i1 %cmp 3013} 3014 3015define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) { 3016; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3( 3017; CHECK-NEXT: ret i1 false 3018; 3019 %shl = shl i32 26, %a 3020 %cmp = icmp eq i32 %shl, 50 3021 ret i1 %cmp 3022} 3023 3024define i1 @icmp_sgt_zero_add_nsw(i32 %a) { 3025; CHECK-LABEL: @icmp_sgt_zero_add_nsw( 3026; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1 3027; CHECK-NEXT: ret i1 [[CMP]] 3028; 3029 %add = add nsw i32 %a, 1 3030 %cmp = icmp sgt i32 %add, 0 3031 ret i1 %cmp 3032} 3033 3034define i1 @icmp_sge_zero_add_nsw(i32 %a) { 3035; CHECK-LABEL: @icmp_sge_zero_add_nsw( 3036; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2 3037; CHECK-NEXT: ret i1 [[CMP]] 3038; 3039 %add = add nsw i32 %a, 1 3040 %cmp = icmp sge i32 %add, 0 3041 ret i1 %cmp 3042} 3043 3044define i1 @icmp_sle_zero_add_nsw(i32 %a) { 3045; CHECK-LABEL: @icmp_sle_zero_add_nsw( 3046; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0 3047; CHECK-NEXT: ret i1 [[CMP]] 3048; 3049 %add = add nsw i32 %a, 1 3050 %cmp = icmp sle i32 %add, 0 3051 ret i1 %cmp 3052} 3053 3054define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) { 3055; CHECK-LABEL: @icmp_cmpxchg_strong( 3056; CHECK-NEXT: [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst 3057; CHECK-NEXT: [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1 3058; CHECK-NEXT: ret i1 [[ICMP]] 3059; 3060 %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst 3061 %xtrc = extractvalue { i32, i1 } %xchg, 0 3062 %icmp = icmp eq i32 %xtrc, %old_val 3063 ret i1 %icmp 3064} 3065 3066define i1 @f1(i64 %a, i64 %b) { 3067; CHECK-LABEL: @f1( 3068; CHECK-NEXT: [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]] 3069; CHECK-NEXT: ret i1 [[V]] 3070; 3071 %t = sub nsw i64 %a, %b 3072 %v = icmp sge i64 %t, 0 3073 ret i1 %v 3074} 3075 3076define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) { 3077; CHECK-LABEL: @f1_vec( 3078; CHECK-NEXT: [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]] 3079; CHECK-NEXT: ret <2 x i1> [[V]] 3080; 3081 %t = sub nsw <2 x i64> %a, %b 3082 %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1> 3083 ret <2 x i1> %v 3084} 3085 3086define i1 @f2(i64 %a, i64 %b) { 3087; CHECK-LABEL: @f2( 3088; CHECK-NEXT: [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]] 3089; CHECK-NEXT: ret i1 [[V]] 3090; 3091 %t = sub nsw i64 %a, %b 3092 %v = icmp sgt i64 %t, 0 3093 ret i1 %v 3094} 3095 3096define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) { 3097; CHECK-LABEL: @f2_vec( 3098; CHECK-NEXT: [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]] 3099; CHECK-NEXT: ret <2 x i1> [[V]] 3100; 3101 %t = sub nsw <2 x i64> %a, %b 3102 %v = icmp sgt <2 x i64> %t, zeroinitializer 3103 ret <2 x i1> %v 3104} 3105 3106define i1 @f3(i64 %a, i64 %b) { 3107; CHECK-LABEL: @f3( 3108; CHECK-NEXT: [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]] 3109; CHECK-NEXT: ret i1 [[V]] 3110; 3111 %t = sub nsw i64 %a, %b 3112 %v = icmp slt i64 %t, 0 3113 ret i1 %v 3114} 3115 3116define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) { 3117; CHECK-LABEL: @f3_vec( 3118; CHECK-NEXT: [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]] 3119; CHECK-NEXT: ret <2 x i1> [[V]] 3120; 3121 %t = sub nsw <2 x i64> %a, %b 3122 %v = icmp slt <2 x i64> %t, zeroinitializer 3123 ret <2 x i1> %v 3124} 3125 3126define i1 @f4(i64 %a, i64 %b) { 3127; CHECK-LABEL: @f4( 3128; CHECK-NEXT: [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]] 3129; CHECK-NEXT: ret i1 [[V]] 3130; 3131 %t = sub nsw i64 %a, %b 3132 %v = icmp sle i64 %t, 0 3133 ret i1 %v 3134} 3135 3136define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) { 3137; CHECK-LABEL: @f4_vec( 3138; CHECK-NEXT: [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]] 3139; CHECK-NEXT: ret <2 x i1> [[V]] 3140; 3141 %t = sub nsw <2 x i64> %a, %b 3142 %v = icmp slt <2 x i64> %t, <i64 1, i64 1> 3143 ret <2 x i1> %v 3144} 3145 3146define i32 @f5(i8 %a, i8 %b) { 3147; CHECK-LABEL: @f5( 3148; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 3149; CHECK-NEXT: [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32 3150; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]] 3151; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true) 3152; CHECK-NEXT: ret i32 [[TMP1]] 3153; 3154 %conv = zext i8 %a to i32 3155 %conv3 = zext i8 %b to i32 3156 %sub = sub nsw i32 %conv, %conv3 3157 %cmp4 = icmp slt i32 %sub, 0 3158 %sub7 = sub nsw i32 0, %sub 3159 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub 3160 ret i32 %sub7.sub 3161} 3162 3163define i32 @f6(i32 %a, i32 %b) { 3164; CHECK-LABEL: @f6( 3165; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 3166; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255 3167; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0 3168; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0 3169; CHECK-NEXT: ret i32 [[S]] 3170; 3171 %sext = shl i32 %a, 24 3172 %conv = ashr i32 %sext, 24 3173 %sext6 = shl i32 %b, 24 3174 %conv4 = ashr i32 %sext6, 24 3175 %cmp = icmp eq i32 %conv, %conv4 3176 %s = select i1 %cmp, i32 10000, i32 0 3177 ret i32 %s 3178} 3179 3180define i32 @f7(i32 %a, i32 %b) { 3181; CHECK-LABEL: @f7( 3182; CHECK-NEXT: [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 3183; CHECK-NEXT: [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 511 3184; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 0 3185; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 10000 3186; CHECK-NEXT: ret i32 [[S]] 3187; 3188 %sext = shl i32 %a, 23 3189 %sext6 = shl i32 %b, 23 3190 %cmp = icmp ne i32 %sext, %sext6 3191 %s = select i1 %cmp, i32 10000, i32 0 3192 ret i32 %s 3193} 3194 3195define i1 @f8(i32 %val, i32 %lim) { 3196; CHECK-LABEL: @f8( 3197; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0 3198; CHECK-NEXT: ret i1 [[R]] 3199; 3200 %lim.sub = add i32 %lim, -1 3201 %val.and = and i32 %val, %lim.sub 3202 %r = icmp ult i32 %val.and, %lim 3203 ret i1 %r 3204} 3205 3206define i1 @f9(i32 %val, i32 %lim) { 3207; CHECK-LABEL: @f9( 3208; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0 3209; CHECK-NEXT: ret i1 [[R]] 3210; 3211 %lim.sub = sub i32 %lim, 1 3212 %val.and = and i32 %val, %lim.sub 3213 %r = icmp ult i32 %val.and, %lim 3214 ret i1 %r 3215} 3216 3217define i1 @f10(i16 %p) { 3218; CHECK-LABEL: @f10( 3219; 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)) 3220; CHECK-NEXT: ret i1 [[CMP580]] 3221; 3222 %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 3223 ret i1 %cmp580 3224} 3225 3226; Note: fptosi is used in various tests below to ensure that operand complexity 3227; canonicalization does not kick in, which would make some of the tests 3228; equivalent to one another. 3229 3230define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) { 3231; CHECK-LABEL: @cmp_sgt_rhs_dec( 3232; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3233; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]] 3234; CHECK-NEXT: ret i1 [[CMP]] 3235; 3236 %conv = fptosi float %x to i32 3237 %dec = sub nsw i32 %i, 1 3238 %cmp = icmp sgt i32 %conv, %dec 3239 ret i1 %cmp 3240} 3241 3242define i1 @cmp_sle_rhs_dec(float %x, i32 %i) { 3243; CHECK-LABEL: @cmp_sle_rhs_dec( 3244; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3245; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]] 3246; CHECK-NEXT: ret i1 [[CMP]] 3247; 3248 %conv = fptosi float %x to i32 3249 %dec = sub nsw i32 %i, 1 3250 %cmp = icmp sle i32 %conv, %dec 3251 ret i1 %cmp 3252} 3253 3254define i1 @cmp_sge_rhs_inc(float %x, i32 %i) { 3255; CHECK-LABEL: @cmp_sge_rhs_inc( 3256; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3257; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]] 3258; CHECK-NEXT: ret i1 [[CMP]] 3259; 3260 %conv = fptosi float %x to i32 3261 %inc = add nsw i32 %i, 1 3262 %cmp = icmp sge i32 %conv, %inc 3263 ret i1 %cmp 3264} 3265 3266define i1 @cmp_slt_rhs_inc(float %x, i32 %i) { 3267; CHECK-LABEL: @cmp_slt_rhs_inc( 3268; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3269; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]] 3270; CHECK-NEXT: ret i1 [[CMP]] 3271; 3272 %conv = fptosi float %x to i32 3273 %inc = add nsw i32 %i, 1 3274 %cmp = icmp slt i32 %conv, %inc 3275 ret i1 %cmp 3276} 3277 3278define i1 @PR26407(i32 %x, i32 %y) { 3279; CHECK-LABEL: @PR26407( 3280; CHECK-NEXT: [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647 3281; CHECK-NEXT: [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647 3282; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]] 3283; CHECK-NEXT: ret i1 [[CMP]] 3284; 3285 %addx = add i32 %x, 2147483647 3286 %addy = add i32 %y, 2147483647 3287 %cmp = icmp uge i32 %addx, %addy 3288 ret i1 %cmp 3289} 3290 3291define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) { 3292; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq( 3293; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 3294; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43 3295; CHECK-NEXT: ret i1 [[CMP]] 3296; 3297 %or = or i32 %x, 42 3298 %cmp = icmp eq i32 %or, -1 3299 ret i1 %cmp 3300} 3301 3302define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) { 3303; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec( 3304; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43> 3305; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43> 3306; CHECK-NEXT: ret <2 x i1> [[CMP]] 3307; 3308 %or = or <2 x i32> %x, <i32 42, i32 42> 3309 %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1> 3310 ret <2 x i1> %cmp 3311} 3312 3313define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) { 3314; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne( 3315; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 3316; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43 3317; CHECK-NEXT: ret i1 [[CMP]] 3318; 3319 %or = or i32 %x, 42 3320 %cmp = icmp ne i32 %or, -1 3321 ret i1 %cmp 3322} 3323 3324; When canonicalizing to 'gt/lt', make sure the constant is correct. 3325 3326define i1 @PR27792(i128 %a) { 3327; CHECK-LABEL: @PR27792( 3328; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1 3329; CHECK-NEXT: ret i1 [[CMP]] 3330; 3331 %cmp = icmp sge i128 %a, 0 3332 ret i1 %cmp 3333} 3334 3335define i1 @PR27792_2(i128 %a) { 3336; CHECK-LABEL: @PR27792_2( 3337; CHECK-NEXT: [[B:%.*]] = icmp ne i128 [[A:%.*]], 0 3338; CHECK-NEXT: ret i1 [[B]] 3339; 3340 %b = icmp uge i128 %a, 1 3341 ret i1 %b 3342} 3343 3344define i1 @ugtMaxSignedVal(i8 %a) { 3345; CHECK-LABEL: @ugtMaxSignedVal( 3346; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0 3347; CHECK-NEXT: ret i1 [[CMP]] 3348; 3349 %cmp = icmp ugt i8 %a, 127 3350 ret i1 %cmp 3351} 3352 3353define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) { 3354; CHECK-LABEL: @ugtMaxSignedValVec( 3355; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer 3356; CHECK-NEXT: ret <2 x i1> [[CMP]] 3357; 3358 %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127> 3359 ret <2 x i1> %cmp 3360} 3361 3362define i1 @ugtKnownBits(i8 %a) { 3363; CHECK-LABEL: @ugtKnownBits( 3364; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 17 3365; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 17 3366; CHECK-NEXT: ret i1 [[CMP]] 3367; 3368 %b = and i8 %a, 17 3369 %cmp = icmp ugt i8 %b, 16 3370 ret i1 %cmp 3371} 3372 3373define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) { 3374; CHECK-LABEL: @ugtKnownBitsVec( 3375; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17> 3376; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17> 3377; CHECK-NEXT: ret <2 x i1> [[CMP]] 3378; 3379 %b = and <2 x i8> %a, <i8 17, i8 17> 3380 %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16> 3381 ret <2 x i1> %cmp 3382} 3383 3384define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) { 3385; CHECK-LABEL: @or_ptrtoint_mismatch( 3386; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null 3387; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null 3388; CHECK-NEXT: [[B:%.*]] = and i1 [[TMP1]], [[TMP2]] 3389; CHECK-NEXT: ret i1 [[B]] 3390; 3391 3392 %pp = ptrtoint i8* %p to i64 3393 %qq = ptrtoint i32* %q to i64 3394 %o = or i64 %pp, %qq 3395 %b = icmp eq i64 %o, 0 3396 ret i1 %b 3397} 3398 3399define i1 @icmp_add1_ugt(i32 %x, i32 %y) { 3400; CHECK-LABEL: @icmp_add1_ugt( 3401; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 3402; CHECK-NEXT: ret i1 [[CMP]] 3403; 3404 %add = add nuw i32 %x, 1 3405 %cmp = icmp ugt i32 %add, %y 3406 ret i1 %cmp 3407} 3408 3409define i1 @icmp_add1_ule(i32 %x, i32 %y) { 3410; CHECK-LABEL: @icmp_add1_ule( 3411; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 3412; CHECK-NEXT: ret i1 [[CMP]] 3413; 3414 %add = add nuw i32 %x, 1 3415 %cmp = icmp ule i32 %add, %y 3416 ret i1 %cmp 3417} 3418 3419define i1 @cmp_uge_rhs_inc(float %x, i32 %i) { 3420; CHECK-LABEL: @cmp_uge_rhs_inc( 3421; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3422; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]] 3423; CHECK-NEXT: ret i1 [[CMP]] 3424; 3425 %conv = fptosi float %x to i32 3426 %inc = add nuw i32 %i, 1 3427 %cmp = icmp uge i32 %conv, %inc 3428 ret i1 %cmp 3429} 3430 3431define i1 @cmp_ult_rhs_inc(float %x, i32 %i) { 3432; CHECK-LABEL: @cmp_ult_rhs_inc( 3433; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3434; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]] 3435; CHECK-NEXT: ret i1 [[CMP]] 3436; 3437 %conv = fptosi float %x to i32 3438 %inc = add nuw i32 %i, 1 3439 %cmp = icmp ult i32 %conv, %inc 3440 ret i1 %cmp 3441} 3442 3443define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) { 3444; CHECK-LABEL: @cmp_sge_lhs_inc( 3445; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[X:%.*]], 1 3446; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]] 3447; CHECK-NEXT: ret i1 [[CMP]] 3448; 3449 %inc = add nsw i32 %x, 1 3450 %cmp = icmp sge i32 %inc, %y 3451 ret i1 %cmp 3452} 3453 3454define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) { 3455; CHECK-LABEL: @cmp_uge_lhs_inc( 3456; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[X:%.*]], 1 3457; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]] 3458; CHECK-NEXT: ret i1 [[CMP]] 3459; 3460 %inc = add nuw i32 %x, 1 3461 %cmp = icmp uge i32 %inc, %y 3462 ret i1 %cmp 3463} 3464 3465define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) { 3466; CHECK-LABEL: @cmp_sgt_lhs_dec( 3467; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1 3468; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]] 3469; CHECK-NEXT: ret i1 [[CMP]] 3470; 3471 %dec = sub nsw i32 %x, 1 3472 %cmp = icmp sgt i32 %dec, %y 3473 ret i1 %cmp 3474} 3475 3476define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) { 3477; CHECK-LABEL: @cmp_ugt_lhs_dec( 3478; CHECK-NEXT: [[DEC:%.*]] = add i32 [[X:%.*]], -1 3479; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]] 3480; CHECK-NEXT: ret i1 [[CMP]] 3481; 3482 %dec = sub nuw i32 %x, 1 3483 %cmp = icmp ugt i32 %dec, %y 3484 ret i1 %cmp 3485} 3486 3487define i1 @cmp_sle_rhs_inc(float %x, i32 %y) { 3488; CHECK-LABEL: @cmp_sle_rhs_inc( 3489; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3490; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1 3491; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]] 3492; CHECK-NEXT: ret i1 [[CMP]] 3493; 3494 %conv = fptosi float %x to i32 3495 %inc = add nsw i32 %y, 1 3496 %cmp = icmp sle i32 %conv, %inc 3497 ret i1 %cmp 3498} 3499 3500define i1 @cmp_ule_rhs_inc(float %x, i32 %y) { 3501; CHECK-LABEL: @cmp_ule_rhs_inc( 3502; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3503; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1 3504; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]] 3505; CHECK-NEXT: ret i1 [[CMP]] 3506; 3507 %conv = fptosi float %x to i32 3508 %inc = add nuw i32 %y, 1 3509 %cmp = icmp ule i32 %conv, %inc 3510 ret i1 %cmp 3511} 3512 3513define i1 @cmp_slt_rhs_dec(float %x, i32 %y) { 3514; CHECK-LABEL: @cmp_slt_rhs_dec( 3515; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3516; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1 3517; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]] 3518; CHECK-NEXT: ret i1 [[CMP]] 3519; 3520 %conv = fptosi float %x to i32 3521 %dec = sub nsw i32 %y, 1 3522 %cmp = icmp slt i32 %conv, %dec 3523 ret i1 %cmp 3524} 3525 3526define i1 @cmp_ult_rhs_dec(float %x, i32 %y) { 3527; CHECK-LABEL: @cmp_ult_rhs_dec( 3528; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3529; CHECK-NEXT: [[DEC:%.*]] = add i32 [[Y:%.*]], -1 3530; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]] 3531; CHECK-NEXT: ret i1 [[CMP]] 3532; 3533 %conv = fptosi float %x to i32 3534 %dec = sub nuw i32 %y, 1 3535 %cmp = icmp ult i32 %conv, %dec 3536 ret i1 %cmp 3537} 3538 3539define i1 @eq_add_constants(i32 %x, i32 %y) { 3540; CHECK-LABEL: @eq_add_constants( 3541; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 3542; CHECK-NEXT: ret i1 [[C]] 3543; 3544 %A = add i32 %x, 5 3545 %B = add i32 %y, 5 3546 %C = icmp eq i32 %A, %B 3547 ret i1 %C 3548} 3549 3550declare i32 @llvm.bswap.i32(i32) 3551 3552define i1 @bswap_ne(i32 %x, i32 %y) { 3553; CHECK-LABEL: @bswap_ne( 3554; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 3555; CHECK-NEXT: ret i1 [[CMP]] 3556; 3557 %swapx = call i32 @llvm.bswap.i32(i32 %x) 3558 %swapy = call i32 @llvm.bswap.i32(i32 %y) 3559 %cmp = icmp ne i32 %swapx, %swapy 3560 ret i1 %cmp 3561} 3562 3563declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>) 3564 3565define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) { 3566; CHECK-LABEL: @bswap_vec_eq( 3567; CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]] 3568; CHECK-NEXT: ret <8 x i1> [[CMP]] 3569; 3570 %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x) 3571 %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y) 3572 %cmp = icmp eq <8 x i16> %swapx, %swapy 3573 ret <8 x i1> %cmp 3574} 3575 3576declare i64 @llvm.bitreverse.i64(i64) 3577 3578define i1 @bitreverse_eq(i64 %x, i64 %y) { 3579; CHECK-LABEL: @bitreverse_eq( 3580; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] 3581; CHECK-NEXT: ret i1 [[CMP]] 3582; 3583 %revx = call i64 @llvm.bitreverse.i64(i64 %x) 3584 %revy = call i64 @llvm.bitreverse.i64(i64 %y) 3585 %cmp = icmp eq i64 %revx, %revy 3586 ret i1 %cmp 3587} 3588 3589declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>) 3590 3591define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) { 3592; CHECK-LABEL: @bitreverse_vec_ne( 3593; CHECK-NEXT: [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]] 3594; CHECK-NEXT: ret <8 x i1> [[CMP]] 3595; 3596 %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x) 3597 %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y) 3598 %cmp = icmp ne <8 x i16> %revx, %revy 3599 ret <8 x i1> %cmp 3600} 3601 3602; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7. 3603; They should all simplify to equality compares. 3604define i1 @knownbits1(i8 %a, i8 %b) { 3605; CHECK-LABEL: @knownbits1( 3606; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3607; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3608; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3609; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3610; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]] 3611; CHECK-NEXT: ret i1 [[C]] 3612; 3613 %a1 = and i8 %a, 5 3614 %a2 = or i8 %a1, 4 3615 %b1 = and i8 %b, 7 3616 %b2 = or i8 %b1, 5 3617 %c = icmp uge i8 %a2, %b2 3618 ret i1 %c 3619} 3620 3621define i1 @knownbits2(i8 %a, i8 %b) { 3622; CHECK-LABEL: @knownbits2( 3623; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3624; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3625; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3626; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3627; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]] 3628; CHECK-NEXT: ret i1 [[C]] 3629; 3630 %a1 = and i8 %a, 5 3631 %a2 = or i8 %a1, 4 3632 %b1 = and i8 %b, 7 3633 %b2 = or i8 %b1, 5 3634 %c = icmp ult i8 %a2, %b2 3635 ret i1 %c 3636} 3637 3638define i1 @knownbits3(i8 %a, i8 %b) { 3639; CHECK-LABEL: @knownbits3( 3640; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3641; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3642; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3643; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3644; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B2]], [[A2]] 3645; CHECK-NEXT: ret i1 [[C]] 3646; 3647 %a1 = and i8 %a, 5 3648 %a2 = or i8 %a1, 4 3649 %b1 = and i8 %b, 7 3650 %b2 = or i8 %b1, 5 3651 %c = icmp ule i8 %b2, %a2 3652 ret i1 %c 3653} 3654 3655define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) { 3656; CHECK-LABEL: @knownbits4( 3657; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1> 3658; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4> 3659; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2> 3660; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5> 3661; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]] 3662; CHECK-NEXT: ret <2 x i1> [[C]] 3663; 3664 %a1 = and <2 x i8> %a, <i8 5, i8 5> 3665 %a2 = or <2 x i8> %a1, <i8 4, i8 4> 3666 %b1 = and <2 x i8> %b, <i8 7, i8 7> 3667 %b2 = or <2 x i8> %b1, <i8 5, i8 5> 3668 %c = icmp ugt <2 x i8> %b2, %a2 3669 ret <2 x i1> %c 3670} 3671 3672; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative. 3673; The other is known to be a value 5-7. These should simplify to equality comparisons. 3674define i1 @knownbits5(i8 %a, i8 %b) { 3675; CHECK-LABEL: @knownbits5( 3676; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3677; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3678; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3679; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3680; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]] 3681; CHECK-NEXT: ret i1 [[C]] 3682; 3683 %a1 = and i8 %a, 133 3684 %a2 = or i8 %a1, 4 3685 %b1 = and i8 %b, 7 3686 %b2 = or i8 %b1, 5 3687 %c = icmp sge i8 %a2, %b2 3688 ret i1 %c 3689} 3690 3691define i1 @knownbits6(i8 %a, i8 %b) { 3692; CHECK-LABEL: @knownbits6( 3693; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3694; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3695; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3696; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3697; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]] 3698; CHECK-NEXT: ret i1 [[C]] 3699; 3700 %a1 = and i8 %a, 133 3701 %a2 = or i8 %a1, 4 3702 %b1 = and i8 %b, 7 3703 %b2 = or i8 %b1, 5 3704 %c = icmp slt i8 %a2, %b2 3705 ret i1 %c 3706} 3707 3708define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) { 3709; CHECK-LABEL: @knownbits7( 3710; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127> 3711; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4> 3712; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2> 3713; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5> 3714; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]] 3715; CHECK-NEXT: ret <2 x i1> [[C]] 3716; 3717 %a1 = and <2 x i8> %a, <i8 133, i8 133> 3718 %a2 = or <2 x i8> %a1, <i8 4, i8 4> 3719 %b1 = and <2 x i8> %b, <i8 7, i8 7> 3720 %b2 = or <2 x i8> %b1, <i8 5, i8 5> 3721 %c = icmp sle <2 x i8> %b2, %a2 3722 ret <2 x i1> %c 3723} 3724 3725define i1 @knownbits8(i8 %a, i8 %b) { 3726; CHECK-LABEL: @knownbits8( 3727; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3728; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3729; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3730; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3731; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[B2]], [[A2]] 3732; CHECK-NEXT: ret i1 [[C]] 3733; 3734 %a1 = and i8 %a, 133 3735 %a2 = or i8 %a1, 4 3736 %b1 = and i8 %b, 7 3737 %b2 = or i8 %b1, 5 3738 %c = icmp sgt i8 %b2, %a2 3739 ret i1 %c 3740} 3741 3742; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom 3743define i32 @abs_preserve(i32 %x) { 3744; CHECK-LABEL: @abs_preserve( 3745; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X:%.*]], 1 3746; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[A]], i1 false) 3747; CHECK-NEXT: ret i32 [[TMP1]] 3748; 3749 %a = mul nsw i32 %x, 2 3750 %c = icmp sge i32 %a, 0 3751 %nega = sub i32 0, %a 3752 %abs = select i1 %c, i32 %a, i32 %nega 3753 ret i32 %abs 3754} 3755 3756; Don't crash by assuming the compared values are integers. 3757 3758declare void @llvm.assume(i1) 3759define i1 @PR35794(i32* %a) { 3760; CHECK-LABEL: @PR35794( 3761; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null 3762; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 3763; CHECK-NEXT: ret i1 true 3764; 3765 %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*) 3766 %maskcond = icmp eq i32* %a, null 3767 tail call void @llvm.assume(i1 %maskcond) 3768 ret i1 %cmp 3769} 3770 3771; Don't crash by assuming the compared values are integers. 3772define <2 x i1> @PR36583(<2 x i8*>) { 3773; CHECK-LABEL: @PR36583( 3774; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer 3775; CHECK-NEXT: ret <2 x i1> [[RES]] 3776; 3777 %cast = ptrtoint <2 x i8*> %0 to <2 x i64> 3778 %res = icmp eq <2 x i64> %cast, zeroinitializer 3779 ret <2 x i1> %res 3780} 3781 3782; fold (icmp pred (sub (0, X)) C1) for vec type 3783define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) { 3784; CHECK-LABEL: @Op1Negated_Vec( 3785; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[X:%.*]], i1 true) 3786; CHECK-NEXT: ret <2 x i32> [[TMP1]] 3787; 3788 %sub = sub nsw <2 x i32> zeroinitializer, %x 3789 %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1> 3790 %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x 3791 ret <2 x i32> %cond 3792} 3793 3794define i1 @signbit_bitcast_fpext(float %x) { 3795; CHECK-LABEL: @signbit_bitcast_fpext( 3796; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32 3797; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 3798; CHECK-NEXT: ret i1 [[R]] 3799; 3800 %f = fpext float %x to double 3801 %b = bitcast double %f to i64 3802 %r = icmp slt i64 %b, 0 3803 ret i1 %r 3804} 3805 3806define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) { 3807; CHECK-LABEL: @signbit_bitcast_fpext_vec( 3808; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x half> [[X:%.*]] to <2 x i16> 3809; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer 3810; CHECK-NEXT: ret <2 x i1> [[R]] 3811; 3812 %f = fpext <2 x half> %x to <2 x float> 3813 %b = bitcast <2 x float> %f to <2 x i32> 3814 %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647> 3815 ret <2 x i1> %r 3816} 3817 3818define i1 @signbit_bitcast_fptrunc(float %x) { 3819; CHECK-LABEL: @signbit_bitcast_fptrunc( 3820; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32 3821; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 3822; CHECK-NEXT: ret i1 [[R]] 3823; 3824 %f = fptrunc float %x to half 3825 %b = bitcast half %f to i16 3826 %r = icmp ult i16 %b, 32768 3827 ret i1 %r 3828} 3829 3830define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) { 3831; CHECK-LABEL: @signbit_bitcast_fptrunc_vec( 3832; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64> 3833; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], <i64 -1, i64 -1> 3834; CHECK-NEXT: ret <2 x i1> [[R]] 3835; 3836 %f = fptrunc <2 x double> %x to <2 x half> 3837 %b = bitcast <2 x half> %f to <2 x i16> 3838 %r = icmp sge <2 x i16> %b, zeroinitializer 3839 ret <2 x i1> %r 3840} 3841 3842define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) { 3843; CHECK-LABEL: @signbit_bitcast_fpext_wrong_cmp( 3844; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double 3845; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 3846; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 1 3847; CHECK-NEXT: ret i1 [[R]] 3848; 3849 %f = fpext float %x to double 3850 %b = bitcast double %f to i64 3851 %r = icmp slt i64 %b, 1 3852 ret i1 %r 3853} 3854 3855define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) { 3856; CHECK-LABEL: @signbit_bitcast_fpext_vec_wrong_bitcast( 3857; CHECK-NEXT: [[F:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x float> 3858; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16> 3859; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i16> [[B]], <i16 -1, i16 -1, i16 -1, i16 -1> 3860; CHECK-NEXT: ret <4 x i1> [[R]] 3861; 3862 %f = fpext <2 x half> %x to <2 x float> 3863 %b = bitcast <2 x float> %f to <4 x i16> 3864 %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1> 3865 ret <4 x i1> %r 3866} 3867 3868declare void @use_i64(i64) 3869 3870define i1 @signbit_bitcast_fpext_extra_use(float %x, i64* %p) { 3871; CHECK-LABEL: @signbit_bitcast_fpext_extra_use( 3872; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double 3873; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 3874; CHECK-NEXT: call void @use_i64(i64 [[B]]) 3875; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 0 3876; CHECK-NEXT: ret i1 [[R]] 3877; 3878 %f = fpext float %x to double 3879 %b = bitcast double %f to i64 3880 call void @use_i64(i64 %b) 3881 %r = icmp slt i64 %b, 0 3882 ret i1 %r 3883} 3884 3885define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) { 3886; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128( 3887; CHECK-NEXT: [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128 3888; CHECK-NEXT: [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128 3889; CHECK-NEXT: [[S4:%.*]] = icmp slt i128 [[S3]], 0 3890; CHECK-NEXT: ret i1 [[S4]] 3891; 3892 %s2 = fpext float %x to ppc_fp128 3893 %s3 = bitcast ppc_fp128 %s2 to i128 3894 %s4 = icmp slt i128 %s3, 0 3895 ret i1 %s4 3896} 3897 3898define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) { 3899; CHECK-LABEL: @signbit_bitcast_fptrunc_ppc_fp128( 3900; CHECK-NEXT: [[S2:%.*]] = fptrunc ppc_fp128 [[X:%.*]] to float 3901; CHECK-NEXT: [[S3:%.*]] = bitcast float [[S2]] to i32 3902; CHECK-NEXT: [[S4:%.*]] = icmp slt i32 [[S3]], 0 3903; CHECK-NEXT: ret i1 [[S4]] 3904; 3905 %s2 = fptrunc ppc_fp128 %x to float 3906 %s3 = bitcast float %s2 to i32 3907 %s4 = icmp slt i32 %s3, 0 3908 ret i1 %s4 3909} 3910 3911@x = external dso_local local_unnamed_addr global i32, align 4 3912@y = external dso_local local_unnamed_addr global i32, align 4 3913define i1 @pr47997(i32 %arg) { 3914; CHECK-LABEL: @pr47997( 3915; CHECK-NEXT: bb: 3916; CHECK-NEXT: [[I:%.*]] = add nsw i32 [[ARG:%.*]], -1 3917; CHECK-NEXT: store i32 [[I]], i32* @x, align 4 3918; CHECK-NEXT: [[I1:%.*]] = sub nsw i32 1, [[ARG]] 3919; CHECK-NEXT: store i32 [[I1]], i32* @y, align 4 3920; CHECK-NEXT: ret i1 true 3921; 3922bb: 3923 %i = add nsw i32 %arg, -1 3924 store i32 %i, i32* @x 3925 %i1 = sub nsw i32 1, %arg 3926 store i32 %i1, i32* @y 3927 %i2 = sub nsw i32 0, %i1 3928 %i3 = icmp eq i32 %i, %i2 3929 ret i1 %i3 3930} 3931