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 @test52b(i128 %x1) { 974; CHECK-LABEL: @test52b( 975; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935 976; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863 977; CHECK-NEXT: ret i1 [[TMP2]] 978; 979 %conv = and i128 %x1, 255 980 %cmp = icmp eq i128 %conv, 127 981 %i2 = lshr i128 %x1, 16 982 %i3 = trunc i128 %i2 to i8 983 %cmp15 = icmp eq i8 %i3, 76 984 985 %A = and i1 %cmp, %cmp15 986 ret i1 %A 987} 988 989; PR9838 990define i1 @test53(i32 %a, i32 %b) { 991; CHECK-LABEL: @test53( 992; CHECK-NEXT: [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30 993; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[B:%.*]], 30 994; CHECK-NEXT: [[Z:%.*]] = icmp eq i32 [[X]], [[Y]] 995; CHECK-NEXT: ret i1 [[Z]] 996; 997 %x = sdiv exact i32 %a, 30 998 %y = sdiv i32 %b, 30 999 %z = icmp eq i32 %x, %y 1000 ret i1 %z 1001} 1002 1003define i1 @test54(i8 %a) { 1004; CHECK-LABEL: @test54( 1005; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], -64 1006; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP1]], -128 1007; CHECK-NEXT: ret i1 [[RET]] 1008; 1009 %ext = zext i8 %a to i32 1010 %and = and i32 %ext, 192 1011 %ret = icmp eq i32 %and, 128 1012 ret i1 %ret 1013} 1014 1015define i1 @test55(i32 %a) { 1016; CHECK-LABEL: @test55( 1017; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123 1018; CHECK-NEXT: ret i1 [[CMP]] 1019; 1020 %sub = sub i32 0, %a 1021 %cmp = icmp eq i32 %sub, 123 1022 ret i1 %cmp 1023} 1024 1025define <2 x i1> @test55vec(<2 x i32> %a) { 1026; CHECK-LABEL: @test55vec( 1027; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -123, i32 -123> 1028; CHECK-NEXT: ret <2 x i1> [[CMP]] 1029; 1030 %sub = sub <2 x i32> zeroinitializer, %a 1031 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123> 1032 ret <2 x i1> %cmp 1033} 1034 1035define i1 @test56(i32 %a) { 1036; CHECK-LABEL: @test56( 1037; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113 1038; CHECK-NEXT: ret i1 [[CMP]] 1039; 1040 %sub = sub i32 10, %a 1041 %cmp = icmp eq i32 %sub, 123 1042 ret i1 %cmp 1043} 1044 1045define <2 x i1> @test56vec(<2 x i32> %a) { 1046; CHECK-LABEL: @test56vec( 1047; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -113, i32 -113> 1048; CHECK-NEXT: ret <2 x i1> [[CMP]] 1049; 1050 %sub = sub <2 x i32> <i32 10, i32 10>, %a 1051 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123> 1052 ret <2 x i1> %cmp 1053} 1054 1055; PR10267 Don't make icmps more expensive when no other inst is subsumed. 1056declare void @foo(i32) 1057define i1 @test57(i32 %a) { 1058; CHECK-LABEL: @test57( 1059; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2 1060; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 1061; CHECK-NEXT: call void @foo(i32 [[AND]]) 1062; CHECK-NEXT: ret i1 [[CMP]] 1063; 1064 %and = and i32 %a, -2 1065 %cmp = icmp ne i32 %and, 0 1066 call void @foo(i32 %and) 1067 ret i1 %cmp 1068} 1069 1070; rdar://problem/10482509 1071define zeroext i1 @cmpabs1(i64 %val) { 1072; CHECK-LABEL: @cmpabs1( 1073; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0 1074; CHECK-NEXT: ret i1 [[TOBOOL]] 1075; 1076 %sub = sub nsw i64 0, %val 1077 %cmp = icmp slt i64 %val, 0 1078 %sub.val = select i1 %cmp, i64 %sub, i64 %val 1079 %tobool = icmp ne i64 %sub.val, 0 1080 ret i1 %tobool 1081} 1082 1083define zeroext i1 @cmpabs2(i64 %val) { 1084; CHECK-LABEL: @cmpabs2( 1085; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0 1086; CHECK-NEXT: ret i1 [[TOBOOL]] 1087; 1088 %sub = sub nsw i64 0, %val 1089 %cmp = icmp slt i64 %val, 0 1090 %sub.val = select i1 %cmp, i64 %val, i64 %sub 1091 %tobool = icmp ne i64 %sub.val, 0 1092 ret i1 %tobool 1093} 1094 1095define i1 @abs_intrin_eq_zero(i8 %x) { 1096; CHECK-LABEL: @abs_intrin_eq_zero( 1097; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0 1098; CHECK-NEXT: ret i1 [[CMP]] 1099; 1100 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false) 1101 %cmp = icmp eq i8 %abs, 0 1102 ret i1 %cmp 1103} 1104 1105define i1 @abs_intrin_ne_zero(i8 %x) { 1106; CHECK-LABEL: @abs_intrin_ne_zero( 1107; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 0 1108; CHECK-NEXT: ret i1 [[CMP]] 1109; 1110 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false) 1111 %cmp = icmp ne i8 %abs, 0 1112 ret i1 %cmp 1113} 1114 1115define void @test58() { 1116; CHECK-LABEL: @test58( 1117; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592) 1118; CHECK-NEXT: ret void 1119; 1120 %cast = bitcast <1 x i64> <i64 36029346783166592> to i64 1121 %call = call i32 @test58_d( i64 %cast) 1122 ret void 1123} 1124declare i32 @test58_d(i64) 1125 1126define i1 @test59(i8* %foo) { 1127; CHECK-LABEL: @test59( 1128; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, i8* [[FOO:%.*]], i64 8 1129; CHECK-NEXT: [[USE:%.*]] = ptrtoint i8* [[GEP1]] to i64 1130; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]]) 1131; CHECK-NEXT: ret i1 true 1132; 1133 %bit = bitcast i8* %foo to i32* 1134 %gep1 = getelementptr inbounds i32, i32* %bit, i64 2 1135 %gep2 = getelementptr inbounds i8, i8* %foo, i64 10 1136 %cast1 = bitcast i32* %gep1 to i8* 1137 %cmp = icmp ult i8* %cast1, %gep2 1138 %use = ptrtoint i8* %cast1 to i64 1139 %call = call i32 @test58_d(i64 %use) 1140 ret i1 %cmp 1141} 1142 1143define i1 @test59_as1(i8 addrspace(1)* %foo) { 1144; CHECK-LABEL: @test59_as1( 1145; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[FOO:%.*]], i16 8 1146; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[GEP1]] to i16 1147; CHECK-NEXT: [[USE:%.*]] = zext i16 [[TMP1]] to i64 1148; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]]) 1149; CHECK-NEXT: ret i1 true 1150; 1151 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* 1152 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 2 1153 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 10 1154 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)* 1155 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 1156 %use = ptrtoint i8 addrspace(1)* %cast1 to i64 1157 %call = call i32 @test58_d(i64 %use) 1158 ret i1 %cmp 1159} 1160 1161define i1 @test60(i8* %foo, i64 %i, i64 %j) { 1162; CHECK-LABEL: @test60( 1163; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2 1164; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]] 1165; CHECK-NEXT: ret i1 [[TMP1]] 1166; 1167 %bit = bitcast i8* %foo to i32* 1168 %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i 1169 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 1170 %cast1 = bitcast i32* %gep1 to i8* 1171 %cmp = icmp ult i8* %cast1, %gep2 1172 ret i1 %cmp 1173} 1174 1175define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) { 1176; CHECK-LABEL: @test60_as1( 1177; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16 1178; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i16 1179; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[TMP1]], 2 1180; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP2]] 1181; CHECK-NEXT: ret i1 [[TMP3]] 1182; 1183 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* 1184 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 %i 1185 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 %j 1186 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)* 1187 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 1188 ret i1 %cmp 1189} 1190 1191; Same as test60, but look through an addrspacecast instead of a 1192; bitcast. This uses the same sized addrspace. 1193define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) { 1194; CHECK-LABEL: @test60_addrspacecast( 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 = addrspacecast i8* %foo to i32 addrspace(3)* 1200 %gep1 = getelementptr inbounds i32, i32 addrspace(3)* %bit, i64 %i 1201 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 1202 %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8* 1203 %cmp = icmp ult i8* %cast1, %gep2 1204 ret i1 %cmp 1205} 1206 1207define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) { 1208; CHECK-LABEL: @test60_addrspacecast_smaller( 1209; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2 1210; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16 1211; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]] 1212; CHECK-NEXT: ret i1 [[TMP2]] 1213; 1214 %bit = addrspacecast i8* %foo to i32 addrspace(1)* 1215 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i 1216 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 1217 %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8* 1218 %cmp = icmp ult i8* %cast1, %gep2 1219 ret i1 %cmp 1220} 1221 1222define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) { 1223; CHECK-LABEL: @test60_addrspacecast_larger( 1224; CHECK-NEXT: [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16 1225; CHECK-NEXT: [[TMP1:%.*]] = shl i16 [[I_TR]], 2 1226; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]] 1227; CHECK-NEXT: ret i1 [[TMP2]] 1228; 1229 %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)* 1230 %gep1 = getelementptr inbounds i32, i32 addrspace(2)* %bit, i32 %i 1231 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j 1232 %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)* 1233 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 1234 ret i1 %cmp 1235} 1236 1237define i1 @test61(i8* %foo, i64 %i, i64 %j) { 1238; CHECK-LABEL: @test61( 1239; CHECK-NEXT: [[BIT:%.*]] = bitcast i8* [[FOO:%.*]] to i32* 1240; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, i32* [[BIT]], i64 [[I:%.*]] 1241; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, i8* [[FOO]], i64 [[J:%.*]] 1242; CHECK-NEXT: [[CAST1:%.*]] = bitcast i32* [[GEP1]] to i8* 1243; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8* [[GEP2]], [[CAST1]] 1244; CHECK-NEXT: ret i1 [[CMP]] 1245; 1246 %bit = bitcast i8* %foo to i32* 1247 %gep1 = getelementptr i32, i32* %bit, i64 %i 1248 %gep2 = getelementptr i8, i8* %foo, i64 %j 1249 %cast1 = bitcast i32* %gep1 to i8* 1250 %cmp = icmp ult i8* %cast1, %gep2 1251 ret i1 %cmp 1252; Don't transform non-inbounds GEPs. 1253} 1254 1255define i1 @test61_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) { 1256; CHECK-LABEL: @test61_as1( 1257; CHECK-NEXT: [[BIT:%.*]] = bitcast i8 addrspace(1)* [[FOO:%.*]] to i32 addrspace(1)* 1258; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, i32 addrspace(1)* [[BIT]], i16 [[I:%.*]] 1259; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, i8 addrspace(1)* [[FOO]], i16 [[J:%.*]] 1260; CHECK-NEXT: [[CAST1:%.*]] = bitcast i32 addrspace(1)* [[GEP1]] to i8 addrspace(1)* 1261; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 addrspace(1)* [[GEP2]], [[CAST1]] 1262; CHECK-NEXT: ret i1 [[CMP]] 1263; 1264 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* 1265 %gep1 = getelementptr i32, i32 addrspace(1)* %bit, i16 %i 1266 %gep2 = getelementptr i8, i8 addrspace(1)* %foo, i16 %j 1267 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)* 1268 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 1269 ret i1 %cmp 1270; Don't transform non-inbounds GEPs. 1271} 1272 1273define i1 @test62(i8* %a) { 1274; CHECK-LABEL: @test62( 1275; CHECK-NEXT: ret i1 true 1276; 1277 %arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1 1278 %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10 1279 %cmp = icmp slt i8* %arrayidx1, %arrayidx2 1280 ret i1 %cmp 1281} 1282 1283define i1 @test62_as1(i8 addrspace(1)* %a) { 1284; CHECK-LABEL: @test62_as1( 1285; CHECK-NEXT: ret i1 true 1286; 1287 %arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1 1288 %arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10 1289 %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2 1290 ret i1 %cmp 1291} 1292 1293define i1 @test63(i8 %a, i32 %b) { 1294; CHECK-LABEL: @test63( 1295; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 1296; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]] 1297; CHECK-NEXT: ret i1 [[C]] 1298; 1299 %z = zext i8 %a to i32 1300 %t = and i32 %b, 255 1301 %c = icmp eq i32 %z, %t 1302 ret i1 %c 1303} 1304 1305define i1 @test64(i8 %a, i32 %b) { 1306; CHECK-LABEL: @test64( 1307; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 1308; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]] 1309; CHECK-NEXT: ret i1 [[C]] 1310; 1311 %t = and i32 %b, 255 1312 %z = zext i8 %a to i32 1313 %c = icmp eq i32 %t, %z 1314 ret i1 %c 1315} 1316 1317define i1 @test65(i64 %A, i64 %B) { 1318; CHECK-LABEL: @test65( 1319; CHECK-NEXT: ret i1 true 1320; 1321 %s1 = add i64 %A, %B 1322 %s2 = add i64 %A, %B 1323 %cmp = icmp eq i64 %s1, %s2 1324 ret i1 %cmp 1325} 1326 1327define i1 @test66(i64 %A, i64 %B) { 1328; CHECK-LABEL: @test66( 1329; CHECK-NEXT: ret i1 true 1330; 1331 %s1 = add i64 %A, %B 1332 %s2 = add i64 %B, %A 1333 %cmp = icmp eq i64 %s1, %s2 1334 ret i1 %cmp 1335} 1336 1337define i1 @test67(i32 %x) { 1338; CHECK-LABEL: @test67( 1339; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96 1340; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 1341; CHECK-NEXT: ret i1 [[CMP]] 1342; 1343 %and = and i32 %x, 127 1344 %cmp = icmp sgt i32 %and, 31 1345 ret i1 %cmp 1346} 1347 1348define i1 @test67inverse(i32 %x) { 1349; CHECK-LABEL: @test67inverse( 1350; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96 1351; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 1352; CHECK-NEXT: ret i1 [[CMP]] 1353; 1354 %and = and i32 %x, 127 1355 %cmp = icmp sle i32 %and, 31 1356 ret i1 %cmp 1357} 1358 1359; The test above relies on 3 different folds. 1360; This test only checks the last of those (icmp ugt -> icmp ne). 1361 1362define <2 x i1> @test67vec(<2 x i32> %x) { 1363; CHECK-LABEL: @test67vec( 1364; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96> 1365; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer 1366; CHECK-NEXT: ret <2 x i1> [[CMP]] 1367; 1368 %and = and <2 x i32> %x, <i32 96, i32 96> 1369 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31> 1370 ret <2 x i1> %cmp 1371} 1372 1373define <2 x i1> @test67vec2(<2 x i32> %x) { 1374; CHECK-LABEL: @test67vec2( 1375; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96> 1376; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer 1377; CHECK-NEXT: ret <2 x i1> [[CMP]] 1378; 1379 %and = and <2 x i32> %x, <i32 127, i32 127> 1380 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31> 1381 ret <2 x i1> %cmp 1382} 1383 1384define <2 x i1> @test67vecinverse(<2 x i32> %x) { 1385; CHECK-LABEL: @test67vecinverse( 1386; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96> 1387; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer 1388; CHECK-NEXT: ret <2 x i1> [[CMP]] 1389; 1390 %and = and <2 x i32> %x, <i32 96, i32 96> 1391 %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31> 1392 ret <2 x i1> %cmp 1393} 1394 1395define i1 @test68(i32 %x) { 1396; CHECK-LABEL: @test68( 1397; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 127 1398; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[AND]], 30 1399; CHECK-NEXT: ret i1 [[CMP]] 1400; 1401 %and = and i32 %x, 127 1402 %cmp = icmp sgt i32 %and, 30 1403 ret i1 %cmp 1404} 1405 1406; PR15940 1407define i1 @test70(i32 %X) { 1408; CHECK-LABEL: @test70( 1409; CHECK-NEXT: [[A:%.*]] = srem i32 5, [[X:%.*]] 1410; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A]], 2 1411; CHECK-NEXT: ret i1 [[C]] 1412; 1413 %A = srem i32 5, %X 1414 %B = add i32 %A, 2 1415 %C = icmp ne i32 %B, 4 1416 ret i1 %C 1417} 1418 1419define <2 x i1> @test70vec(<2 x i32> %X) { 1420; CHECK-LABEL: @test70vec( 1421; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2> 1422; CHECK-NEXT: ret <2 x i1> [[C]] 1423; 1424 %B = add <2 x i32> %X, <i32 2, i32 2> 1425 %C = icmp ne <2 x i32> %B, <i32 4, i32 4> 1426 ret <2 x i1> %C 1427} 1428 1429define i1 @icmp_sext16trunc(i32 %x) { 1430; CHECK-LABEL: @icmp_sext16trunc( 1431; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16 1432; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36 1433; CHECK-NEXT: ret i1 [[CMP]] 1434; 1435 %trunc = trunc i32 %x to i16 1436 %sext = sext i16 %trunc to i32 1437 %cmp = icmp slt i32 %sext, 36 1438 ret i1 %cmp 1439} 1440 1441define i1 @icmp_sext8trunc(i32 %x) { 1442; CHECK-LABEL: @icmp_sext8trunc( 1443; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 1444; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36 1445; CHECK-NEXT: ret i1 [[CMP]] 1446; 1447 %trunc = trunc i32 %x to i8 1448 %sext = sext i8 %trunc to i32 1449 %cmp = icmp slt i32 %sext, 36 1450 ret i1 %cmp 1451} 1452 1453; Vectors should fold the same way. 1454define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) { 1455; CHECK-LABEL: @icmp_sext8trunc_vec( 1456; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8> 1457; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], <i8 36, i8 36> 1458; CHECK-NEXT: ret <2 x i1> [[CMP]] 1459; 1460 %trunc = trunc <2 x i32> %x to <2 x i8> 1461 %sext = sext <2 x i8> %trunc to <2 x i32> 1462 %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36> 1463 ret <2 x i1> %cmp 1464} 1465 1466define i1 @icmp_shl16(i32 %x) { 1467; CHECK-LABEL: @icmp_shl16( 1468; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16 1469; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36 1470; CHECK-NEXT: ret i1 [[CMP]] 1471; 1472 %shl = shl i32 %x, 16 1473 %cmp = icmp slt i32 %shl, 2359296 1474 ret i1 %cmp 1475} 1476 1477; D25952: Don't create illegal types like i15 in InstCombine 1478 1479define i1 @icmp_shl17(i32 %x) { 1480; CHECK-LABEL: @icmp_shl17( 1481; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 17 1482; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296 1483; CHECK-NEXT: ret i1 [[CMP]] 1484; 1485 %shl = shl i32 %x, 17 1486 %cmp = icmp slt i32 %shl, 2359296 1487 ret i1 %cmp 1488} 1489 1490define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) { 1491; CHECK-LABEL: @icmp_shl16_vec( 1492; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16> 1493; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], <i16 36, i16 36> 1494; CHECK-NEXT: ret <2 x i1> [[CMP]] 1495; 1496 %shl = shl <2 x i32> %x, <i32 16, i32 16> 1497 %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296> 1498 ret <2 x i1> %cmp 1499} 1500 1501define i1 @icmp_shl24(i32 %x) { 1502; CHECK-LABEL: @icmp_shl24( 1503; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 1504; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36 1505; CHECK-NEXT: ret i1 [[CMP]] 1506; 1507 %shl = shl i32 %x, 24 1508 %cmp = icmp slt i32 %shl, 603979776 1509 ret i1 %cmp 1510} 1511 1512define i1 @icmp_shl_eq(i32 %x) { 1513; CHECK-LABEL: @icmp_shl_eq( 1514; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727 1515; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0 1516; CHECK-NEXT: ret i1 [[CMP]] 1517; 1518 %mul = shl i32 %x, 5 1519 %cmp = icmp eq i32 %mul, 0 1520 ret i1 %cmp 1521} 1522 1523define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) { 1524; CHECK-LABEL: @icmp_shl_eq_vec( 1525; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727> 1526; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer 1527; CHECK-NEXT: ret <2 x i1> [[CMP]] 1528; 1529 %mul = shl <2 x i32> %x, <i32 5, i32 5> 1530 %cmp = icmp eq <2 x i32> %mul, zeroinitializer 1531 ret <2 x i1> %cmp 1532} 1533 1534define i1 @icmp_shl_nsw_ne(i32 %x) { 1535; CHECK-LABEL: @icmp_shl_nsw_ne( 1536; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0 1537; CHECK-NEXT: ret i1 [[CMP]] 1538; 1539 %mul = shl nsw i32 %x, 7 1540 %cmp = icmp ne i32 %mul, 0 1541 ret i1 %cmp 1542} 1543 1544define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) { 1545; CHECK-LABEL: @icmp_shl_nsw_ne_vec( 1546; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 1547; CHECK-NEXT: ret <2 x i1> [[CMP]] 1548; 1549 %mul = shl nsw <2 x i32> %x, <i32 7, i32 7> 1550 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1551 ret <2 x i1> %cmp 1552} 1553 1554define i1 @icmp_shl_ne(i32 %x) { 1555; CHECK-LABEL: @icmp_shl_ne( 1556; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431 1557; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0 1558; CHECK-NEXT: ret i1 [[CMP]] 1559; 1560 %mul = shl i32 %x, 7 1561 %cmp = icmp ne i32 %mul, 0 1562 ret i1 %cmp 1563} 1564 1565define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) { 1566; CHECK-LABEL: @icmp_shl_ne_vec( 1567; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 33554431, i32 33554431> 1568; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer 1569; CHECK-NEXT: ret <2 x i1> [[CMP]] 1570; 1571 %mul = shl <2 x i32> %x, <i32 7, i32 7> 1572 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1573 ret <2 x i1> %cmp 1574} 1575 1576define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) { 1577; CHECK-LABEL: @icmp_shl_nuw_ne_vec( 1578; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2> 1579; CHECK-NEXT: ret <2 x i1> [[CMP]] 1580; 1581 %shl = shl nuw <2 x i32> %x, <i32 7, i32 7> 1582 %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256> 1583 ret <2 x i1> %cmp 1584} 1585 1586; If the (mul x, C) preserved the sign and this is sign test, 1587; compare the LHS operand instead 1588define i1 @icmp_mul_nsw(i32 %x) { 1589; CHECK-LABEL: @icmp_mul_nsw( 1590; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0 1591; CHECK-NEXT: ret i1 [[CMP]] 1592; 1593 %mul = mul nsw i32 %x, 12 1594 %cmp = icmp sgt i32 %mul, 0 1595 ret i1 %cmp 1596} 1597 1598define i1 @icmp_mul_nsw1(i32 %x) { 1599; CHECK-LABEL: @icmp_mul_nsw1( 1600; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 1601; CHECK-NEXT: ret i1 [[CMP]] 1602; 1603 %mul = mul nsw i32 %x, 12 1604 %cmp = icmp sle i32 %mul, -1 1605 ret i1 %cmp 1606} 1607 1608define i1 @icmp_mul_nsw_neg(i32 %x) { 1609; CHECK-LABEL: @icmp_mul_nsw_neg( 1610; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1 1611; CHECK-NEXT: ret i1 [[CMP]] 1612; 1613 %mul = mul nsw i32 %x, -12 1614 %cmp = icmp sge i32 %mul, 0 1615 ret i1 %cmp 1616} 1617 1618define i1 @icmp_mul_nsw_neg1(i32 %x) { 1619; CHECK-LABEL: @icmp_mul_nsw_neg1( 1620; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 1621; CHECK-NEXT: ret i1 [[CMP]] 1622; 1623 %mul = mul nsw i32 %x, -12 1624 %cmp = icmp sge i32 %mul, 1 1625 ret i1 %cmp 1626} 1627 1628define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) { 1629; CHECK-LABEL: @icmp_mul_nsw_neg1_vec( 1630; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer 1631; CHECK-NEXT: ret <2 x i1> [[CMP]] 1632; 1633 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12> 1634 %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1> 1635 ret <2 x i1> %cmp 1636} 1637 1638define i1 @icmp_mul_nsw_0(i32 %x) { 1639; CHECK-LABEL: @icmp_mul_nsw_0( 1640; CHECK-NEXT: ret i1 false 1641; 1642 %mul = mul nsw i32 %x, 0 1643 %cmp = icmp sgt i32 %mul, 0 1644 ret i1 %cmp 1645} 1646 1647define i1 @icmp_mul(i32 %x) { 1648; CHECK-LABEL: @icmp_mul( 1649; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X:%.*]], -12 1650; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1 1651; CHECK-NEXT: ret i1 [[CMP]] 1652; 1653 %mul = mul i32 %x, -12 1654 %cmp = icmp sge i32 %mul, 0 1655 ret i1 %cmp 1656} 1657 1658; Checks for icmp (eq|ne) (mul x, C), 0 1659define i1 @icmp_mul_neq0(i32 %x) { 1660; CHECK-LABEL: @icmp_mul_neq0( 1661; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0 1662; CHECK-NEXT: ret i1 [[CMP]] 1663; 1664 %mul = mul nsw i32 %x, -12 1665 %cmp = icmp ne i32 %mul, 0 1666 ret i1 %cmp 1667} 1668 1669define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) { 1670; CHECK-LABEL: @icmp_mul_neq0_vec( 1671; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 1672; CHECK-NEXT: ret <2 x i1> [[CMP]] 1673; 1674 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12> 1675 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1676 ret <2 x i1> %cmp 1677} 1678 1679define i1 @icmp_mul_eq0(i32 %x) { 1680; CHECK-LABEL: @icmp_mul_eq0( 1681; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 1682; CHECK-NEXT: ret i1 [[CMP]] 1683; 1684 %mul = mul nsw i32 %x, 12 1685 %cmp = icmp eq i32 %mul, 0 1686 ret i1 %cmp 1687} 1688 1689define i1 @icmp_mul0_eq0(i32 %x) { 1690; CHECK-LABEL: @icmp_mul0_eq0( 1691; CHECK-NEXT: ret i1 true 1692; 1693 %mul = mul i32 %x, 0 1694 %cmp = icmp eq i32 %mul, 0 1695 ret i1 %cmp 1696} 1697 1698define i1 @icmp_mul0_ne0(i32 %x) { 1699; CHECK-LABEL: @icmp_mul0_ne0( 1700; CHECK-NEXT: ret i1 false 1701; 1702 %mul = mul i32 %x, 0 1703 %cmp = icmp ne i32 %mul, 0 1704 ret i1 %cmp 1705} 1706 1707define i1 @icmp_sub1_sge(i32 %x, i32 %y) { 1708; CHECK-LABEL: @icmp_sub1_sge( 1709; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 1710; CHECK-NEXT: ret i1 [[CMP]] 1711; 1712 %sub = add nsw i32 %x, -1 1713 %cmp = icmp sge i32 %sub, %y 1714 ret i1 %cmp 1715} 1716 1717define i1 @icmp_add1_sgt(i32 %x, i32 %y) { 1718; CHECK-LABEL: @icmp_add1_sgt( 1719; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]] 1720; CHECK-NEXT: ret i1 [[CMP]] 1721; 1722 %add = add nsw i32 %x, 1 1723 %cmp = icmp sgt i32 %add, %y 1724 ret i1 %cmp 1725} 1726 1727define i1 @icmp_sub1_slt(i32 %x, i32 %y) { 1728; CHECK-LABEL: @icmp_sub1_slt( 1729; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]] 1730; CHECK-NEXT: ret i1 [[CMP]] 1731; 1732 %sub = add nsw i32 %x, -1 1733 %cmp = icmp slt i32 %sub, %y 1734 ret i1 %cmp 1735} 1736 1737define i1 @icmp_add1_sle(i32 %x, i32 %y) { 1738; CHECK-LABEL: @icmp_add1_sle( 1739; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 1740; CHECK-NEXT: ret i1 [[CMP]] 1741; 1742 %add = add nsw i32 %x, 1 1743 %cmp = icmp sle i32 %add, %y 1744 ret i1 %cmp 1745} 1746 1747define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) { 1748; CHECK-LABEL: @icmp_add20_sge_add57( 1749; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37 1750; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X:%.*]] 1751; CHECK-NEXT: ret i1 [[CMP]] 1752; 1753 %1 = add nsw i32 %x, 20 1754 %2 = add nsw i32 %y, 57 1755 %cmp = icmp sge i32 %1, %2 1756 ret i1 %cmp 1757} 1758 1759define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) { 1760; CHECK-LABEL: @icmp_sub57_sge_sub20( 1761; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37 1762; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]] 1763; CHECK-NEXT: ret i1 [[CMP]] 1764; 1765 %1 = add nsw i32 %x, -57 1766 %2 = add nsw i32 %y, -20 1767 %cmp = icmp sge i32 %1, %2 1768 ret i1 %cmp 1769} 1770 1771define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) { 1772; CHECK-LABEL: @icmp_and_shl_neg_ne_0( 1773; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]] 1774; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]] 1775; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 1776; CHECK-NEXT: ret i1 [[CMP]] 1777; 1778 %neg = xor i32 %A, -1 1779 %shl = shl i32 1, %B 1780 %and = and i32 %shl, %neg 1781 %cmp = icmp ne i32 %and, 0 1782 ret i1 %cmp 1783} 1784 1785define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) { 1786; CHECK-LABEL: @icmp_and_shl_neg_eq_0( 1787; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]] 1788; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]] 1789; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0 1790; CHECK-NEXT: ret i1 [[CMP]] 1791; 1792 %neg = xor i32 %A, -1 1793 %shl = shl i32 1, %B 1794 %and = and i32 %shl, %neg 1795 %cmp = icmp eq i32 %and, 0 1796 ret i1 %cmp 1797} 1798 1799define i1 @icmp_add_and_shr_ne_0(i32 %X) { 1800; CHECK-LABEL: @icmp_add_and_shr_ne_0( 1801; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 1802; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 1803; CHECK-NEXT: ret i1 [[TOBOOL]] 1804; 1805 %shr = lshr i32 %X, 4 1806 %and = and i32 %shr, 15 1807 %add = add i32 %and, -14 1808 %tobool = icmp ne i32 %add, 0 1809 ret i1 %tobool 1810} 1811 1812define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) { 1813; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec( 1814; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240> 1815; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 224, i32 224> 1816; CHECK-NEXT: ret <2 x i1> [[TOBOOL]] 1817; 1818 %shr = lshr <2 x i32> %X, <i32 4, i32 4> 1819 %and = and <2 x i32> %shr, <i32 15, i32 15> 1820 %add = add <2 x i32> %and, <i32 -14, i32 -14> 1821 %tobool = icmp ne <2 x i32> %add, zeroinitializer 1822 ret <2 x i1> %tobool 1823} 1824 1825; Variation of the above with an extra use of the shift 1826define i1 @icmp_and_shr_multiuse(i32 %X) { 1827; CHECK-LABEL: @icmp_and_shr_multiuse( 1828; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 1829; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 1830; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 1831; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 1832; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] 1833; CHECK-NEXT: ret i1 [[AND3]] 1834; 1835 %shr = lshr i32 %X, 4 1836 %and = and i32 %shr, 15 1837 %and2 = and i32 %shr, 31 ; second use of the shift 1838 %tobool = icmp ne i32 %and, 14 1839 %tobool2 = icmp ne i32 %and2, 27 1840 %and3 = and i1 %tobool, %tobool2 1841 ret i1 %and3 1842} 1843 1844; Variation of the above with an ashr 1845define i1 @icmp_and_ashr_multiuse(i32 %X) { 1846; CHECK-LABEL: @icmp_and_ashr_multiuse( 1847; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 1848; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 1849; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 1850; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 1851; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] 1852; CHECK-NEXT: ret i1 [[AND3]] 1853; 1854 %shr = ashr i32 %X, 4 1855 %and = and i32 %shr, 15 1856 %and2 = and i32 %shr, 31 ; second use of the shift 1857 %tobool = icmp ne i32 %and, 14 1858 %tobool2 = icmp ne i32 %and2, 27 1859 %and3 = and i1 %tobool, %tobool2 1860 ret i1 %and3 1861} 1862 1863define i1 @icmp_lshr_and_overshift(i8 %X) { 1864; CHECK-LABEL: @icmp_lshr_and_overshift( 1865; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31 1866; CHECK-NEXT: ret i1 [[TOBOOL]] 1867; 1868 %shr = lshr i8 %X, 5 1869 %and = and i8 %shr, 15 1870 %tobool = icmp ne i8 %and, 0 1871 ret i1 %tobool 1872} 1873 1874; We shouldn't simplify this because the and uses bits that are shifted in. 1875define i1 @icmp_ashr_and_overshift(i8 %X) { 1876; CHECK-LABEL: @icmp_ashr_and_overshift( 1877; CHECK-NEXT: [[SHR:%.*]] = ashr i8 [[X:%.*]], 5 1878; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHR]], 15 1879; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0 1880; CHECK-NEXT: ret i1 [[TOBOOL]] 1881; 1882 %shr = ashr i8 %X, 5 1883 %and = and i8 %shr, 15 1884 %tobool = icmp ne i8 %and, 0 1885 ret i1 %tobool 1886} 1887 1888define i1 @icmp_and_ashr_neg_and_legal(i8 %x) { 1889; CHECK-LABEL: @icmp_and_ashr_neg_and_legal( 1890; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 1891; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 16 1892; CHECK-NEXT: ret i1 [[CMP]] 1893; 1894 %ashr = ashr i8 %x, 4 1895 %and = and i8 %ashr, -2 1896 %cmp = icmp slt i8 %and, 1 1897 ret i1 %cmp 1898} 1899 1900; Negative test. 1901define i1 @icmp_and_ashr_mixed_and_shiftout(i8 %x) { 1902; CHECK-LABEL: @icmp_and_ashr_mixed_and_shiftout( 1903; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4 1904; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], 31 1905; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[AND]], 8 1906; CHECK-NEXT: ret i1 [[CMP]] 1907; 1908 %ashr = ashr i8 %x, 4 1909 %and = and i8 %ashr, 31 1910 %cmp = icmp ugt i8 %and, 8 1911 ret i1 %cmp 1912} 1913 1914define i1 @icmp_and_ashr_neg_cmp_slt_legal(i8 %x) { 1915; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_legal( 1916; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 1917; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], -64 1918; CHECK-NEXT: ret i1 [[CMP]] 1919; 1920 %ashr = ashr i8 %x, 4 1921 %and = and i8 %ashr, -2 1922 %cmp = icmp slt i8 %and, -4 1923 ret i1 %cmp 1924} 1925 1926; Negative test. 1927define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(i8 %x) { 1928; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_shiftout( 1929; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4 1930; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], -2 1931; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[AND]], -68 1932; CHECK-NEXT: ret i1 [[CMP]] 1933; 1934 %ashr = ashr i8 %x, 4 1935 %and = and i8 %ashr, -2 1936 %cmp = icmp slt i8 %and, -68 1937 ret i1 %cmp 1938} 1939 1940define i1 @icmp_and_ashr_neg_cmp_eq_legal(i8 %x) { 1941; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_legal( 1942; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 1943; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], -64 1944; CHECK-NEXT: ret i1 [[CMP]] 1945; 1946 %ashr = ashr i8 %x, 4 1947 %and = and i8 %ashr, -2 1948 %cmp = icmp eq i8 %and, -4 1949 ret i1 %cmp 1950} 1951 1952define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(i8 %x) { 1953; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_shiftout( 1954; CHECK-NEXT: ret i1 false 1955; 1956 %ashr = ashr i8 %x, 4 1957 %and = and i8 %ashr, -2 1958 %cmp = icmp eq i8 %and, -68 1959 ret i1 %cmp 1960} 1961 1962define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(i8 %x) { 1963; CHECK-LABEL: @icmp_and_ashr_neg_cmp_ne_shiftout( 1964; CHECK-NEXT: ret i1 true 1965; 1966 %ashr = ashr i8 %x, 4 1967 %and = and i8 %ashr, -2 1968 %cmp = icmp ne i8 %and, -68 1969 ret i1 %cmp 1970} 1971 1972; PR16244 1973define i1 @test71(i8* %x) { 1974; CHECK-LABEL: @test71( 1975; CHECK-NEXT: ret i1 false 1976; 1977 %a = getelementptr i8, i8* %x, i64 8 1978 %b = getelementptr inbounds i8, i8* %x, i64 8 1979 %c = icmp ugt i8* %a, %b 1980 ret i1 %c 1981} 1982 1983define i1 @test71_as1(i8 addrspace(1)* %x) { 1984; CHECK-LABEL: @test71_as1( 1985; CHECK-NEXT: ret i1 false 1986; 1987 %a = getelementptr i8, i8 addrspace(1)* %x, i64 8 1988 %b = getelementptr inbounds i8, i8 addrspace(1)* %x, i64 8 1989 %c = icmp ugt i8 addrspace(1)* %a, %b 1990 ret i1 %c 1991} 1992 1993define i1 @icmp_shl_1_V_ult_32(i32 %V) { 1994; CHECK-LABEL: @icmp_shl_1_V_ult_32( 1995; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 1996; CHECK-NEXT: ret i1 [[CMP]] 1997; 1998 %shl = shl i32 1, %V 1999 %cmp = icmp ult i32 %shl, 32 2000 ret i1 %cmp 2001} 2002 2003define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) { 2004; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec( 2005; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5> 2006; CHECK-NEXT: ret <2 x i1> [[CMP]] 2007; 2008 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2009 %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32> 2010 ret <2 x i1> %cmp 2011} 2012 2013define i1 @icmp_shl_1_V_eq_32(i32 %V) { 2014; CHECK-LABEL: @icmp_shl_1_V_eq_32( 2015; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5 2016; CHECK-NEXT: ret i1 [[CMP]] 2017; 2018 %shl = shl i32 1, %V 2019 %cmp = icmp eq i32 %shl, 32 2020 ret i1 %cmp 2021} 2022 2023define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) { 2024; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec( 2025; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 5, i32 5> 2026; CHECK-NEXT: ret <2 x i1> [[CMP]] 2027; 2028 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2029 %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32> 2030 ret <2 x i1> %cmp 2031} 2032 2033define i1 @icmp_shl_1_V_ult_30(i32 %V) { 2034; CHECK-LABEL: @icmp_shl_1_V_ult_30( 2035; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 2036; CHECK-NEXT: ret i1 [[CMP]] 2037; 2038 %shl = shl i32 1, %V 2039 %cmp = icmp ult i32 %shl, 30 2040 ret i1 %cmp 2041} 2042 2043define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) { 2044; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec( 2045; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5> 2046; CHECK-NEXT: ret <2 x i1> [[CMP]] 2047; 2048 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2049 %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30> 2050 ret <2 x i1> %cmp 2051} 2052 2053define i1 @icmp_shl_1_V_ugt_30(i32 %V) { 2054; CHECK-LABEL: @icmp_shl_1_V_ugt_30( 2055; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4 2056; CHECK-NEXT: ret i1 [[CMP]] 2057; 2058 %shl = shl i32 1, %V 2059 %cmp = icmp ugt i32 %shl, 30 2060 ret i1 %cmp 2061} 2062 2063define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) { 2064; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec( 2065; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4> 2066; CHECK-NEXT: ret <2 x i1> [[CMP]] 2067; 2068 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2069 %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30> 2070 ret <2 x i1> %cmp 2071} 2072 2073define i1 @icmp_shl_1_V_ule_30(i32 %V) { 2074; CHECK-LABEL: @icmp_shl_1_V_ule_30( 2075; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 2076; CHECK-NEXT: ret i1 [[CMP]] 2077; 2078 %shl = shl i32 1, %V 2079 %cmp = icmp ule i32 %shl, 30 2080 ret i1 %cmp 2081} 2082 2083define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) { 2084; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec( 2085; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5> 2086; CHECK-NEXT: ret <2 x i1> [[CMP]] 2087; 2088 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2089 %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30> 2090 ret <2 x i1> %cmp 2091} 2092 2093define i1 @icmp_shl_1_V_uge_30(i32 %V) { 2094; CHECK-LABEL: @icmp_shl_1_V_uge_30( 2095; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4 2096; CHECK-NEXT: ret i1 [[CMP]] 2097; 2098 %shl = shl i32 1, %V 2099 %cmp = icmp uge i32 %shl, 30 2100 ret i1 %cmp 2101} 2102 2103define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) { 2104; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec( 2105; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4> 2106; CHECK-NEXT: ret <2 x i1> [[CMP]] 2107; 2108 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2109 %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30> 2110 ret <2 x i1> %cmp 2111} 2112 2113define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) { 2114; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648( 2115; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31 2116; CHECK-NEXT: ret i1 [[CMP]] 2117; 2118 %shl = shl i32 1, %V 2119 %cmp = icmp uge i32 %shl, 2147483648 2120 ret i1 %cmp 2121} 2122 2123define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) { 2124; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec( 2125; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 31, i32 31> 2126; CHECK-NEXT: ret <2 x i1> [[CMP]] 2127; 2128 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2129 %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648> 2130 ret <2 x i1> %cmp 2131} 2132 2133define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) { 2134; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648( 2135; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31 2136; CHECK-NEXT: ret i1 [[CMP]] 2137; 2138 %shl = shl i32 1, %V 2139 %cmp = icmp ult i32 %shl, 2147483648 2140 ret i1 %cmp 2141} 2142 2143define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) { 2144; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec( 2145; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], <i32 31, i32 31> 2146; CHECK-NEXT: ret <2 x i1> [[CMP]] 2147; 2148 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2149 %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648> 2150 ret <2 x i1> %cmp 2151} 2152 2153define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) { 2154; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B( 2155; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1 2156; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]] 2157; CHECK-NEXT: ret i1 [[TMP2]] 2158; 2159 %1 = icmp eq i64 %b, 0 2160 %2 = icmp ult i64 %a, %b 2161 %3 = or i1 %1, %2 2162 ret i1 %3 2163} 2164 2165define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) { 2166; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform( 2167; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1> 2168; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]] 2169; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2170; 2171 %1 = icmp eq <2 x i64> %b, zeroinitializer 2172 %2 = icmp ult <2 x i64> %a, %b 2173 %3 = or <2 x i1> %1, %2 2174 ret <2 x i1> %3 2175} 2176 2177define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_undef(<2 x i64> %a, <2 x i64> %b) { 2178; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_undef( 2179; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1> 2180; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]] 2181; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2182; 2183 %1 = icmp eq <2 x i64> %b, <i64 0, i64 undef> 2184 %2 = icmp ult <2 x i64> %a, %b 2185 %3 = or <2 x i1> %1, %2 2186 ret <2 x i1> %3 2187} 2188 2189define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) { 2190; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0( 2191; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]] 2192; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0 2193; CHECK-NEXT: ret i1 [[TMP2]] 2194; 2195 %1 = icmp ne i64 %a, 0 2196 %2 = icmp ne i64 %b, 0 2197 %3 = or i1 %1, %2 2198 ret i1 %3 2199} 2200 2201define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) { 2202; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform( 2203; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]] 2204; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer 2205; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2206; 2207 %1 = icmp ne <2 x i64> %a, zeroinitializer 2208 %2 = icmp ne <2 x i64> %b, zeroinitializer 2209 %3 = or <2 x i1> %1, %2 2210 ret <2 x i1> %3 2211} 2212 2213define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_undef(<2 x i64> %a, <2 x i64> %b) { 2214; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_undef( 2215; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]] 2216; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer 2217; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2218; 2219 %1 = icmp ne <2 x i64> %a, <i64 0, i64 undef> 2220 %2 = icmp ne <2 x i64> %b, <i64 0, i64 undef> 2221 %3 = or <2 x i1> %1, %2 2222 ret <2 x i1> %3 2223} 2224 2225define i1 @icmp_add_ult_2(i32 %X) { 2226; CHECK-LABEL: @icmp_add_ult_2( 2227; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2228; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14 2229; CHECK-NEXT: ret i1 [[CMP]] 2230; 2231 %add = add i32 %X, -14 2232 %cmp = icmp ult i32 %add, 2 2233 ret i1 %cmp 2234} 2235 2236define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) { 2237; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec( 2238; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2239; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14> 2240; CHECK-NEXT: ret <2 x i1> [[CMP]] 2241; 2242 %add = add <2 x i32> %X, <i32 -14, i32 -14> 2243 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2> 2244 ret <2 x i1> %cmp 2245} 2246 2247define i1 @icmp_sub_3_X_ult_2(i32 %X) { 2248; CHECK-LABEL: @icmp_sub_3_X_ult_2( 2249; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2250; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 2 2251; CHECK-NEXT: ret i1 [[CMP]] 2252; 2253 %add = sub i32 3, %X 2254 %cmp = icmp ult i32 %add, 2 2255 ret i1 %cmp 2256} 2257 2258define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) { 2259; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec( 2260; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2261; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 2, i32 2> 2262; CHECK-NEXT: ret <2 x i1> [[CMP]] 2263; 2264 %add = sub <2 x i32> <i32 3, i32 3>, %X 2265 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2> 2266 ret <2 x i1> %cmp 2267} 2268 2269define i1 @icmp_add_X_-14_uge_2(i32 %X) { 2270; CHECK-LABEL: @icmp_add_X_-14_uge_2( 2271; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2272; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14 2273; CHECK-NEXT: ret i1 [[CMP]] 2274; 2275 %add = add i32 %X, -14 2276 %cmp = icmp uge i32 %add, 2 2277 ret i1 %cmp 2278} 2279 2280define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) { 2281; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec( 2282; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2283; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14> 2284; CHECK-NEXT: ret <2 x i1> [[CMP]] 2285; 2286 %add = add <2 x i32> %X, <i32 -14, i32 -14> 2287 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2> 2288 ret <2 x i1> %cmp 2289} 2290 2291define i1 @icmp_sub_3_X_uge_2(i32 %X) { 2292; CHECK-LABEL: @icmp_sub_3_X_uge_2( 2293; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2294; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 2 2295; CHECK-NEXT: ret i1 [[CMP]] 2296; 2297 %add = sub i32 3, %X 2298 %cmp = icmp uge i32 %add, 2 2299 ret i1 %cmp 2300} 2301 2302define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) { 2303; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec( 2304; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2> 2305; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 2, i32 2> 2306; CHECK-NEXT: ret <2 x i1> [[CMP]] 2307; 2308 %add = sub <2 x i32> <i32 3, i32 3>, %X 2309 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2> 2310 ret <2 x i1> %cmp 2311} 2312 2313define i1 @icmp_and_X_-16_eq-16(i32 %X) { 2314; CHECK-LABEL: @icmp_and_X_-16_eq-16( 2315; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17 2316; CHECK-NEXT: ret i1 [[CMP]] 2317; 2318 %and = and i32 %X, -16 2319 %cmp = icmp eq i32 %and, -16 2320 ret i1 %cmp 2321} 2322 2323define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) { 2324; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec( 2325; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17> 2326; CHECK-NEXT: ret <2 x i1> [[CMP]] 2327; 2328 %and = and <2 x i32> %X, <i32 -16, i32 -16> 2329 %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16> 2330 ret <2 x i1> %cmp 2331} 2332 2333define i1 @icmp_and_X_-16_ne-16(i32 %X) { 2334; CHECK-LABEL: @icmp_and_X_-16_ne-16( 2335; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16 2336; CHECK-NEXT: ret i1 [[CMP]] 2337; 2338 %and = and i32 %X, -16 2339 %cmp = icmp ne i32 %and, -16 2340 ret i1 %cmp 2341} 2342 2343define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) { 2344; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec( 2345; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16> 2346; CHECK-NEXT: ret <2 x i1> [[CMP]] 2347; 2348 %and = and <2 x i32> %X, <i32 -16, i32 -16> 2349 %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16> 2350 ret <2 x i1> %cmp 2351} 2352 2353; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524 2354; X | C == C --> X <=u C (when C+1 is PowerOf2). 2355 2356define i1 @or1_eq1(i32 %x) { 2357; CHECK-LABEL: @or1_eq1( 2358; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2 2359; CHECK-NEXT: ret i1 [[T1]] 2360; 2361 %t0 = or i32 %x, 1 2362 %t1 = icmp eq i32 %t0, 1 2363 ret i1 %t1 2364} 2365 2366; X | C == C --> X <=u C (when C+1 is PowerOf2). 2367 2368define <2 x i1> @or3_eq3_vec(<2 x i8> %x) { 2369; CHECK-LABEL: @or3_eq3_vec( 2370; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4> 2371; CHECK-NEXT: ret <2 x i1> [[T1]] 2372; 2373 %t0 = or <2 x i8> %x, <i8 3, i8 3> 2374 %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3> 2375 ret <2 x i1> %t1 2376} 2377 2378; X | C != C --> X >u C (when C+1 is PowerOf2). 2379 2380define i1 @or7_ne7(i32 %x) { 2381; CHECK-LABEL: @or7_ne7( 2382; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7 2383; CHECK-NEXT: ret i1 [[T1]] 2384; 2385 %t0 = or i32 %x, 7 2386 %t1 = icmp ne i32 %t0, 7 2387 ret i1 %t1 2388} 2389 2390; X | C != C --> X >u C (when C+1 is PowerOf2). 2391 2392define <2 x i1> @or63_ne63_vec(<2 x i8> %x) { 2393; CHECK-LABEL: @or63_ne63_vec( 2394; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63> 2395; CHECK-NEXT: ret <2 x i1> [[T1]] 2396; 2397 %t0 = or <2 x i8> %x, <i8 63, i8 63> 2398 %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63> 2399 ret <2 x i1> %t1 2400} 2401 2402; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611 2403; X | C == C --> (X & ~C) == 0 2404 2405define i1 @orC_eqC(i32 %x) { 2406; CHECK-LABEL: @orC_eqC( 2407; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 2408; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[TMP1]], 0 2409; CHECK-NEXT: ret i1 [[T1]] 2410; 2411 %t0 = or i32 %x, 42 2412 %t1 = icmp eq i32 %t0, 42 2413 ret i1 %t1 2414} 2415 2416; X | C == C --> (X & ~C) == 0 2417 2418define <2 x i1> @orC_eqC_vec(<2 x i8> %x) { 2419; CHECK-LABEL: @orC_eqC_vec( 2420; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44> 2421; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer 2422; CHECK-NEXT: ret <2 x i1> [[T1]] 2423; 2424 %t0 = or <2 x i8> %x, <i8 43, i8 43> 2425 %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43> 2426 ret <2 x i1> %t1 2427} 2428 2429; X | C != C --> (X & ~C) != 0 2430 2431define i1 @orC_neC(i32 %x) { 2432; CHECK-LABEL: @orC_neC( 2433; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 41 2434; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[TMP1]], 0 2435; CHECK-NEXT: ret i1 [[T1]] 2436; 2437 %t0 = or i32 %x, -42 2438 %t1 = icmp ne i32 %t0, -42 2439 ret i1 %t1 2440} 2441 2442; X | C != C --> (X & ~C) != 0 2443 2444define <2 x i1> @orC_neC_vec(<2 x i8> %x) { 2445; CHECK-LABEL: @orC_neC_vec( 2446; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42> 2447; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer 2448; CHECK-NEXT: ret <2 x i1> [[T1]] 2449; 2450 %t0 = or <2 x i8> %x, <i8 -43, i8 -43> 2451 %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43> 2452 ret <2 x i1> %t1 2453} 2454 2455define i1 @shrink_constant(i32 %X) { 2456; CHECK-LABEL: @shrink_constant( 2457; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], -12 2458; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[XOR]], 4 2459; CHECK-NEXT: ret i1 [[CMP]] 2460; 2461 %xor = xor i32 %X, -9 2462 %cmp = icmp ult i32 %xor, 4 2463 ret i1 %cmp 2464} 2465 2466define <2 x i1> @shrink_constant_vec(<2 x i32> %X) { 2467; CHECK-LABEL: @shrink_constant_vec( 2468; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12> 2469; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4> 2470; CHECK-NEXT: ret <2 x i1> [[CMP]] 2471; 2472 %xor = xor <2 x i32> %X, <i32 -9, i32 -9> 2473 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4> 2474 ret <2 x i1> %cmp 2475} 2476 2477; This test requires 3 different transforms to get to the result. 2478define i1 @icmp_sub_-1_X_ult_4(i32 %X) { 2479; CHECK-LABEL: @icmp_sub_-1_X_ult_4( 2480; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5 2481; CHECK-NEXT: ret i1 [[CMP]] 2482; 2483 %sub = sub i32 -1, %X 2484 %cmp = icmp ult i32 %sub, 4 2485 ret i1 %cmp 2486} 2487 2488define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) { 2489; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec( 2490; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5> 2491; CHECK-NEXT: ret <2 x i1> [[CMP]] 2492; 2493 %xor = xor <2 x i32> %X, <i32 -4, i32 -4> 2494 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4> 2495 ret <2 x i1> %cmp 2496} 2497 2498define i1 @icmp_sub_-1_X_uge_4(i32 %X) { 2499; CHECK-LABEL: @icmp_sub_-1_X_uge_4( 2500; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4 2501; CHECK-NEXT: ret i1 [[CMP]] 2502; 2503 %sub = sub i32 -1, %X 2504 %cmp = icmp uge i32 %sub, 4 2505 ret i1 %cmp 2506} 2507 2508define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) { 2509; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec( 2510; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4> 2511; CHECK-NEXT: ret <2 x i1> [[CMP]] 2512; 2513 %xor = xor <2 x i32> %X, <i32 -4, i32 -4> 2514 %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4> 2515 ret <2 x i1> %cmp 2516} 2517 2518define <2 x i1> @xor_ult(<2 x i8> %x) { 2519; CHECK-LABEL: @xor_ult( 2520; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3> 2521; CHECK-NEXT: ret <2 x i1> [[R]] 2522; 2523 %xor = xor <2 x i8> %x, <i8 -4, i8 -4> 2524 %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4> 2525 ret <2 x i1> %r 2526} 2527 2528define i1 @xor_ult_extra_use(i8 %x, i8* %p) { 2529; CHECK-LABEL: @xor_ult_extra_use( 2530; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32 2531; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1 2532; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31 2533; CHECK-NEXT: ret i1 [[R]] 2534; 2535 %xor = xor i8 %x, -32 2536 store i8 %xor, i8* %p 2537 %r = icmp ult i8 %xor, -32 2538 ret i1 %r 2539} 2540 2541define <2 x i1> @xor_ugt(<2 x i8> %x) { 2542; CHECK-LABEL: @xor_ugt( 2543; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7> 2544; CHECK-NEXT: ret <2 x i1> [[R]] 2545; 2546 %xor = xor <2 x i8> %x, <i8 7, i8 7> 2547 %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7> 2548 ret <2 x i1> %r 2549} 2550 2551define i1 @xor_ugt_extra_use(i8 %x, i8* %p) { 2552; CHECK-LABEL: @xor_ugt_extra_use( 2553; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63 2554; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1 2555; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63 2556; CHECK-NEXT: ret i1 [[R]] 2557; 2558 %xor = xor i8 %x, 63 2559 store i8 %xor, i8* %p 2560 %r = icmp ugt i8 %xor, 63 2561 ret i1 %r 2562} 2563 2564define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) { 2565; CHECK-LABEL: @icmp_swap_operands_for_cse( 2566; CHECK-NEXT: entry: 2567; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 2568; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]] 2569; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2570; CHECK: true: 2571; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[SUB]], 1 2572; CHECK-NEXT: br label [[END:%.*]] 2573; CHECK: false: 2574; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SUB]], 16 2575; CHECK-NEXT: br label [[END]] 2576; CHECK: end: 2577; CHECK-NEXT: [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ] 2578; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2579; CHECK-NEXT: ret i1 [[RES]] 2580; 2581entry: 2582 %sub = sub i32 %X, %Y 2583 %cmp = icmp ugt i32 %Y, %X 2584 br i1 %cmp, label %true, label %false 2585true: 2586 %restrue = trunc i32 %sub to i1 2587 br label %end 2588false: 2589 %shift = lshr i32 %sub, 4 2590 %resfalse = trunc i32 %shift to i1 2591 br label %end 2592end: 2593 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2594 ret i1 %res 2595} 2596 2597define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) { 2598; CHECK-LABEL: @icmp_swap_operands_for_cse2( 2599; CHECK-NEXT: entry: 2600; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2601; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2602; CHECK: true: 2603; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]] 2604; CHECK-NEXT: [[SUB1:%.*]] = sub i32 [[X]], [[Y]] 2605; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]] 2606; CHECK-NEXT: br label [[END:%.*]] 2607; CHECK: false: 2608; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]] 2609; CHECK-NEXT: br label [[END]] 2610; CHECK: end: 2611; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ] 2612; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1 2613; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2614; CHECK-NEXT: ret i1 [[RES]] 2615; 2616entry: 2617 %cmp = icmp ugt i32 %Y, %X 2618 br i1 %cmp, label %true, label %false 2619true: 2620 %sub = sub i32 %X, %Y 2621 %sub1 = sub i32 %X, %Y 2622 %add = add i32 %sub, %sub1 2623 %restrue = trunc i32 %add to i1 2624 br label %end 2625false: 2626 %sub2 = sub i32 %Y, %X 2627 %resfalse = trunc i32 %sub2 to i1 2628 br label %end 2629end: 2630 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2631 ret i1 %res 2632} 2633 2634define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) { 2635; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse( 2636; CHECK-NEXT: entry: 2637; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]] 2638; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]] 2639; CHECK: true: 2640; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]] 2641; CHECK-NEXT: br label [[END:%.*]] 2642; CHECK: false: 2643; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]] 2644; CHECK-NEXT: br label [[END]] 2645; CHECK: end: 2646; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ] 2647; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1 2648; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0 2649; CHECK-NEXT: ret i1 [[RES]] 2650; 2651entry: 2652 %cmp = icmp ugt i32 %Y, %X 2653 br i1 %cmp, label %true, label %false 2654true: 2655 %sub = sub i32 %X, %Y 2656 %restrue = trunc i32 %sub to i1 2657 br label %end 2658false: 2659 %sub2 = sub i32 %Y, %X 2660 %resfalse = trunc i32 %sub2 to i1 2661 br label %end 2662end: 2663 %res = phi i1 [%restrue, %true], [%resfalse, %false] 2664 ret i1 %res 2665} 2666 2667define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) { 2668; CHECK-LABEL: @icmp_lshr_lshr_eq( 2669; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 2670; CHECK-NEXT: [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824 2671; CHECK-NEXT: ret i1 [[Z]] 2672; 2673 %x = lshr i32 %a, 30 2674 %y = lshr i32 %b, 30 2675 %z = icmp eq i32 %x, %y 2676 ret i1 %z 2677} 2678 2679define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) { 2680; CHECK-LABEL: @icmp_ashr_ashr_ne( 2681; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 2682; CHECK-NEXT: [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255 2683; CHECK-NEXT: ret i1 [[Z]] 2684; 2685 %x = ashr i32 %a, 8 2686 %y = ashr i32 %b, 8 2687 %z = icmp ne i32 %x, %y 2688 ret i1 %z 2689} 2690 2691define i1 @icmp_neg_cst_slt(i32 %a) { 2692; CHECK-LABEL: @icmp_neg_cst_slt( 2693; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10 2694; CHECK-NEXT: ret i1 [[TMP1]] 2695; 2696 %1 = sub nsw i32 0, %a 2697 %2 = icmp slt i32 %1, -10 2698 ret i1 %2 2699} 2700 2701define i1 @icmp_and_or_lshr(i32 %x, i32 %y) { 2702; CHECK-LABEL: @icmp_and_or_lshr( 2703; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]] 2704; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1 2705; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]] 2706; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0 2707; CHECK-NEXT: ret i1 [[RET]] 2708; 2709 %shf = lshr i32 %x, %y 2710 %or = or i32 %shf, %x 2711 %and = and i32 %or, 1 2712 %ret = icmp ne i32 %and, 0 2713 ret i1 %ret 2714} 2715 2716define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) { 2717; CHECK-LABEL: @icmp_and_or_lshr_vec( 2718; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]] 2719; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]] 2720; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1> 2721; CHECK-NEXT: ret <2 x i1> [[RET]] 2722; 2723 %shf = lshr <2 x i32> %x, %y 2724 %or = or <2 x i32> %shf, %x 2725 %and = and <2 x i32> %or, <i32 1, i32 1> 2726 %ret = icmp ne <2 x i32> %and, zeroinitializer 2727 ret <2 x i1> %ret 2728} 2729 2730define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) { 2731; CHECK-LABEL: @icmp_and_or_lshr_vec_commute( 2732; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2733; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]] 2734; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]] 2735; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1> 2736; CHECK-NEXT: ret <2 x i1> [[RET]] 2737; 2738 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2739 %shf = lshr <2 x i32> %x, %y 2740 %or = or <2 x i32> %x, %shf 2741 %and = and <2 x i32> %or, <i32 1, i32 1> 2742 %ret = icmp ne <2 x i32> %and, zeroinitializer 2743 ret <2 x i1> %ret 2744} 2745 2746define i1 @icmp_and_or_lshr_cst(i32 %x) { 2747; CHECK-LABEL: @icmp_and_or_lshr_cst( 2748; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], 3 2749; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND1]], 0 2750; CHECK-NEXT: ret i1 [[RET]] 2751; 2752 %shf = lshr i32 %x, 1 2753 %or = or i32 %shf, %x 2754 %and = and i32 %or, 1 2755 %ret = icmp ne i32 %and, 0 2756 ret i1 %ret 2757} 2758 2759define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) { 2760; CHECK-LABEL: @icmp_and_or_lshr_cst_vec( 2761; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3> 2762; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2763; CHECK-NEXT: ret <2 x i1> [[RET]] 2764; 2765 %shf = lshr <2 x i32> %x, <i32 1, i32 1> 2766 %or = or <2 x i32> %shf, %x 2767 %and = and <2 x i32> %or, <i32 1, i32 1> 2768 %ret = icmp ne <2 x i32> %and, zeroinitializer 2769 ret <2 x i1> %ret 2770} 2771 2772define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) { 2773; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform( 2774; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 5> 2775; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2776; CHECK-NEXT: ret <2 x i1> [[RET]] 2777; 2778 %shf = lshr <2 x i32> %x, <i32 1, i32 2> 2779 %or = or <2 x i32> %shf, %x 2780 %and = and <2 x i32> %or, <i32 1, i32 1> 2781 %ret = icmp ne <2 x i32> %and, zeroinitializer 2782 ret <2 x i1> %ret 2783} 2784 2785define <2 x i1> @icmp_and_or_lshr_cst_vec_undef(<2 x i32> %x) { 2786; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef( 2787; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 poison> 2788; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2789; CHECK-NEXT: ret <2 x i1> [[RET]] 2790; 2791 %shf = lshr <2 x i32> %x, <i32 1, i32 undef> 2792 %or = or <2 x i32> %shf, %x 2793 %and = and <2 x i32> %or, <i32 1, i32 1> 2794 %ret = icmp ne <2 x i32> %and, zeroinitializer 2795 ret <2 x i1> %ret 2796} 2797 2798define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) { 2799; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute( 2800; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2801; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3> 2802; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2803; CHECK-NEXT: ret <2 x i1> [[RET]] 2804; 2805 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2806 %shf = lshr <2 x i32> %x, <i32 1, i32 1> 2807 %or = or <2 x i32> %x, %shf 2808 %and = and <2 x i32> %or, <i32 1, i32 1> 2809 %ret = icmp ne <2 x i32> %and, zeroinitializer 2810 ret <2 x i1> %ret 2811} 2812 2813define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) { 2814; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform_commute( 2815; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2816; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5> 2817; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2818; CHECK-NEXT: ret <2 x i1> [[RET]] 2819; 2820 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2821 %shf = lshr <2 x i32> %x, <i32 1, i32 2> 2822 %or = or <2 x i32> %x, %shf 2823 %and = and <2 x i32> %or, <i32 1, i32 1> 2824 %ret = icmp ne <2 x i32> %and, zeroinitializer 2825 ret <2 x i1> %ret 2826} 2827 2828define <2 x i1> @icmp_and_or_lshr_cst_vec_undef_commute(<2 x i32> %xp) { 2829; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef_commute( 2830; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42> 2831; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison> 2832; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 2833; CHECK-NEXT: ret <2 x i1> [[RET]] 2834; 2835 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 2836 %shf = lshr <2 x i32> %x, <i32 1, i32 undef> 2837 %or = or <2 x i32> %x, %shf 2838 %and = and <2 x i32> %or, <i32 1, i32 1> 2839 %ret = icmp ne <2 x i32> %and, zeroinitializer 2840 ret <2 x i1> %ret 2841} 2842 2843define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) { 2844; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2( 2845; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29 2846; CHECK-NEXT: ret i1 [[CMP]] 2847; 2848 %shl = shl i32 4, %a 2849 %cmp = icmp eq i32 %shl, 0 2850 ret i1 %cmp 2851} 2852 2853define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) { 2854; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec( 2855; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29> 2856; CHECK-NEXT: ret <2 x i1> [[CMP]] 2857; 2858 %shl = shl <2 x i32> <i32 4, i32 4>, %a 2859 %cmp = icmp eq <2 x i32> %shl, zeroinitializer 2860 ret <2 x i1> %cmp 2861} 2862 2863define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) { 2864; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform( 2865; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A:%.*]] 2866; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer 2867; CHECK-NEXT: ret <2 x i1> [[CMP]] 2868; 2869 %shl = shl <2 x i32> <i32 4, i32 5>, %a 2870 %cmp = icmp eq <2 x i32> %shl, zeroinitializer 2871 ret <2 x i1> %cmp 2872} 2873 2874define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) { 2875; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4( 2876; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30 2877; CHECK-NEXT: ret i1 [[CMP]] 2878; 2879 %shl = shl i32 -2, %a 2880 %cmp = icmp eq i32 %shl, 0 2881 ret i1 %cmp 2882} 2883 2884define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) { 2885; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive( 2886; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 2887; CHECK-NEXT: ret i1 [[CMP]] 2888; 2889 %shl = shl i32 50, %a 2890 %cmp = icmp eq i32 %shl, 50 2891 ret i1 %cmp 2892} 2893 2894define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) { 2895; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative( 2896; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 2897; CHECK-NEXT: ret i1 [[CMP]] 2898; 2899 %shl = shl i32 -50, %a 2900 %cmp = icmp eq i32 %shl, -50 2901 ret i1 %cmp 2902} 2903 2904define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) { 2905; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1( 2906; CHECK-NEXT: ret i1 false 2907; 2908 %shl = shl i32 50, %a 2909 %cmp = icmp eq i32 %shl, 25 2910 ret i1 %cmp 2911} 2912 2913define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) { 2914; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2( 2915; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1 2916; CHECK-NEXT: ret i1 [[CMP]] 2917; 2918 %shl = shl i32 25, %a 2919 %cmp = icmp eq i32 %shl, 50 2920 ret i1 %cmp 2921} 2922 2923define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) { 2924; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3( 2925; CHECK-NEXT: ret i1 false 2926; 2927 %shl = shl i32 26, %a 2928 %cmp = icmp eq i32 %shl, 50 2929 ret i1 %cmp 2930} 2931 2932define i1 @icmp_sgt_zero_add_nsw(i32 %a) { 2933; CHECK-LABEL: @icmp_sgt_zero_add_nsw( 2934; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1 2935; CHECK-NEXT: ret i1 [[CMP]] 2936; 2937 %add = add nsw i32 %a, 1 2938 %cmp = icmp sgt i32 %add, 0 2939 ret i1 %cmp 2940} 2941 2942define i1 @icmp_sge_zero_add_nsw(i32 %a) { 2943; CHECK-LABEL: @icmp_sge_zero_add_nsw( 2944; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2 2945; CHECK-NEXT: ret i1 [[CMP]] 2946; 2947 %add = add nsw i32 %a, 1 2948 %cmp = icmp sge i32 %add, 0 2949 ret i1 %cmp 2950} 2951 2952define i1 @icmp_sle_zero_add_nsw(i32 %a) { 2953; CHECK-LABEL: @icmp_sle_zero_add_nsw( 2954; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0 2955; CHECK-NEXT: ret i1 [[CMP]] 2956; 2957 %add = add nsw i32 %a, 1 2958 %cmp = icmp sle i32 %add, 0 2959 ret i1 %cmp 2960} 2961 2962define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) { 2963; CHECK-LABEL: @icmp_cmpxchg_strong( 2964; CHECK-NEXT: [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst 2965; CHECK-NEXT: [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1 2966; CHECK-NEXT: ret i1 [[ICMP]] 2967; 2968 %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst 2969 %xtrc = extractvalue { i32, i1 } %xchg, 0 2970 %icmp = icmp eq i32 %xtrc, %old_val 2971 ret i1 %icmp 2972} 2973 2974define i1 @f1(i64 %a, i64 %b) { 2975; CHECK-LABEL: @f1( 2976; CHECK-NEXT: [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]] 2977; CHECK-NEXT: ret i1 [[V]] 2978; 2979 %t = sub nsw i64 %a, %b 2980 %v = icmp sge i64 %t, 0 2981 ret i1 %v 2982} 2983 2984define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) { 2985; CHECK-LABEL: @f1_vec( 2986; CHECK-NEXT: [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]] 2987; CHECK-NEXT: ret <2 x i1> [[V]] 2988; 2989 %t = sub nsw <2 x i64> %a, %b 2990 %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1> 2991 ret <2 x i1> %v 2992} 2993 2994define i1 @f2(i64 %a, i64 %b) { 2995; CHECK-LABEL: @f2( 2996; CHECK-NEXT: [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]] 2997; CHECK-NEXT: ret i1 [[V]] 2998; 2999 %t = sub nsw i64 %a, %b 3000 %v = icmp sgt i64 %t, 0 3001 ret i1 %v 3002} 3003 3004define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) { 3005; CHECK-LABEL: @f2_vec( 3006; CHECK-NEXT: [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]] 3007; CHECK-NEXT: ret <2 x i1> [[V]] 3008; 3009 %t = sub nsw <2 x i64> %a, %b 3010 %v = icmp sgt <2 x i64> %t, zeroinitializer 3011 ret <2 x i1> %v 3012} 3013 3014define i1 @f3(i64 %a, i64 %b) { 3015; CHECK-LABEL: @f3( 3016; CHECK-NEXT: [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]] 3017; CHECK-NEXT: ret i1 [[V]] 3018; 3019 %t = sub nsw i64 %a, %b 3020 %v = icmp slt i64 %t, 0 3021 ret i1 %v 3022} 3023 3024define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) { 3025; CHECK-LABEL: @f3_vec( 3026; CHECK-NEXT: [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]] 3027; CHECK-NEXT: ret <2 x i1> [[V]] 3028; 3029 %t = sub nsw <2 x i64> %a, %b 3030 %v = icmp slt <2 x i64> %t, zeroinitializer 3031 ret <2 x i1> %v 3032} 3033 3034define i1 @f4(i64 %a, i64 %b) { 3035; CHECK-LABEL: @f4( 3036; CHECK-NEXT: [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]] 3037; CHECK-NEXT: ret i1 [[V]] 3038; 3039 %t = sub nsw i64 %a, %b 3040 %v = icmp sle i64 %t, 0 3041 ret i1 %v 3042} 3043 3044define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) { 3045; CHECK-LABEL: @f4_vec( 3046; CHECK-NEXT: [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]] 3047; CHECK-NEXT: ret <2 x i1> [[V]] 3048; 3049 %t = sub nsw <2 x i64> %a, %b 3050 %v = icmp slt <2 x i64> %t, <i64 1, i64 1> 3051 ret <2 x i1> %v 3052} 3053 3054define i32 @f5(i8 %a, i8 %b) { 3055; CHECK-LABEL: @f5( 3056; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 3057; CHECK-NEXT: [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32 3058; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]] 3059; CHECK-NEXT: [[CMP4:%.*]] = icmp slt i32 [[SUB]], 0 3060; CHECK-NEXT: [[SUB7:%.*]] = sub nsw i32 0, [[SUB]] 3061; CHECK-NEXT: [[SUB7_SUB:%.*]] = select i1 [[CMP4]], i32 [[SUB7]], i32 [[SUB]] 3062; CHECK-NEXT: ret i32 [[SUB7_SUB]] 3063; 3064 %conv = zext i8 %a to i32 3065 %conv3 = zext i8 %b to i32 3066 %sub = sub nsw i32 %conv, %conv3 3067 %cmp4 = icmp slt i32 %sub, 0 3068 %sub7 = sub nsw i32 0, %sub 3069 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub 3070 ret i32 %sub7.sub 3071} 3072 3073define i32 @f6(i32 %a, i32 %b) { 3074; CHECK-LABEL: @f6( 3075; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 3076; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255 3077; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0 3078; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0 3079; CHECK-NEXT: ret i32 [[S]] 3080; 3081 %sext = shl i32 %a, 24 3082 %conv = ashr i32 %sext, 24 3083 %sext6 = shl i32 %b, 24 3084 %conv4 = ashr i32 %sext6, 24 3085 %cmp = icmp eq i32 %conv, %conv4 3086 %s = select i1 %cmp, i32 10000, i32 0 3087 ret i32 %s 3088} 3089 3090define i32 @f7(i32 %a, i32 %b) { 3091; CHECK-LABEL: @f7( 3092; CHECK-NEXT: [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 3093; CHECK-NEXT: [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 511 3094; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 0 3095; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 10000 3096; CHECK-NEXT: ret i32 [[S]] 3097; 3098 %sext = shl i32 %a, 23 3099 %sext6 = shl i32 %b, 23 3100 %cmp = icmp ne i32 %sext, %sext6 3101 %s = select i1 %cmp, i32 10000, i32 0 3102 ret i32 %s 3103} 3104 3105define i1 @f8(i32 %val, i32 %lim) { 3106; CHECK-LABEL: @f8( 3107; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0 3108; CHECK-NEXT: ret i1 [[R]] 3109; 3110 %lim.sub = add i32 %lim, -1 3111 %val.and = and i32 %val, %lim.sub 3112 %r = icmp ult i32 %val.and, %lim 3113 ret i1 %r 3114} 3115 3116define i1 @f9(i32 %val, i32 %lim) { 3117; CHECK-LABEL: @f9( 3118; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0 3119; CHECK-NEXT: ret i1 [[R]] 3120; 3121 %lim.sub = sub i32 %lim, 1 3122 %val.and = and i32 %val, %lim.sub 3123 %r = icmp ult i32 %val.and, %lim 3124 ret i1 %r 3125} 3126 3127define i1 @f10(i16 %p) { 3128; CHECK-LABEL: @f10( 3129; 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)) 3130; CHECK-NEXT: ret i1 [[CMP580]] 3131; 3132 %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 3133 ret i1 %cmp580 3134} 3135 3136; Note: fptosi is used in various tests below to ensure that operand complexity 3137; canonicalization does not kick in, which would make some of the tests 3138; equivalent to one another. 3139 3140define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) { 3141; CHECK-LABEL: @cmp_sgt_rhs_dec( 3142; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3143; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]] 3144; CHECK-NEXT: ret i1 [[CMP]] 3145; 3146 %conv = fptosi float %x to i32 3147 %dec = sub nsw i32 %i, 1 3148 %cmp = icmp sgt i32 %conv, %dec 3149 ret i1 %cmp 3150} 3151 3152define i1 @cmp_sle_rhs_dec(float %x, i32 %i) { 3153; CHECK-LABEL: @cmp_sle_rhs_dec( 3154; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3155; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]] 3156; CHECK-NEXT: ret i1 [[CMP]] 3157; 3158 %conv = fptosi float %x to i32 3159 %dec = sub nsw i32 %i, 1 3160 %cmp = icmp sle i32 %conv, %dec 3161 ret i1 %cmp 3162} 3163 3164define i1 @cmp_sge_rhs_inc(float %x, i32 %i) { 3165; CHECK-LABEL: @cmp_sge_rhs_inc( 3166; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3167; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]] 3168; CHECK-NEXT: ret i1 [[CMP]] 3169; 3170 %conv = fptosi float %x to i32 3171 %inc = add nsw i32 %i, 1 3172 %cmp = icmp sge i32 %conv, %inc 3173 ret i1 %cmp 3174} 3175 3176define i1 @cmp_slt_rhs_inc(float %x, i32 %i) { 3177; CHECK-LABEL: @cmp_slt_rhs_inc( 3178; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3179; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]] 3180; CHECK-NEXT: ret i1 [[CMP]] 3181; 3182 %conv = fptosi float %x to i32 3183 %inc = add nsw i32 %i, 1 3184 %cmp = icmp slt i32 %conv, %inc 3185 ret i1 %cmp 3186} 3187 3188define i1 @PR26407(i32 %x, i32 %y) { 3189; CHECK-LABEL: @PR26407( 3190; CHECK-NEXT: [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647 3191; CHECK-NEXT: [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647 3192; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]] 3193; CHECK-NEXT: ret i1 [[CMP]] 3194; 3195 %addx = add i32 %x, 2147483647 3196 %addy = add i32 %y, 2147483647 3197 %cmp = icmp uge i32 %addx, %addy 3198 ret i1 %cmp 3199} 3200 3201define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) { 3202; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq( 3203; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 3204; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43 3205; CHECK-NEXT: ret i1 [[CMP]] 3206; 3207 %or = or i32 %x, 42 3208 %cmp = icmp eq i32 %or, -1 3209 ret i1 %cmp 3210} 3211 3212define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) { 3213; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec( 3214; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43> 3215; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43> 3216; CHECK-NEXT: ret <2 x i1> [[CMP]] 3217; 3218 %or = or <2 x i32> %x, <i32 42, i32 42> 3219 %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1> 3220 ret <2 x i1> %cmp 3221} 3222 3223define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) { 3224; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne( 3225; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 3226; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43 3227; CHECK-NEXT: ret i1 [[CMP]] 3228; 3229 %or = or i32 %x, 42 3230 %cmp = icmp ne i32 %or, -1 3231 ret i1 %cmp 3232} 3233 3234; When canonicalizing to 'gt/lt', make sure the constant is correct. 3235 3236define i1 @PR27792(i128 %a) { 3237; CHECK-LABEL: @PR27792( 3238; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1 3239; CHECK-NEXT: ret i1 [[CMP]] 3240; 3241 %cmp = icmp sge i128 %a, 0 3242 ret i1 %cmp 3243} 3244 3245define i1 @PR27792_2(i128 %a) { 3246; CHECK-LABEL: @PR27792_2( 3247; CHECK-NEXT: [[B:%.*]] = icmp ne i128 [[A:%.*]], 0 3248; CHECK-NEXT: ret i1 [[B]] 3249; 3250 %b = icmp uge i128 %a, 1 3251 ret i1 %b 3252} 3253 3254define i1 @ugtMaxSignedVal(i8 %a) { 3255; CHECK-LABEL: @ugtMaxSignedVal( 3256; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0 3257; CHECK-NEXT: ret i1 [[CMP]] 3258; 3259 %cmp = icmp ugt i8 %a, 127 3260 ret i1 %cmp 3261} 3262 3263define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) { 3264; CHECK-LABEL: @ugtMaxSignedValVec( 3265; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer 3266; CHECK-NEXT: ret <2 x i1> [[CMP]] 3267; 3268 %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127> 3269 ret <2 x i1> %cmp 3270} 3271 3272define i1 @ugtKnownBits(i8 %a) { 3273; CHECK-LABEL: @ugtKnownBits( 3274; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 17 3275; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 17 3276; CHECK-NEXT: ret i1 [[CMP]] 3277; 3278 %b = and i8 %a, 17 3279 %cmp = icmp ugt i8 %b, 16 3280 ret i1 %cmp 3281} 3282 3283define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) { 3284; CHECK-LABEL: @ugtKnownBitsVec( 3285; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17> 3286; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17> 3287; CHECK-NEXT: ret <2 x i1> [[CMP]] 3288; 3289 %b = and <2 x i8> %a, <i8 17, i8 17> 3290 %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16> 3291 ret <2 x i1> %cmp 3292} 3293 3294define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) { 3295; CHECK-LABEL: @or_ptrtoint_mismatch( 3296; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null 3297; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null 3298; CHECK-NEXT: [[B:%.*]] = and i1 [[TMP1]], [[TMP2]] 3299; CHECK-NEXT: ret i1 [[B]] 3300; 3301 3302 %pp = ptrtoint i8* %p to i64 3303 %qq = ptrtoint i32* %q to i64 3304 %o = or i64 %pp, %qq 3305 %b = icmp eq i64 %o, 0 3306 ret i1 %b 3307} 3308 3309define i1 @icmp_add1_ugt(i32 %x, i32 %y) { 3310; CHECK-LABEL: @icmp_add1_ugt( 3311; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 3312; CHECK-NEXT: ret i1 [[CMP]] 3313; 3314 %add = add nuw i32 %x, 1 3315 %cmp = icmp ugt i32 %add, %y 3316 ret i1 %cmp 3317} 3318 3319define i1 @icmp_add1_ule(i32 %x, i32 %y) { 3320; CHECK-LABEL: @icmp_add1_ule( 3321; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 3322; CHECK-NEXT: ret i1 [[CMP]] 3323; 3324 %add = add nuw i32 %x, 1 3325 %cmp = icmp ule i32 %add, %y 3326 ret i1 %cmp 3327} 3328 3329define i1 @cmp_uge_rhs_inc(float %x, i32 %i) { 3330; CHECK-LABEL: @cmp_uge_rhs_inc( 3331; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3332; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]] 3333; CHECK-NEXT: ret i1 [[CMP]] 3334; 3335 %conv = fptosi float %x to i32 3336 %inc = add nuw i32 %i, 1 3337 %cmp = icmp uge i32 %conv, %inc 3338 ret i1 %cmp 3339} 3340 3341define i1 @cmp_ult_rhs_inc(float %x, i32 %i) { 3342; CHECK-LABEL: @cmp_ult_rhs_inc( 3343; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3344; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]] 3345; CHECK-NEXT: ret i1 [[CMP]] 3346; 3347 %conv = fptosi float %x to i32 3348 %inc = add nuw i32 %i, 1 3349 %cmp = icmp ult i32 %conv, %inc 3350 ret i1 %cmp 3351} 3352 3353define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) { 3354; CHECK-LABEL: @cmp_sge_lhs_inc( 3355; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[X:%.*]], 1 3356; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]] 3357; CHECK-NEXT: ret i1 [[CMP]] 3358; 3359 %inc = add nsw i32 %x, 1 3360 %cmp = icmp sge i32 %inc, %y 3361 ret i1 %cmp 3362} 3363 3364define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) { 3365; CHECK-LABEL: @cmp_uge_lhs_inc( 3366; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[X:%.*]], 1 3367; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]] 3368; CHECK-NEXT: ret i1 [[CMP]] 3369; 3370 %inc = add nuw i32 %x, 1 3371 %cmp = icmp uge i32 %inc, %y 3372 ret i1 %cmp 3373} 3374 3375define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) { 3376; CHECK-LABEL: @cmp_sgt_lhs_dec( 3377; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1 3378; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]] 3379; CHECK-NEXT: ret i1 [[CMP]] 3380; 3381 %dec = sub nsw i32 %x, 1 3382 %cmp = icmp sgt i32 %dec, %y 3383 ret i1 %cmp 3384} 3385 3386define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) { 3387; CHECK-LABEL: @cmp_ugt_lhs_dec( 3388; CHECK-NEXT: [[DEC:%.*]] = add i32 [[X:%.*]], -1 3389; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]] 3390; CHECK-NEXT: ret i1 [[CMP]] 3391; 3392 %dec = sub nuw i32 %x, 1 3393 %cmp = icmp ugt i32 %dec, %y 3394 ret i1 %cmp 3395} 3396 3397define i1 @cmp_sle_rhs_inc(float %x, i32 %y) { 3398; CHECK-LABEL: @cmp_sle_rhs_inc( 3399; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3400; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1 3401; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]] 3402; CHECK-NEXT: ret i1 [[CMP]] 3403; 3404 %conv = fptosi float %x to i32 3405 %inc = add nsw i32 %y, 1 3406 %cmp = icmp sle i32 %conv, %inc 3407 ret i1 %cmp 3408} 3409 3410define i1 @cmp_ule_rhs_inc(float %x, i32 %y) { 3411; CHECK-LABEL: @cmp_ule_rhs_inc( 3412; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3413; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1 3414; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]] 3415; CHECK-NEXT: ret i1 [[CMP]] 3416; 3417 %conv = fptosi float %x to i32 3418 %inc = add nuw i32 %y, 1 3419 %cmp = icmp ule i32 %conv, %inc 3420 ret i1 %cmp 3421} 3422 3423define i1 @cmp_slt_rhs_dec(float %x, i32 %y) { 3424; CHECK-LABEL: @cmp_slt_rhs_dec( 3425; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3426; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1 3427; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]] 3428; CHECK-NEXT: ret i1 [[CMP]] 3429; 3430 %conv = fptosi float %x to i32 3431 %dec = sub nsw i32 %y, 1 3432 %cmp = icmp slt i32 %conv, %dec 3433 ret i1 %cmp 3434} 3435 3436define i1 @cmp_ult_rhs_dec(float %x, i32 %y) { 3437; CHECK-LABEL: @cmp_ult_rhs_dec( 3438; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3439; CHECK-NEXT: [[DEC:%.*]] = add i32 [[Y:%.*]], -1 3440; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]] 3441; CHECK-NEXT: ret i1 [[CMP]] 3442; 3443 %conv = fptosi float %x to i32 3444 %dec = sub nuw i32 %y, 1 3445 %cmp = icmp ult i32 %conv, %dec 3446 ret i1 %cmp 3447} 3448 3449define i1 @eq_add_constants(i32 %x, i32 %y) { 3450; CHECK-LABEL: @eq_add_constants( 3451; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 3452; CHECK-NEXT: ret i1 [[C]] 3453; 3454 %A = add i32 %x, 5 3455 %B = add i32 %y, 5 3456 %C = icmp eq i32 %A, %B 3457 ret i1 %C 3458} 3459 3460declare i32 @llvm.bswap.i32(i32) 3461 3462define i1 @bswap_ne(i32 %x, i32 %y) { 3463; CHECK-LABEL: @bswap_ne( 3464; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 3465; CHECK-NEXT: ret i1 [[CMP]] 3466; 3467 %swapx = call i32 @llvm.bswap.i32(i32 %x) 3468 %swapy = call i32 @llvm.bswap.i32(i32 %y) 3469 %cmp = icmp ne i32 %swapx, %swapy 3470 ret i1 %cmp 3471} 3472 3473declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>) 3474 3475define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) { 3476; CHECK-LABEL: @bswap_vec_eq( 3477; CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]] 3478; CHECK-NEXT: ret <8 x i1> [[CMP]] 3479; 3480 %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x) 3481 %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y) 3482 %cmp = icmp eq <8 x i16> %swapx, %swapy 3483 ret <8 x i1> %cmp 3484} 3485 3486declare i64 @llvm.bitreverse.i64(i64) 3487 3488define i1 @bitreverse_eq(i64 %x, i64 %y) { 3489; CHECK-LABEL: @bitreverse_eq( 3490; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] 3491; CHECK-NEXT: ret i1 [[CMP]] 3492; 3493 %revx = call i64 @llvm.bitreverse.i64(i64 %x) 3494 %revy = call i64 @llvm.bitreverse.i64(i64 %y) 3495 %cmp = icmp eq i64 %revx, %revy 3496 ret i1 %cmp 3497} 3498 3499declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>) 3500 3501define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) { 3502; CHECK-LABEL: @bitreverse_vec_ne( 3503; CHECK-NEXT: [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]] 3504; CHECK-NEXT: ret <8 x i1> [[CMP]] 3505; 3506 %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x) 3507 %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y) 3508 %cmp = icmp ne <8 x i16> %revx, %revy 3509 ret <8 x i1> %cmp 3510} 3511 3512; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7. 3513; They should all simplify to equality compares. 3514define i1 @knownbits1(i8 %a, i8 %b) { 3515; CHECK-LABEL: @knownbits1( 3516; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3517; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3518; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3519; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3520; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]] 3521; CHECK-NEXT: ret i1 [[C]] 3522; 3523 %a1 = and i8 %a, 5 3524 %a2 = or i8 %a1, 4 3525 %b1 = and i8 %b, 7 3526 %b2 = or i8 %b1, 5 3527 %c = icmp uge i8 %a2, %b2 3528 ret i1 %c 3529} 3530 3531define i1 @knownbits2(i8 %a, i8 %b) { 3532; CHECK-LABEL: @knownbits2( 3533; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3534; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3535; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3536; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3537; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]] 3538; CHECK-NEXT: ret i1 [[C]] 3539; 3540 %a1 = and i8 %a, 5 3541 %a2 = or i8 %a1, 4 3542 %b1 = and i8 %b, 7 3543 %b2 = or i8 %b1, 5 3544 %c = icmp ult i8 %a2, %b2 3545 ret i1 %c 3546} 3547 3548define i1 @knownbits3(i8 %a, i8 %b) { 3549; CHECK-LABEL: @knownbits3( 3550; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 3551; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3552; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3553; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3554; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B2]], [[A2]] 3555; CHECK-NEXT: ret i1 [[C]] 3556; 3557 %a1 = and i8 %a, 5 3558 %a2 = or i8 %a1, 4 3559 %b1 = and i8 %b, 7 3560 %b2 = or i8 %b1, 5 3561 %c = icmp ule i8 %b2, %a2 3562 ret i1 %c 3563} 3564 3565define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) { 3566; CHECK-LABEL: @knownbits4( 3567; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1> 3568; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4> 3569; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2> 3570; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5> 3571; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]] 3572; CHECK-NEXT: ret <2 x i1> [[C]] 3573; 3574 %a1 = and <2 x i8> %a, <i8 5, i8 5> 3575 %a2 = or <2 x i8> %a1, <i8 4, i8 4> 3576 %b1 = and <2 x i8> %b, <i8 7, i8 7> 3577 %b2 = or <2 x i8> %b1, <i8 5, i8 5> 3578 %c = icmp ugt <2 x i8> %b2, %a2 3579 ret <2 x i1> %c 3580} 3581 3582; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative. 3583; The other is known to be a value 5-7. These should simplify to equality comparisons. 3584define i1 @knownbits5(i8 %a, i8 %b) { 3585; CHECK-LABEL: @knownbits5( 3586; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3587; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3588; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3589; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3590; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]] 3591; CHECK-NEXT: ret i1 [[C]] 3592; 3593 %a1 = and i8 %a, 133 3594 %a2 = or i8 %a1, 4 3595 %b1 = and i8 %b, 7 3596 %b2 = or i8 %b1, 5 3597 %c = icmp sge i8 %a2, %b2 3598 ret i1 %c 3599} 3600 3601define i1 @knownbits6(i8 %a, i8 %b) { 3602; CHECK-LABEL: @knownbits6( 3603; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3604; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3605; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3606; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3607; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]] 3608; CHECK-NEXT: ret i1 [[C]] 3609; 3610 %a1 = and i8 %a, 133 3611 %a2 = or i8 %a1, 4 3612 %b1 = and i8 %b, 7 3613 %b2 = or i8 %b1, 5 3614 %c = icmp slt i8 %a2, %b2 3615 ret i1 %c 3616} 3617 3618define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) { 3619; CHECK-LABEL: @knownbits7( 3620; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127> 3621; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4> 3622; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2> 3623; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5> 3624; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]] 3625; CHECK-NEXT: ret <2 x i1> [[C]] 3626; 3627 %a1 = and <2 x i8> %a, <i8 133, i8 133> 3628 %a2 = or <2 x i8> %a1, <i8 4, i8 4> 3629 %b1 = and <2 x i8> %b, <i8 7, i8 7> 3630 %b2 = or <2 x i8> %b1, <i8 5, i8 5> 3631 %c = icmp sle <2 x i8> %b2, %a2 3632 ret <2 x i1> %c 3633} 3634 3635define i1 @knownbits8(i8 %a, i8 %b) { 3636; CHECK-LABEL: @knownbits8( 3637; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 3638; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4 3639; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 3640; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5 3641; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[B2]], [[A2]] 3642; CHECK-NEXT: ret i1 [[C]] 3643; 3644 %a1 = and i8 %a, 133 3645 %a2 = or i8 %a1, 4 3646 %b1 = and i8 %b, 7 3647 %b2 = or i8 %b1, 5 3648 %c = icmp sgt i8 %b2, %a2 3649 ret i1 %c 3650} 3651 3652; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom 3653define i32 @abs_preserve(i32 %x) { 3654; CHECK-LABEL: @abs_preserve( 3655; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X:%.*]], 1 3656; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A]], 0 3657; CHECK-NEXT: [[NEGA:%.*]] = sub i32 0, [[A]] 3658; CHECK-NEXT: [[ABS:%.*]] = select i1 [[C]], i32 [[NEGA]], i32 [[A]] 3659; CHECK-NEXT: ret i32 [[ABS]] 3660; 3661 %a = mul nsw i32 %x, 2 3662 %c = icmp sge i32 %a, 0 3663 %nega = sub i32 0, %a 3664 %abs = select i1 %c, i32 %a, i32 %nega 3665 ret i32 %abs 3666} 3667 3668; Don't crash by assuming the compared values are integers. 3669 3670declare void @llvm.assume(i1) 3671define i1 @PR35794(i32* %a) { 3672; CHECK-LABEL: @PR35794( 3673; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null 3674; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 3675; CHECK-NEXT: ret i1 true 3676; 3677 %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*) 3678 %maskcond = icmp eq i32* %a, null 3679 tail call void @llvm.assume(i1 %maskcond) 3680 ret i1 %cmp 3681} 3682 3683; Don't crash by assuming the compared values are integers. 3684define <2 x i1> @PR36583(<2 x i8*>) { 3685; CHECK-LABEL: @PR36583( 3686; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer 3687; CHECK-NEXT: ret <2 x i1> [[RES]] 3688; 3689 %cast = ptrtoint <2 x i8*> %0 to <2 x i64> 3690 %res = icmp eq <2 x i64> %cast, zeroinitializer 3691 ret <2 x i1> %res 3692} 3693 3694; fold (icmp pred (sub (0, X)) C1) for vec type 3695define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) { 3696; CHECK-LABEL: @Op1Negated_Vec( 3697; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]] 3698; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer 3699; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> [[X]] 3700; CHECK-NEXT: ret <2 x i32> [[COND]] 3701; 3702 %sub = sub nsw <2 x i32> zeroinitializer, %x 3703 %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1> 3704 %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x 3705 ret <2 x i32> %cond 3706} 3707 3708define i1 @signbit_bitcast_fpext(float %x) { 3709; CHECK-LABEL: @signbit_bitcast_fpext( 3710; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32 3711; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 3712; CHECK-NEXT: ret i1 [[R]] 3713; 3714 %f = fpext float %x to double 3715 %b = bitcast double %f to i64 3716 %r = icmp slt i64 %b, 0 3717 ret i1 %r 3718} 3719 3720define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) { 3721; CHECK-LABEL: @signbit_bitcast_fpext_vec( 3722; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x half> [[X:%.*]] to <2 x i16> 3723; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer 3724; CHECK-NEXT: ret <2 x i1> [[R]] 3725; 3726 %f = fpext <2 x half> %x to <2 x float> 3727 %b = bitcast <2 x float> %f to <2 x i32> 3728 %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647> 3729 ret <2 x i1> %r 3730} 3731 3732define i1 @signbit_bitcast_fptrunc(float %x) { 3733; CHECK-LABEL: @signbit_bitcast_fptrunc( 3734; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32 3735; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 3736; CHECK-NEXT: ret i1 [[R]] 3737; 3738 %f = fptrunc float %x to half 3739 %b = bitcast half %f to i16 3740 %r = icmp ult i16 %b, 32768 3741 ret i1 %r 3742} 3743 3744define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) { 3745; CHECK-LABEL: @signbit_bitcast_fptrunc_vec( 3746; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64> 3747; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], <i64 -1, i64 -1> 3748; CHECK-NEXT: ret <2 x i1> [[R]] 3749; 3750 %f = fptrunc <2 x double> %x to <2 x half> 3751 %b = bitcast <2 x half> %f to <2 x i16> 3752 %r = icmp sge <2 x i16> %b, zeroinitializer 3753 ret <2 x i1> %r 3754} 3755 3756define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) { 3757; CHECK-LABEL: @signbit_bitcast_fpext_wrong_cmp( 3758; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double 3759; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 3760; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 1 3761; CHECK-NEXT: ret i1 [[R]] 3762; 3763 %f = fpext float %x to double 3764 %b = bitcast double %f to i64 3765 %r = icmp slt i64 %b, 1 3766 ret i1 %r 3767} 3768 3769define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) { 3770; CHECK-LABEL: @signbit_bitcast_fpext_vec_wrong_bitcast( 3771; CHECK-NEXT: [[F:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x float> 3772; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16> 3773; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i16> [[B]], <i16 -1, i16 -1, i16 -1, i16 -1> 3774; CHECK-NEXT: ret <4 x i1> [[R]] 3775; 3776 %f = fpext <2 x half> %x to <2 x float> 3777 %b = bitcast <2 x float> %f to <4 x i16> 3778 %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1> 3779 ret <4 x i1> %r 3780} 3781 3782declare void @use_i64(i64) 3783 3784define i1 @signbit_bitcast_fpext_extra_use(float %x, i64* %p) { 3785; CHECK-LABEL: @signbit_bitcast_fpext_extra_use( 3786; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double 3787; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 3788; CHECK-NEXT: call void @use_i64(i64 [[B]]) 3789; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 0 3790; CHECK-NEXT: ret i1 [[R]] 3791; 3792 %f = fpext float %x to double 3793 %b = bitcast double %f to i64 3794 call void @use_i64(i64 %b) 3795 %r = icmp slt i64 %b, 0 3796 ret i1 %r 3797} 3798 3799define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) { 3800; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128( 3801; CHECK-NEXT: [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128 3802; CHECK-NEXT: [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128 3803; CHECK-NEXT: [[S4:%.*]] = icmp slt i128 [[S3]], 0 3804; CHECK-NEXT: ret i1 [[S4]] 3805; 3806 %s2 = fpext float %x to ppc_fp128 3807 %s3 = bitcast ppc_fp128 %s2 to i128 3808 %s4 = icmp slt i128 %s3, 0 3809 ret i1 %s4 3810} 3811 3812define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) { 3813; CHECK-LABEL: @signbit_bitcast_fptrunc_ppc_fp128( 3814; CHECK-NEXT: [[S2:%.*]] = fptrunc ppc_fp128 [[X:%.*]] to float 3815; CHECK-NEXT: [[S3:%.*]] = bitcast float [[S2]] to i32 3816; CHECK-NEXT: [[S4:%.*]] = icmp slt i32 [[S3]], 0 3817; CHECK-NEXT: ret i1 [[S4]] 3818; 3819 %s2 = fptrunc ppc_fp128 %x to float 3820 %s3 = bitcast float %s2 to i32 3821 %s4 = icmp slt i32 %s3, 0 3822 ret i1 %s4 3823} 3824 3825@x = external dso_local local_unnamed_addr global i32, align 4 3826@y = external dso_local local_unnamed_addr global i32, align 4 3827define i1 @pr47997(i32 %arg) { 3828; CHECK-LABEL: @pr47997( 3829; CHECK-NEXT: bb: 3830; CHECK-NEXT: [[I:%.*]] = add nsw i32 [[ARG:%.*]], -1 3831; CHECK-NEXT: store i32 [[I]], i32* @x, align 4 3832; CHECK-NEXT: [[I1:%.*]] = sub nsw i32 1, [[ARG]] 3833; CHECK-NEXT: store i32 [[I1]], i32* @y, align 4 3834; CHECK-NEXT: ret i1 true 3835; 3836bb: 3837 %i = add nsw i32 %arg, -1 3838 store i32 %i, i32* @x 3839 %i1 = sub nsw i32 1, %arg 3840 store i32 %i1, i32* @y 3841 %i2 = sub nsw i32 0, %i1 3842 %i3 = icmp eq i32 %i, %i2 3843 ret i1 %i3 3844} 3845