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