1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 5 6declare i8 @llvm.abs.i8(i8, i1) 7 8declare void @use_i1(i1) 9declare void @use_i8(i8) 10declare void @use_i32(i32) 11declare void @use_i64(i64) 12 13define i32 @test1(i32 %X) { 14; CHECK-LABEL: @test1( 15; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31 16; CHECK-NEXT: ret i32 [[X_LOBIT]] 17; 18 %a = icmp slt i32 %X, 0 19 %b = zext i1 %a to i32 20 ret i32 %b 21} 22 23define <2 x i32> @test1vec(<2 x i32> %X) { 24; CHECK-LABEL: @test1vec( 25; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 31) 26; CHECK-NEXT: ret <2 x i32> [[X_LOBIT]] 27; 28 %a = icmp slt <2 x i32> %X, zeroinitializer 29 %b = zext <2 x i1> %a to <2 x i32> 30 ret <2 x i32> %b 31} 32 33define i32 @test2(i32 %X) { 34; CHECK-LABEL: @test2( 35; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1 36; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32 37; CHECK-NEXT: ret i32 [[B]] 38; 39 %a = icmp ult i32 %X, -2147483648 40 %b = zext i1 %a to i32 41 ret i32 %b 42} 43 44define <2 x i32> @test2vec(<2 x i32> %X) { 45; CHECK-LABEL: @test2vec( 46; CHECK-NEXT: [[A:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1) 47; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[A]] to <2 x i32> 48; CHECK-NEXT: ret <2 x i32> [[B]] 49; 50 %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648> 51 %b = zext <2 x i1> %a to <2 x i32> 52 ret <2 x i32> %b 53} 54 55define i32 @test3(i32 %X) { 56; CHECK-LABEL: @test3( 57; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31 58; CHECK-NEXT: ret i32 [[X_LOBIT]] 59; 60 %a = icmp slt i32 %X, 0 61 %b = sext i1 %a to i32 62 ret i32 %b 63} 64 65define i32 @test4(i32 %X) { 66; CHECK-LABEL: @test4( 67; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1 68; CHECK-NEXT: [[B:%.*]] = sext i1 [[A]] to i32 69; CHECK-NEXT: ret i32 [[B]] 70; 71 %a = icmp ult i32 %X, -2147483648 72 %b = sext i1 %a to i32 73 ret i32 %b 74} 75 76; PR4837 77define <2 x i1> @test5_eq(<2 x i64> %x) { 78; CHECK-LABEL: @test5_eq( 79; CHECK-NEXT: ret <2 x i1> undef 80; 81 %V = icmp eq <2 x i64> %x, undef 82 ret <2 x i1> %V 83} 84define <2 x i1> @test5_ne(<2 x i64> %x) { 85; CHECK-LABEL: @test5_ne( 86; CHECK-NEXT: ret <2 x i1> undef 87; 88 %V = icmp ne <2 x i64> %x, undef 89 ret <2 x i1> %V 90} 91define <2 x i1> @test5_ugt(<2 x i64> %x) { 92; CHECK-LABEL: @test5_ugt( 93; CHECK-NEXT: ret <2 x i1> zeroinitializer 94; 95 %V = icmp ugt <2 x i64> %x, undef 96 ret <2 x i1> %V 97} 98define <2 x i1> @test5_zero() { 99; CHECK-LABEL: @test5_zero( 100; CHECK-NEXT: ret <2 x i1> undef 101; 102 %V = icmp eq <2 x i64> zeroinitializer, undef 103 ret <2 x i1> %V 104} 105 106define i32 @test6(i32 %a, i32 %b) { 107; CHECK-LABEL: @test6( 108; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0 109; CHECK-NEXT: [[F:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0 110; CHECK-NEXT: ret i32 [[F]] 111; 112 %c = icmp sle i32 %a, -1 113 %d = zext i1 %c to i32 114 %e = sub i32 0, %d 115 %f = and i32 %e, %b 116 ret i32 %f 117} 118 119 120define i1 @test7(i32 %x) { 121; CHECK-LABEL: @test7( 122; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0 123; CHECK-NEXT: ret i1 [[B]] 124; 125 %a = add i32 %x, -1 126 %b = icmp ult i32 %a, %x 127 ret i1 %b 128} 129 130define <2 x i1> @test7_vec(<2 x i32> %x) { 131; CHECK-LABEL: @test7_vec( 132; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 133; CHECK-NEXT: ret <2 x i1> [[B]] 134; 135 %a = add <2 x i32> %x, <i32 -1, i32 -1> 136 %b = icmp ult <2 x i32> %a, %x 137 ret <2 x i1> %b 138} 139 140define i1 @test8(i32 %x) { 141; CHECK-LABEL: @test8( 142; CHECK-NEXT: ret i1 false 143; 144 %a = add i32 %x, -1 145 %b = icmp eq i32 %a, %x 146 ret i1 %b 147} 148 149define <2 x i1> @test8_vec(<2 x i32> %x) { 150; CHECK-LABEL: @test8_vec( 151; CHECK-NEXT: ret <2 x i1> zeroinitializer 152; 153 %a = add <2 x i32> %x, <i32 -1, i32 -1> 154 %b = icmp eq <2 x i32> %a, %x 155 ret <2 x i1> %b 156} 157 158define i1 @test9(i32 %x) { 159; CHECK-LABEL: @test9( 160; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 [[X:%.*]], 1 161; CHECK-NEXT: ret i1 [[B]] 162; 163 %a = add i32 %x, -2 164 %b = icmp ugt i32 %x, %a 165 ret i1 %b 166} 167 168define <2 x i1> @test9_vec(<2 x i32> %x) { 169; CHECK-LABEL: @test9_vec( 170; CHECK-NEXT: [[B:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 1) 171; CHECK-NEXT: ret <2 x i1> [[B]] 172; 173 %a = add <2 x i32> %x, <i32 -2, i32 -2> 174 %b = icmp ugt <2 x i32> %x, %a 175 ret <2 x i1> %b 176} 177 178define i1 @test9b(i32 %x) { 179; CHECK-LABEL: @test9b( 180; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 2 181; CHECK-NEXT: ret i1 [[B]] 182; 183 %a = add i32 %x, -2 184 %b = icmp ugt i32 %a, %x 185 ret i1 %b 186} 187 188define <2 x i1> @test9b_vec(<2 x i32> %x) { 189; CHECK-LABEL: @test9b_vec( 190; CHECK-NEXT: [[B:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 2) 191; CHECK-NEXT: ret <2 x i1> [[B]] 192; 193 %a = add <2 x i32> %x, <i32 -2, i32 -2> 194 %b = icmp ugt <2 x i32> %a, %x 195 ret <2 x i1> %b 196} 197 198define i1 @test10(i32 %x) { 199; CHECK-LABEL: @test10( 200; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], -2147483648 201; CHECK-NEXT: ret i1 [[B]] 202; 203 %a = add i32 %x, -1 204 %b = icmp slt i32 %a, %x 205 ret i1 %b 206} 207 208define <2 x i1> @test10_vec(<2 x i32> %x) { 209; CHECK-LABEL: @test10_vec( 210; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 -2147483648) 211; CHECK-NEXT: ret <2 x i1> [[B]] 212; 213 %a = add <2 x i32> %x, <i32 -1, i32 -1> 214 %b = icmp slt <2 x i32> %a, %x 215 ret <2 x i1> %b 216} 217 218define i1 @test10b(i32 %x) { 219; CHECK-LABEL: @test10b( 220; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X:%.*]], -2147483648 221; CHECK-NEXT: ret i1 [[B]] 222; 223 %a = add i32 %x, -1 224 %b = icmp sgt i32 %a, %x 225 ret i1 %b 226} 227 228define <2 x i1> @test10b_vec(<2 x i32> %x) { 229; CHECK-LABEL: @test10b_vec( 230; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 -2147483648) 231; CHECK-NEXT: ret <2 x i1> [[B]] 232; 233 %a = add <2 x i32> %x, <i32 -1, i32 -1> 234 %b = icmp sgt <2 x i32> %a, %x 235 ret <2 x i1> %b 236} 237 238define i1 @test11(i32 %x) { 239; CHECK-LABEL: @test11( 240; CHECK-NEXT: ret i1 true 241; 242 %a = add nsw i32 %x, 8 243 %b = icmp slt i32 %x, %a 244 ret i1 %b 245} 246 247define <2 x i1> @test11_vec(<2 x i32> %x) { 248; CHECK-LABEL: @test11_vec( 249; CHECK-NEXT: ret <2 x i1> splat (i1 true) 250; 251 %a = add nsw <2 x i32> %x, <i32 8, i32 8> 252 %b = icmp slt <2 x i32> %x, %a 253 ret <2 x i1> %b 254} 255 256; PR6195 257define i1 @test12(i1 %A) { 258; CHECK-LABEL: @test12( 259; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true 260; CHECK-NEXT: ret i1 [[NOT_A]] 261; 262 %S = select i1 %A, i64 -4294967295, i64 8589934591 263 %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S 264 ret i1 %B 265} 266 267; PR6481 268define i1 @test13(i8 %X) { 269; CHECK-LABEL: @test13( 270; CHECK-NEXT: ret i1 false 271; 272 %cmp = icmp slt i8 undef, %X 273 ret i1 %cmp 274} 275 276define i1 @test14(i8 %X) { 277; CHECK-LABEL: @test14( 278; CHECK-NEXT: ret i1 false 279; 280 %cmp = icmp slt i8 undef, -128 281 ret i1 %cmp 282} 283 284define i1 @test15() { 285; CHECK-LABEL: @test15( 286; CHECK-NEXT: ret i1 undef 287; 288 %cmp = icmp eq i8 undef, -128 289 ret i1 %cmp 290} 291 292define i1 @test16() { 293; CHECK-LABEL: @test16( 294; CHECK-NEXT: ret i1 undef 295; 296 %cmp = icmp ne i8 undef, -128 297 ret i1 %cmp 298} 299 300define i1 @test17(i32 %x) { 301; CHECK-LABEL: @test17( 302; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 3 303; CHECK-NEXT: ret i1 [[TMP1]] 304; 305 %shl = shl i32 1, %x 306 %and = and i32 %shl, 8 307 %cmp = icmp eq i32 %and, 0 308 ret i1 %cmp 309} 310 311define <2 x i1> @test17vec(<2 x i32> %x) { 312; CHECK-LABEL: @test17vec( 313; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 3) 314; CHECK-NEXT: ret <2 x i1> [[TMP1]] 315; 316 %shl = shl <2 x i32> <i32 1, i32 1>, %x 317 %and = and <2 x i32> %shl, <i32 8, i32 8> 318 %cmp = icmp eq <2 x i32> %and, zeroinitializer 319 ret <2 x i1> %cmp 320} 321 322define i1 @test17a(i32 %x) { 323; CHECK-LABEL: @test17a( 324; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2 325; CHECK-NEXT: ret i1 [[CMP]] 326; 327 %shl = shl i32 1, %x 328 %and = and i32 %shl, 7 329 %cmp = icmp eq i32 %and, 0 330 ret i1 %cmp 331} 332 333define <2 x i1> @test17a_vec(<2 x i32> %x) { 334; CHECK-LABEL: @test17a_vec( 335; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 2) 336; CHECK-NEXT: ret <2 x i1> [[CMP]] 337; 338 %shl = shl <2 x i32> <i32 1, i32 1>, %x 339 %and = and <2 x i32> %shl, <i32 7, i32 7> 340 %cmp = icmp eq <2 x i32> %and, zeroinitializer 341 ret <2 x i1> %cmp 342} 343 344define i1 @test18_eq(i32 %x) { 345; CHECK-LABEL: @test18_eq( 346; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 3 347; CHECK-NEXT: ret i1 [[TMP1]] 348; 349 %sh = lshr i32 8, %x 350 %and = and i32 %sh, 1 351 %cmp = icmp eq i32 %and, 0 352 ret i1 %cmp 353} 354 355define <2 x i1> @test18_eq_vec(<2 x i32> %x) { 356; CHECK-LABEL: @test18_eq_vec( 357; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 3) 358; CHECK-NEXT: ret <2 x i1> [[TMP1]] 359; 360 %sh = lshr <2 x i32> <i32 8, i32 8>, %x 361 %and = and <2 x i32> %sh, <i32 1, i32 1> 362 %cmp = icmp eq <2 x i32> %and, zeroinitializer 363 ret <2 x i1> %cmp 364} 365 366define i1 @test18_ne(i32 %x) { 367; CHECK-LABEL: @test18_ne( 368; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3 369; CHECK-NEXT: ret i1 [[TMP1]] 370; 371 %sh = lshr i32 8, %x 372 %and = and i32 %sh, 1 373 %cmp = icmp ne i32 %and, 0 374 ret i1 %cmp 375} 376 377define <2 x i1> @test18_ne_vec(<2 x i32> %x) { 378; CHECK-LABEL: @test18_ne_vec( 379; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3) 380; CHECK-NEXT: ret <2 x i1> [[TMP1]] 381; 382 %sh = lshr <2 x i32> <i32 8, i32 8>, %x 383 %and = and <2 x i32> %sh, <i32 1, i32 1> 384 %cmp = icmp ne <2 x i32> %and, zeroinitializer 385 ret <2 x i1> %cmp 386} 387 388define i1 @test19(i32 %x) { 389; CHECK-LABEL: @test19( 390; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3 391; CHECK-NEXT: ret i1 [[TMP1]] 392; 393 %shl = shl i32 1, %x 394 %and = and i32 %shl, 8 395 %cmp = icmp eq i32 %and, 8 396 ret i1 %cmp 397} 398 399define <2 x i1> @test19vec(<2 x i32> %x) { 400; CHECK-LABEL: @test19vec( 401; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3) 402; CHECK-NEXT: ret <2 x i1> [[TMP1]] 403; 404 %shl = shl <2 x i32> <i32 1, i32 1>, %x 405 %and = and <2 x i32> %shl, <i32 8, i32 8> 406 %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8> 407 ret <2 x i1> %cmp 408} 409 410define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) { 411; CHECK-LABEL: @cmp_and_signbit_vec( 412; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i3> [[X:%.*]], zeroinitializer 413; CHECK-NEXT: ret <2 x i1> [[CMP]] 414; 415 %and = and <2 x i3> %x, <i3 4, i3 4> 416 %cmp = icmp ne <2 x i3> %and, zeroinitializer 417 ret <2 x i1> %cmp 418} 419 420define i1 @test20(i32 %x) { 421; CHECK-LABEL: @test20( 422; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3 423; CHECK-NEXT: ret i1 [[TMP1]] 424; 425 %shl = shl i32 1, %x 426 %and = and i32 %shl, 8 427 %cmp = icmp ne i32 %and, 0 428 ret i1 %cmp 429} 430 431define <2 x i1> @test20vec(<2 x i32> %x) { 432; CHECK-LABEL: @test20vec( 433; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3) 434; CHECK-NEXT: ret <2 x i1> [[TMP1]] 435; 436 %shl = shl <2 x i32> <i32 1, i32 1>, %x 437 %and = and <2 x i32> %shl, <i32 8, i32 8> 438 %cmp = icmp ne <2 x i32> %and, zeroinitializer 439 ret <2 x i1> %cmp 440} 441 442define i1 @test20a(i32 %x) { 443; CHECK-LABEL: @test20a( 444; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3 445; CHECK-NEXT: ret i1 [[CMP]] 446; 447 %shl = shl i32 1, %x 448 %and = and i32 %shl, 7 449 %cmp = icmp ne i32 %and, 0 450 ret i1 %cmp 451} 452 453define <2 x i1> @test20a_vec(<2 x i32> %x) { 454; CHECK-LABEL: @test20a_vec( 455; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 3) 456; CHECK-NEXT: ret <2 x i1> [[CMP]] 457; 458 %shl = shl <2 x i32> <i32 1, i32 1>, %x 459 %and = and <2 x i32> %shl, <i32 7, i32 7> 460 %cmp = icmp ne <2 x i32> %and, zeroinitializer 461 ret <2 x i1> %cmp 462} 463 464define i1 @test21(i8 %x, i8 %y) { 465; CHECK-LABEL: @test21( 466; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3 467; CHECK-NEXT: ret i1 [[B]] 468; 469 %A = or i8 %x, 1 470 %B = icmp ugt i8 %A, 3 471 ret i1 %B 472} 473 474define i1 @test22(i8 %x, i8 %y) { 475; CHECK-LABEL: @test22( 476; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 4 477; CHECK-NEXT: ret i1 [[B]] 478; 479 %A = or i8 %x, 1 480 %B = icmp ult i8 %A, 4 481 ret i1 %B 482} 483 484; PR2740 485define i1 @test23(i32 %x) { 486; CHECK-LABEL: @test23( 487; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[X:%.*]], 1328634634 488; CHECK-NEXT: ret i1 [[I4]] 489; 490 %i3 = sdiv i32 %x, -1328634635 491 %i4 = icmp eq i32 %i3, -1 492 ret i1 %i4 493} 494 495define <2 x i1> @test23vec(<2 x i32> %x) { 496; CHECK-LABEL: @test23vec( 497; CHECK-NEXT: [[I4:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 1328634634) 498; CHECK-NEXT: ret <2 x i1> [[I4]] 499; 500 %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635> 501 %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1> 502 ret <2 x i1> %i4 503} 504 505; Note: offs can be negative, LLVM used to make an incorrect assumption that 506; unsigned overflow does not happen during offset computation 507define i1 @test24_neg_offs(ptr %p, i64 %offs) { 508; CHECK-LABEL: @test24_neg_offs( 509; CHECK-NEXT: [[P1_IDX_NEG:%.*]] = mul i64 [[OFFS:%.*]], -4 510; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[P1_IDX_NEG]], 8 511; CHECK-NEXT: ret i1 [[CMP]] 512; 513 %p1 = getelementptr inbounds i32, ptr %p, i64 %offs 514 %conv1 = ptrtoint ptr %p to i64 515 %conv2 = ptrtoint ptr %p1 to i64 516 %delta = sub i64 %conv1, %conv2 517 %cmp = icmp eq i64 %delta, 8 518 ret i1 %cmp 519} 520 521; X - Z > Y - Z -> X > Y if there is no overflow. 522define i1 @test27(i32 %x, i32 %y, i32 %z) { 523; CHECK-LABEL: @test27( 524; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 525; CHECK-NEXT: ret i1 [[C]] 526; 527 %lhs = sub nsw i32 %x, %z 528 %rhs = sub nsw i32 %y, %z 529 %c = icmp sgt i32 %lhs, %rhs 530 ret i1 %c 531} 532 533define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) { 534; CHECK-LABEL: @test27_extra_uses( 535; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]] 536; CHECK-NEXT: call void @use_i32(i32 [[LHS]]) 537; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]] 538; CHECK-NEXT: call void @use_i32(i32 [[RHS]]) 539; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X]], [[Y]] 540; CHECK-NEXT: ret i1 [[C]] 541; 542 %lhs = sub nsw i32 %x, %z 543 call void @use_i32(i32 %lhs) 544 %rhs = sub nsw i32 %y, %z 545 call void @use_i32(i32 %rhs) 546 %c = icmp sgt i32 %lhs, %rhs 547 ret i1 %c 548} 549 550; X - Z > Y - Z -> X > Y if there is no overflow. 551define i1 @test28(i32 %x, i32 %y, i32 %z) { 552; CHECK-LABEL: @test28( 553; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 554; CHECK-NEXT: ret i1 [[C]] 555; 556 %lhs = sub nuw i32 %x, %z 557 %rhs = sub nuw i32 %y, %z 558 %c = icmp ugt i32 %lhs, %rhs 559 ret i1 %c 560} 561 562define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) { 563; CHECK-LABEL: @test28_extra_uses( 564; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]] 565; CHECK-NEXT: call void @use_i32(i32 [[LHS]]) 566; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]] 567; CHECK-NEXT: call void @use_i32(i32 [[RHS]]) 568; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]] 569; CHECK-NEXT: ret i1 [[C]] 570; 571 %lhs = sub nuw i32 %x, %z 572 call void @use_i32(i32 %lhs) 573 %rhs = sub nuw i32 %y, %z 574 call void @use_i32(i32 %rhs) 575 %c = icmp ugt i32 %lhs, %rhs 576 ret i1 %c 577} 578 579; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969 580 581define i1 @ugt_sub(i32 %xsrc, i32 %y) { 582; CHECK-LABEL: @ugt_sub( 583; CHECK-NEXT: [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42 584; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X]] 585; CHECK-NEXT: ret i1 [[CMP]] 586; 587 %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization 588 %sub = sub i32 %x, %y 589 %cmp = icmp ugt i32 %sub, %x 590 ret i1 %cmp 591} 592 593; Swap operands and predicate. Try a vector type to verify that works too. 594 595define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) { 596; CHECK-LABEL: @ult_sub( 597; CHECK-NEXT: [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42> 598; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]] 599; CHECK-NEXT: ret <2 x i1> [[CMP]] 600; 601 %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization 602 %sub = sub <2 x i8> %x, %y 603 %cmp = icmp ult <2 x i8> %x, %sub 604 ret <2 x i1> %cmp 605} 606 607; X - Y > X -> 0 > Y if there is no overflow. 608define i1 @test33(i32 %x, i32 %y) { 609; CHECK-LABEL: @test33( 610; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0 611; CHECK-NEXT: ret i1 [[C]] 612; 613 %lhs = sub nsw i32 %x, %y 614 %c = icmp sgt i32 %lhs, %x 615 ret i1 %c 616} 617 618; X - Y > X -> 0 > Y if there is no overflow. 619define i1 @test34(i32 %x, i32 %y) { 620; CHECK-LABEL: @test34( 621; CHECK-NEXT: ret i1 false 622; 623 %lhs = sub nuw i32 %x, %y 624 %c = icmp ugt i32 %lhs, %x 625 ret i1 %c 626} 627 628; X > X - Y -> Y > 0 if there is no overflow. 629define i1 @test35(i32 %x, i32 %y) { 630; CHECK-LABEL: @test35( 631; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0 632; CHECK-NEXT: ret i1 [[C]] 633; 634 %rhs = sub nsw i32 %x, %y 635 %c = icmp sgt i32 %x, %rhs 636 ret i1 %c 637} 638 639; X > X - Y -> Y > 0 if there is no overflow. 640define i1 @test36(i32 %x, i32 %y) { 641; CHECK-LABEL: @test36( 642; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0 643; CHECK-NEXT: ret i1 [[C]] 644; 645 %rhs = sub nuw i32 %x, %y 646 %c = icmp ugt i32 %x, %rhs 647 ret i1 %c 648} 649 650; X - Y > X - Z -> Z > Y if there is no overflow. 651define i1 @test37(i32 %x, i32 %y, i32 %z) { 652; CHECK-LABEL: @test37( 653; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]] 654; CHECK-NEXT: ret i1 [[C]] 655; 656 %lhs = sub nsw i32 %x, %y 657 %rhs = sub nsw i32 %x, %z 658 %c = icmp sgt i32 %lhs, %rhs 659 ret i1 %c 660} 661 662define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) { 663; CHECK-LABEL: @test37_extra_uses( 664; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 665; CHECK-NEXT: call void @use_i32(i32 [[LHS]]) 666; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]] 667; CHECK-NEXT: call void @use_i32(i32 [[RHS]]) 668; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]] 669; CHECK-NEXT: ret i1 [[C]] 670; 671 %lhs = sub nsw i32 %x, %y 672 call void @use_i32(i32 %lhs) 673 %rhs = sub nsw i32 %x, %z 674 call void @use_i32(i32 %rhs) 675 %c = icmp sgt i32 %lhs, %rhs 676 ret i1 %c 677} 678 679; TODO: Min/max pattern should not prevent the fold. 680 681define i32 @neg_max_s32(i32 %x, i32 %y) { 682; CHECK-LABEL: @neg_max_s32( 683; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 684; CHECK-NEXT: ret i32 [[TMP1]] 685; 686 %nx = sub nsw i32 0, %x 687 %ny = sub nsw i32 0, %y 688 %c = icmp slt i32 %nx, %ny 689 %s = select i1 %c, i32 %ny, i32 %nx 690 %r = sub nsw i32 0, %s 691 ret i32 %r 692} 693 694define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) { 695; CHECK-LABEL: @neg_max_v4s32( 696; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) 697; CHECK-NEXT: ret <4 x i32> [[TMP1]] 698; 699 %nx = sub nsw <4 x i32> zeroinitializer, %x 700 %ny = sub nsw <4 x i32> zeroinitializer, %y 701 %c = icmp sgt <4 x i32> %nx, %ny 702 %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny 703 %r = sub <4 x i32> zeroinitializer, %s 704 ret <4 x i32> %r 705} 706 707; X - Y > X - Z -> Z > Y if there is no overflow. 708define i1 @test38(i32 %x, i32 %y, i32 %z) { 709; CHECK-LABEL: @test38( 710; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]] 711; CHECK-NEXT: ret i1 [[C]] 712; 713 %lhs = sub nuw i32 %x, %y 714 %rhs = sub nuw i32 %x, %z 715 %c = icmp ugt i32 %lhs, %rhs 716 ret i1 %c 717} 718 719define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) { 720; CHECK-LABEL: @test38_extra_uses( 721; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]] 722; CHECK-NEXT: call void @use_i32(i32 [[LHS]]) 723; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]] 724; CHECK-NEXT: call void @use_i32(i32 [[RHS]]) 725; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]] 726; CHECK-NEXT: ret i1 [[C]] 727; 728 %lhs = sub nuw i32 %x, %y 729 call void @use_i32(i32 %lhs) 730 %rhs = sub nuw i32 %x, %z 731 call void @use_i32(i32 %rhs) 732 %c = icmp ugt i32 %lhs, %rhs 733 ret i1 %c 734} 735 736define i1 @shr_exact(i132 %x) { 737; CHECK-LABEL: @shr_exact( 738; CHECK-NEXT: [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32 739; CHECK-NEXT: ret i1 [[CMP]] 740; 741 %sh = ashr exact i132 %x, 4 742 %cmp = icmp eq i132 %sh, 2 743 ret i1 %cmp 744} 745 746define <2 x i1> @shr_exact_vec(<2 x i132> %x) { 747; CHECK-LABEL: @shr_exact_vec( 748; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], splat (i132 32) 749; CHECK-NEXT: ret <2 x i1> [[CMP]] 750; 751 %sh = lshr exact <2 x i132> %x, <i132 4, i132 4> 752 %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2> 753 ret <2 x i1> %cmp 754} 755 756; PR9343 #3 757define i1 @test41(i32 %X, i32 %Y) { 758; CHECK-LABEL: @test41( 759; CHECK-NEXT: ret i1 true 760; 761 %A = urem i32 %X, %Y 762 %B = icmp ugt i32 %Y, %A 763 ret i1 %B 764} 765 766define i1 @test42(i32 %X, i32 %Y) { 767; CHECK-LABEL: @test42( 768; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1 769; CHECK-NEXT: ret i1 [[B]] 770; 771 %A = srem i32 %X, %Y 772 %B = icmp slt i32 %A, %Y 773 ret i1 %B 774} 775 776define i1 @test43(i32 %X, i32 %Y) { 777; CHECK-LABEL: @test43( 778; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0 779; CHECK-NEXT: ret i1 [[B]] 780; 781 %A = srem i32 %X, %Y 782 %B = icmp slt i32 %Y, %A 783 ret i1 %B 784} 785 786define i1 @test44(i32 %X, i32 %Y) { 787; CHECK-LABEL: @test44( 788; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1 789; CHECK-NEXT: ret i1 [[B]] 790; 791 %A = srem i32 %X, %Y 792 %B = icmp slt i32 %A, %Y 793 ret i1 %B 794} 795 796define i1 @test45(i32 %X, i32 %Y) { 797; CHECK-LABEL: @test45( 798; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0 799; CHECK-NEXT: ret i1 [[B]] 800; 801 %A = srem i32 %X, %Y 802 %B = icmp slt i32 %Y, %A 803 ret i1 %B 804} 805 806; PR9343 #4 807define i1 @test46(i32 %X, i32 %Y, i32 %Z) { 808; CHECK-LABEL: @test46( 809; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 810; CHECK-NEXT: ret i1 [[C]] 811; 812 %A = ashr exact i32 %X, %Z 813 %B = ashr exact i32 %Y, %Z 814 %C = icmp ult i32 %A, %B 815 ret i1 %C 816} 817 818define i1 @test46_multiuse1(i32 %X, i32 %Y, i32 %Z) { 819; CHECK-LABEL: @test46_multiuse1( 820; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]] 821; CHECK-NEXT: call void @use_i32(i32 [[A]]) 822; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y:%.*]] 823; CHECK-NEXT: ret i1 [[C]] 824; 825 %A = ashr exact i32 %X, %Z 826 call void @use_i32(i32 %A) 827 %B = ashr exact i32 %Y, %Z 828 %C = icmp ult i32 %A, %B 829 ret i1 %C 830} 831 832define i1 @test46_multiuse2(i32 %X, i32 %Y, i32 %Z) { 833; CHECK-LABEL: @test46_multiuse2( 834; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z:%.*]] 835; CHECK-NEXT: call void @use_i32(i32 [[B]]) 836; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y]] 837; CHECK-NEXT: ret i1 [[C]] 838; 839 %A = ashr exact i32 %X, %Z 840 %B = ashr exact i32 %Y, %Z 841 call void @use_i32(i32 %B) 842 %C = icmp ult i32 %A, %B 843 ret i1 %C 844} 845 846define i1 @test46_multiuse3(i32 %X, i32 %Y, i32 %Z) { 847; CHECK-LABEL: @test46_multiuse3( 848; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]] 849; CHECK-NEXT: call void @use_i32(i32 [[A]]) 850; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z]] 851; CHECK-NEXT: call void @use_i32(i32 [[B]]) 852; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]] 853; CHECK-NEXT: ret i1 [[C]] 854; 855 %A = ashr exact i32 %X, %Z 856 call void @use_i32(i32 %A) 857 %B = ashr exact i32 %Y, %Z 858 call void @use_i32(i32 %B) 859 %C = icmp ult i32 %A, %B 860 ret i1 %C 861} 862 863; PR9343 #5 864define i1 @test47(i32 %X, i32 %Y, i32 %Z) { 865; CHECK-LABEL: @test47( 866; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 867; CHECK-NEXT: ret i1 [[C]] 868; 869 %A = ashr exact i32 %X, %Z 870 %B = ashr exact i32 %Y, %Z 871 %C = icmp ugt i32 %A, %B 872 ret i1 %C 873} 874 875; PR9343 #8 876define i1 @test48(i32 %X, i32 %Y, i32 %Z) { 877; CHECK-LABEL: @test48( 878; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 879; CHECK-NEXT: ret i1 [[C]] 880; 881 %A = sdiv exact i32 %X, %Z 882 %B = sdiv exact i32 %Y, %Z 883 %C = icmp eq i32 %A, %B 884 ret i1 %C 885} 886 887; The above transform only works for equality predicates. 888 889define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) { 890; CHECK-LABEL: @PR32949( 891; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]] 892; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]] 893; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]] 894; CHECK-NEXT: ret i1 [[C]] 895; 896 %A = sdiv exact i32 %X, %Z 897 %B = sdiv exact i32 %Y, %Z 898 %C = icmp sgt i32 %A, %B 899 ret i1 %C 900} 901 902define i1 @test_sdiv_pos_slt(i32 %x, i32 %y) { 903; CHECK-LABEL: @test_sdiv_pos_slt( 904; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 905; CHECK-NEXT: ret i1 [[CMP]] 906; 907 %divx = sdiv exact i32 %x, 40 908 %divy = sdiv exact i32 %y, 40 909 %cmp = icmp slt i32 %divx, %divy 910 ret i1 %cmp 911} 912 913define i1 @test_sdiv_pos_sle(i32 %x, i32 %y) { 914; CHECK-LABEL: @test_sdiv_pos_sle( 915; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]] 916; CHECK-NEXT: ret i1 [[CMP]] 917; 918 %divx = sdiv exact i32 %x, 40 919 %divy = sdiv exact i32 %y, 40 920 %cmp = icmp sle i32 %divx, %divy 921 ret i1 %cmp 922} 923 924define i1 @test_sdiv_pos_sgt(i32 %x, i32 %y) { 925; CHECK-LABEL: @test_sdiv_pos_sgt( 926; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 927; CHECK-NEXT: ret i1 [[CMP]] 928; 929 %divx = sdiv exact i32 %x, 40 930 %divy = sdiv exact i32 %y, 40 931 %cmp = icmp sgt i32 %divx, %divy 932 ret i1 %cmp 933} 934 935define i1 @test_sdiv_pos_sge(i32 %x, i32 %y) { 936; CHECK-LABEL: @test_sdiv_pos_sge( 937; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]] 938; CHECK-NEXT: ret i1 [[CMP]] 939; 940 %divx = sdiv exact i32 %x, 40 941 %divy = sdiv exact i32 %y, 40 942 %cmp = icmp sge i32 %divx, %divy 943 ret i1 %cmp 944} 945 946define i1 @test_sdiv_pos_ult(i32 %x, i32 %y) { 947; CHECK-LABEL: @test_sdiv_pos_ult( 948; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 949; CHECK-NEXT: ret i1 [[CMP]] 950; 951 %divx = sdiv exact i32 %x, 40 952 %divy = sdiv exact i32 %y, 40 953 %cmp = icmp ult i32 %divx, %divy 954 ret i1 %cmp 955} 956 957define i1 @test_sdiv_pos_ule(i32 %x, i32 %y) { 958; CHECK-LABEL: @test_sdiv_pos_ule( 959; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]] 960; CHECK-NEXT: ret i1 [[CMP]] 961; 962 %divx = sdiv exact i32 %x, 40 963 %divy = sdiv exact i32 %y, 40 964 %cmp = icmp ule i32 %divx, %divy 965 ret i1 %cmp 966} 967 968define i1 @test_sdiv_pos_ugt(i32 %x, i32 %y) { 969; CHECK-LABEL: @test_sdiv_pos_ugt( 970; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 971; CHECK-NEXT: ret i1 [[CMP]] 972; 973 %divx = sdiv exact i32 %x, 40 974 %divy = sdiv exact i32 %y, 40 975 %cmp = icmp ugt i32 %divx, %divy 976 ret i1 %cmp 977} 978 979define i1 @test_sdiv_pos_uge(i32 %x, i32 %y) { 980; CHECK-LABEL: @test_sdiv_pos_uge( 981; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 982; CHECK-NEXT: ret i1 [[CMP]] 983; 984 %divx = sdiv exact i32 %x, 40 985 %divy = sdiv exact i32 %y, 40 986 %cmp = icmp uge i32 %divx, %divy 987 ret i1 %cmp 988} 989 990define i1 @test_sdiv_neg_slt(i32 %x, i32 %y) { 991; CHECK-LABEL: @test_sdiv_neg_slt( 992; CHECK-NEXT: [[DIVX:%.*]] = sdiv exact i32 [[X:%.*]], -40 993; CHECK-NEXT: [[DIVY:%.*]] = sdiv exact i32 [[Y:%.*]], -40 994; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DIVX]], [[DIVY]] 995; CHECK-NEXT: ret i1 [[CMP]] 996; 997 %divx = sdiv exact i32 %x, -40 998 %divy = sdiv exact i32 %y, -40 999 %cmp = icmp slt i32 %divx, %divy 1000 ret i1 %cmp 1001} 1002 1003; PR8469 1004define <2 x i1> @test49(<2 x i32> %i3) { 1005; CHECK-LABEL: @test49( 1006; CHECK-NEXT: entry: 1007; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1008; 1009entry: 1010 %i11 = and <2 x i32> %i3, <i32 3, i32 3> 1011 %cmp = icmp ult <2 x i32> %i11, <i32 4, i32 4> 1012 ret <2 x i1> %cmp 1013} 1014 1015; PR9343 #7 1016define i1 @test50(i16 %X, i32 %Y) { 1017; CHECK-LABEL: @test50( 1018; CHECK-NEXT: ret i1 true 1019; 1020 %A = zext i16 %X to i32 1021 %B = srem i32 %A, %Y 1022 %C = icmp sgt i32 %B, -1 1023 ret i1 %C 1024} 1025 1026define i1 @test51(i32 %X, i32 %Y) { 1027; CHECK-LABEL: @test51( 1028; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], -2147483648 1029; CHECK-NEXT: [[B:%.*]] = srem i32 [[A]], [[Y:%.*]] 1030; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[B]], -1 1031; CHECK-NEXT: ret i1 [[C]] 1032; 1033 %A = and i32 %X, 2147483648 1034 %B = srem i32 %A, %Y 1035 %C = icmp sgt i32 %B, -1 1036 ret i1 %C 1037} 1038 1039define i1 @test52(i32 %x1) { 1040; CHECK-LABEL: @test52( 1041; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935 1042; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[TMP1]], 4980863 1043; CHECK-NEXT: ret i1 [[A]] 1044; 1045 %conv = and i32 %x1, 255 1046 %cmp = icmp eq i32 %conv, 127 1047 %i2 = lshr i32 %x1, 16 1048 %i3 = trunc i32 %i2 to i8 1049 %cmp15 = icmp eq i8 %i3, 76 1050 1051 %A = and i1 %cmp, %cmp15 1052 ret i1 %A 1053} 1054 1055define i1 @test52_logical(i32 %x1) { 1056; CHECK-LABEL: @test52_logical( 1057; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935 1058; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[TMP1]], 4980863 1059; CHECK-NEXT: ret i1 [[A]] 1060; 1061 %conv = and i32 %x1, 255 1062 %cmp = icmp eq i32 %conv, 127 1063 %i2 = lshr i32 %x1, 16 1064 %i3 = trunc i32 %i2 to i8 1065 %cmp15 = icmp eq i8 %i3, 76 1066 1067 %A = select i1 %cmp, i1 %cmp15, i1 false 1068 ret i1 %A 1069} 1070 1071define i1 @test52b(i128 %x1) { 1072; CHECK-LABEL: @test52b( 1073; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935 1074; CHECK-NEXT: [[A:%.*]] = icmp eq i128 [[TMP1]], 4980863 1075; CHECK-NEXT: ret i1 [[A]] 1076; 1077 %conv = and i128 %x1, 255 1078 %cmp = icmp eq i128 %conv, 127 1079 %i2 = lshr i128 %x1, 16 1080 %i3 = trunc i128 %i2 to i8 1081 %cmp15 = icmp eq i8 %i3, 76 1082 1083 %A = and i1 %cmp, %cmp15 1084 ret i1 %A 1085} 1086 1087define i1 @test52b_logical(i128 %x1) { 1088; CHECK-LABEL: @test52b_logical( 1089; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935 1090; CHECK-NEXT: [[A:%.*]] = icmp eq i128 [[TMP1]], 4980863 1091; CHECK-NEXT: ret i1 [[A]] 1092; 1093 %conv = and i128 %x1, 255 1094 %cmp = icmp eq i128 %conv, 127 1095 %i2 = lshr i128 %x1, 16 1096 %i3 = trunc i128 %i2 to i8 1097 %cmp15 = icmp eq i8 %i3, 76 1098 1099 %A = select i1 %cmp, i1 %cmp15, i1 false 1100 ret i1 %A 1101} 1102 1103; PR9838 1104define i1 @test53(i32 %a, i32 %b) { 1105; CHECK-LABEL: @test53( 1106; CHECK-NEXT: [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30 1107; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[B:%.*]], 30 1108; CHECK-NEXT: [[Z:%.*]] = icmp eq i32 [[X]], [[Y]] 1109; CHECK-NEXT: ret i1 [[Z]] 1110; 1111 %x = sdiv exact i32 %a, 30 1112 %y = sdiv i32 %b, 30 1113 %z = icmp eq i32 %x, %y 1114 ret i1 %z 1115} 1116 1117define i1 @test54(i8 %a) { 1118; CHECK-LABEL: @test54( 1119; CHECK-NEXT: [[RET:%.*]] = icmp slt i8 [[A:%.*]], -64 1120; CHECK-NEXT: ret i1 [[RET]] 1121; 1122 %ext = zext i8 %a to i32 1123 %and = and i32 %ext, 192 1124 %ret = icmp eq i32 %and, 128 1125 ret i1 %ret 1126} 1127 1128define i1 @test55(i32 %a) { 1129; CHECK-LABEL: @test55( 1130; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123 1131; CHECK-NEXT: ret i1 [[CMP]] 1132; 1133 %sub = sub i32 0, %a 1134 %cmp = icmp eq i32 %sub, 123 1135 ret i1 %cmp 1136} 1137 1138define <2 x i1> @test55vec(<2 x i32> %a) { 1139; CHECK-LABEL: @test55vec( 1140; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], splat (i32 -123) 1141; CHECK-NEXT: ret <2 x i1> [[CMP]] 1142; 1143 %sub = sub <2 x i32> zeroinitializer, %a 1144 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123> 1145 ret <2 x i1> %cmp 1146} 1147 1148define i1 @test56(i32 %a) { 1149; CHECK-LABEL: @test56( 1150; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113 1151; CHECK-NEXT: ret i1 [[CMP]] 1152; 1153 %sub = sub i32 10, %a 1154 %cmp = icmp eq i32 %sub, 123 1155 ret i1 %cmp 1156} 1157 1158define <2 x i1> @test56vec(<2 x i32> %a) { 1159; CHECK-LABEL: @test56vec( 1160; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], splat (i32 -113) 1161; CHECK-NEXT: ret <2 x i1> [[CMP]] 1162; 1163 %sub = sub <2 x i32> <i32 10, i32 10>, %a 1164 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123> 1165 ret <2 x i1> %cmp 1166} 1167 1168; PR10267 Don't make icmps more expensive when no other inst is subsumed. 1169define i1 @test57(i32 %a) { 1170; CHECK-LABEL: @test57( 1171; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2 1172; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 1173; CHECK-NEXT: call void @use_i32(i32 [[AND]]) 1174; CHECK-NEXT: ret i1 [[CMP]] 1175; 1176 %and = and i32 %a, -2 1177 %cmp = icmp ne i32 %and, 0 1178 call void @use_i32(i32 %and) 1179 ret i1 %cmp 1180} 1181 1182; rdar://problem/10482509 1183define zeroext i1 @cmpabs1(i64 %val) { 1184; CHECK-LABEL: @cmpabs1( 1185; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0 1186; CHECK-NEXT: ret i1 [[TOBOOL]] 1187; 1188 %sub = sub nsw i64 0, %val 1189 %cmp = icmp slt i64 %val, 0 1190 %sub.val = select i1 %cmp, i64 %sub, i64 %val 1191 %tobool = icmp ne i64 %sub.val, 0 1192 ret i1 %tobool 1193} 1194 1195define zeroext i1 @cmpabs2(i64 %val) { 1196; CHECK-LABEL: @cmpabs2( 1197; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0 1198; CHECK-NEXT: ret i1 [[TOBOOL]] 1199; 1200 %sub = sub nsw i64 0, %val 1201 %cmp = icmp slt i64 %val, 0 1202 %sub.val = select i1 %cmp, i64 %val, i64 %sub 1203 %tobool = icmp ne i64 %sub.val, 0 1204 ret i1 %tobool 1205} 1206 1207define i1 @abs_intrin_eq_zero(i8 %x) { 1208; CHECK-LABEL: @abs_intrin_eq_zero( 1209; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0 1210; CHECK-NEXT: ret i1 [[CMP]] 1211; 1212 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false) 1213 %cmp = icmp eq i8 %abs, 0 1214 ret i1 %cmp 1215} 1216 1217define i1 @abs_intrin_ne_zero(i8 %x) { 1218; CHECK-LABEL: @abs_intrin_ne_zero( 1219; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 0 1220; CHECK-NEXT: ret i1 [[CMP]] 1221; 1222 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false) 1223 %cmp = icmp ne i8 %abs, 0 1224 ret i1 %cmp 1225} 1226 1227define void @test58() { 1228; CHECK-LABEL: @test58( 1229; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592) 1230; CHECK-NEXT: ret void 1231; 1232 %cast = bitcast <1 x i64> <i64 36029346783166592> to i64 1233 %call = call i32 @test58_d( i64 %cast) 1234 ret void 1235} 1236declare i32 @test58_d(i64) 1237 1238; Negative test: GEP inbounds may cross sign boundary. 1239define i1 @test62(ptr %a) { 1240; CHECK-LABEL: @test62( 1241; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i64 1 1242; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 10 1243; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr [[ARRAYIDX1]], [[ARRAYIDX2]] 1244; CHECK-NEXT: ret i1 [[CMP]] 1245; 1246 %arrayidx1 = getelementptr inbounds i8, ptr %a, i64 1 1247 %arrayidx2 = getelementptr inbounds i8, ptr %a, i64 10 1248 %cmp = icmp slt ptr %arrayidx1, %arrayidx2 1249 ret i1 %cmp 1250} 1251 1252define i1 @test62_as1(ptr addrspace(1) %a) { 1253; CHECK-LABEL: @test62_as1( 1254; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A:%.*]], i16 1 1255; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A]], i16 10 1256; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr addrspace(1) [[ARRAYIDX1]], [[ARRAYIDX2]] 1257; CHECK-NEXT: ret i1 [[CMP]] 1258; 1259 %arrayidx1 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 1 1260 %arrayidx2 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 10 1261 %cmp = icmp slt ptr addrspace(1) %arrayidx1, %arrayidx2 1262 ret i1 %cmp 1263} 1264 1265define i1 @low_mask_eq_zext(i8 %a, i32 %b) { 1266; CHECK-LABEL: @low_mask_eq_zext( 1267; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 1268; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]] 1269; CHECK-NEXT: ret i1 [[C]] 1270; 1271 %z = zext i8 %a to i32 1272 %t = and i32 %b, 255 1273 %c = icmp eq i32 %z, %t 1274 ret i1 %c 1275} 1276 1277define i1 @low_mask_eq_zext_commute(i8 %a, i32 %b) { 1278; CHECK-LABEL: @low_mask_eq_zext_commute( 1279; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 1280; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]] 1281; CHECK-NEXT: ret i1 [[C]] 1282; 1283 %t = and i32 %b, 255 1284 %z = zext i8 %a to i32 1285 %c = icmp eq i32 %t, %z 1286 ret i1 %c 1287} 1288 1289; negative test 1290 1291define i1 @wrong_low_mask_eq_zext(i8 %a, i32 %b) { 1292; CHECK-LABEL: @wrong_low_mask_eq_zext( 1293; CHECK-NEXT: [[T:%.*]] = and i32 [[B:%.*]], 127 1294; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32 1295; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]] 1296; CHECK-NEXT: ret i1 [[C]] 1297; 1298 %t = and i32 %b, 127 1299 %z = zext i8 %a to i32 1300 %c = icmp eq i32 %t, %z 1301 ret i1 %c 1302} 1303 1304; negative test 1305 1306define i1 @wrong_low_mask_eq_zext2(i8 %a, i32 %b) { 1307; CHECK-LABEL: @wrong_low_mask_eq_zext2( 1308; CHECK-NEXT: [[T:%.*]] = and i32 [[B:%.*]], 254 1309; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32 1310; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]] 1311; CHECK-NEXT: ret i1 [[C]] 1312; 1313 %t = and i32 %b, 254 1314 %z = zext i8 %a to i32 1315 %c = icmp eq i32 %t, %z 1316 ret i1 %c 1317} 1318 1319define i1 @low_mask_eq_zext_use1(i8 %a, i32 %b) { 1320; CHECK-LABEL: @low_mask_eq_zext_use1( 1321; CHECK-NEXT: [[T:%.*]] = and i32 [[B:%.*]], 255 1322; CHECK-NEXT: call void @use_i32(i32 [[T]]) 1323; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B]] to i8 1324; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]] 1325; CHECK-NEXT: ret i1 [[C]] 1326; 1327 %t = and i32 %b, 255 1328 call void @use_i32(i32 %t) 1329 %z = zext i8 %a to i32 1330 %c = icmp eq i32 %t, %z 1331 ret i1 %c 1332} 1333 1334define i1 @low_mask_eq_zext_use2(i8 %a, i32 %b) { 1335; CHECK-LABEL: @low_mask_eq_zext_use2( 1336; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32 1337; CHECK-NEXT: call void @use_i32(i32 [[Z]]) 1338; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 1339; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], [[TMP1]] 1340; CHECK-NEXT: ret i1 [[C]] 1341; 1342 %t = and i32 %b, 255 1343 %z = zext i8 %a to i32 1344 call void @use_i32(i32 %z) 1345 %c = icmp eq i32 %t, %z 1346 ret i1 %c 1347} 1348 1349define i1 @low_mask_eq_zext_use3(i8 %a, i32 %b) { 1350; CHECK-LABEL: @low_mask_eq_zext_use3( 1351; CHECK-NEXT: [[T:%.*]] = and i32 [[B:%.*]], 255 1352; CHECK-NEXT: call void @use_i32(i32 [[T]]) 1353; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32 1354; CHECK-NEXT: call void @use_i32(i32 [[Z]]) 1355; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]] 1356; CHECK-NEXT: ret i1 [[C]] 1357; 1358 %t = and i32 %b, 255 1359 call void @use_i32(i32 %t) 1360 %z = zext i8 %a to i32 1361 call void @use_i32(i32 %z) 1362 %c = icmp eq i32 %t, %z 1363 ret i1 %c 1364} 1365 1366define <2 x i1> @low_mask_eq_zext_vec_splat(<2 x i8> %a, <2 x i32> %b) { 1367; CHECK-LABEL: @low_mask_eq_zext_vec_splat( 1368; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[B:%.*]] to <2 x i8> 1369; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], [[TMP1]] 1370; CHECK-NEXT: ret <2 x i1> [[C]] 1371; 1372 %t = and <2 x i32> %b, <i32 255, i32 255> 1373 %z = zext <2 x i8> %a to <2 x i32> 1374 %c = icmp eq <2 x i32> %t, %z 1375 ret <2 x i1> %c 1376} 1377 1378define i1 @test65(i64 %A, i64 %B) { 1379; CHECK-LABEL: @test65( 1380; CHECK-NEXT: ret i1 true 1381; 1382 %s1 = add i64 %A, %B 1383 %s2 = add i64 %A, %B 1384 %cmp = icmp eq i64 %s1, %s2 1385 ret i1 %cmp 1386} 1387 1388define i1 @test66(i64 %A, i64 %B) { 1389; CHECK-LABEL: @test66( 1390; CHECK-NEXT: ret i1 true 1391; 1392 %s1 = add i64 %A, %B 1393 %s2 = add i64 %B, %A 1394 %cmp = icmp eq i64 %s1, %s2 1395 ret i1 %cmp 1396} 1397 1398define i1 @test67(i32 %x) { 1399; CHECK-LABEL: @test67( 1400; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96 1401; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 1402; CHECK-NEXT: ret i1 [[CMP]] 1403; 1404 %and = and i32 %x, 127 1405 %cmp = icmp sgt i32 %and, 31 1406 ret i1 %cmp 1407} 1408 1409define i1 @test67inverse(i32 %x) { 1410; CHECK-LABEL: @test67inverse( 1411; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96 1412; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 1413; CHECK-NEXT: ret i1 [[CMP]] 1414; 1415 %and = and i32 %x, 127 1416 %cmp = icmp sle i32 %and, 31 1417 ret i1 %cmp 1418} 1419 1420; The test above relies on 3 different folds. 1421; This test only checks the last of those (icmp ugt -> icmp ne). 1422 1423define <2 x i1> @test67vec(<2 x i32> %x) { 1424; CHECK-LABEL: @test67vec( 1425; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96) 1426; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer 1427; CHECK-NEXT: ret <2 x i1> [[CMP]] 1428; 1429 %and = and <2 x i32> %x, <i32 96, i32 96> 1430 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31> 1431 ret <2 x i1> %cmp 1432} 1433 1434define <2 x i1> @test67vec2(<2 x i32> %x) { 1435; CHECK-LABEL: @test67vec2( 1436; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96) 1437; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer 1438; CHECK-NEXT: ret <2 x i1> [[CMP]] 1439; 1440 %and = and <2 x i32> %x, <i32 127, i32 127> 1441 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31> 1442 ret <2 x i1> %cmp 1443} 1444 1445define <2 x i1> @test67vecinverse(<2 x i32> %x) { 1446; CHECK-LABEL: @test67vecinverse( 1447; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96) 1448; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer 1449; CHECK-NEXT: ret <2 x i1> [[CMP]] 1450; 1451 %and = and <2 x i32> %x, <i32 96, i32 96> 1452 %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31> 1453 ret <2 x i1> %cmp 1454} 1455 1456define i1 @test68(i32 %x) { 1457; CHECK-LABEL: @test68( 1458; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 127 1459; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[AND]], 30 1460; CHECK-NEXT: ret i1 [[CMP]] 1461; 1462 %and = and i32 %x, 127 1463 %cmp = icmp sgt i32 %and, 30 1464 ret i1 %cmp 1465} 1466 1467; PR15940 1468define i1 @test70(i32 %X) { 1469; CHECK-LABEL: @test70( 1470; CHECK-NEXT: [[A:%.*]] = srem i32 5, [[X:%.*]] 1471; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A]], 2 1472; CHECK-NEXT: ret i1 [[C]] 1473; 1474 %A = srem i32 5, %X 1475 %B = add i32 %A, 2 1476 %C = icmp ne i32 %B, 4 1477 ret i1 %C 1478} 1479 1480define <2 x i1> @test70vec(<2 x i32> %X) { 1481; CHECK-LABEL: @test70vec( 1482; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 2) 1483; CHECK-NEXT: ret <2 x i1> [[C]] 1484; 1485 %B = add <2 x i32> %X, <i32 2, i32 2> 1486 %C = icmp ne <2 x i32> %B, <i32 4, i32 4> 1487 ret <2 x i1> %C 1488} 1489 1490define i1 @icmp_sext16trunc(i32 %x) { 1491; CHECK-LABEL: @icmp_sext16trunc( 1492; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16 1493; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36 1494; CHECK-NEXT: ret i1 [[CMP]] 1495; 1496 %trunc = trunc i32 %x to i16 1497 %sext = sext i16 %trunc to i32 1498 %cmp = icmp slt i32 %sext, 36 1499 ret i1 %cmp 1500} 1501 1502define i1 @icmp_sext8trunc(i32 %x) { 1503; CHECK-LABEL: @icmp_sext8trunc( 1504; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 1505; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36 1506; CHECK-NEXT: ret i1 [[CMP]] 1507; 1508 %trunc = trunc i32 %x to i8 1509 %sext = sext i8 %trunc to i32 1510 %cmp = icmp slt i32 %sext, 36 1511 ret i1 %cmp 1512} 1513 1514; Vectors should fold the same way. 1515define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) { 1516; CHECK-LABEL: @icmp_sext8trunc_vec( 1517; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8> 1518; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], splat (i8 36) 1519; CHECK-NEXT: ret <2 x i1> [[CMP]] 1520; 1521 %trunc = trunc <2 x i32> %x to <2 x i8> 1522 %sext = sext <2 x i8> %trunc to <2 x i32> 1523 %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36> 1524 ret <2 x i1> %cmp 1525} 1526 1527define i1 @icmp_shl16(i32 %x) { 1528; CHECK-LABEL: @icmp_shl16( 1529; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16 1530; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36 1531; CHECK-NEXT: ret i1 [[CMP]] 1532; 1533 %shl = shl i32 %x, 16 1534 %cmp = icmp slt i32 %shl, 2359296 1535 ret i1 %cmp 1536} 1537 1538; D25952: Don't create illegal types like i15 in InstCombine 1539 1540define i1 @icmp_shl17(i32 %x) { 1541; CHECK-LABEL: @icmp_shl17( 1542; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 17 1543; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296 1544; CHECK-NEXT: ret i1 [[CMP]] 1545; 1546 %shl = shl i32 %x, 17 1547 %cmp = icmp slt i32 %shl, 2359296 1548 ret i1 %cmp 1549} 1550 1551define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) { 1552; CHECK-LABEL: @icmp_shl16_vec( 1553; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16> 1554; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], splat (i16 36) 1555; CHECK-NEXT: ret <2 x i1> [[CMP]] 1556; 1557 %shl = shl <2 x i32> %x, <i32 16, i32 16> 1558 %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296> 1559 ret <2 x i1> %cmp 1560} 1561 1562define i1 @icmp_shl24(i32 %x) { 1563; CHECK-LABEL: @icmp_shl24( 1564; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 1565; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36 1566; CHECK-NEXT: ret i1 [[CMP]] 1567; 1568 %shl = shl i32 %x, 24 1569 %cmp = icmp slt i32 %shl, 603979776 1570 ret i1 %cmp 1571} 1572 1573define i1 @icmp_shl_eq(i32 %x) { 1574; CHECK-LABEL: @icmp_shl_eq( 1575; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727 1576; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0 1577; CHECK-NEXT: ret i1 [[CMP]] 1578; 1579 %mul = shl i32 %x, 5 1580 %cmp = icmp eq i32 %mul, 0 1581 ret i1 %cmp 1582} 1583 1584define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) { 1585; CHECK-LABEL: @icmp_shl_eq_vec( 1586; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 134217727) 1587; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer 1588; CHECK-NEXT: ret <2 x i1> [[CMP]] 1589; 1590 %mul = shl <2 x i32> %x, <i32 5, i32 5> 1591 %cmp = icmp eq <2 x i32> %mul, zeroinitializer 1592 ret <2 x i1> %cmp 1593} 1594 1595define i1 @icmp_shl_nsw_ne(i32 %x) { 1596; CHECK-LABEL: @icmp_shl_nsw_ne( 1597; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0 1598; CHECK-NEXT: ret i1 [[CMP]] 1599; 1600 %mul = shl nsw i32 %x, 7 1601 %cmp = icmp ne i32 %mul, 0 1602 ret i1 %cmp 1603} 1604 1605define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) { 1606; CHECK-LABEL: @icmp_shl_nsw_ne_vec( 1607; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 1608; CHECK-NEXT: ret <2 x i1> [[CMP]] 1609; 1610 %mul = shl nsw <2 x i32> %x, <i32 7, i32 7> 1611 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1612 ret <2 x i1> %cmp 1613} 1614 1615define i1 @icmp_shl_ne(i32 %x) { 1616; CHECK-LABEL: @icmp_shl_ne( 1617; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431 1618; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0 1619; CHECK-NEXT: ret i1 [[CMP]] 1620; 1621 %mul = shl i32 %x, 7 1622 %cmp = icmp ne i32 %mul, 0 1623 ret i1 %cmp 1624} 1625 1626define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) { 1627; CHECK-LABEL: @icmp_shl_ne_vec( 1628; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 33554431) 1629; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer 1630; CHECK-NEXT: ret <2 x i1> [[CMP]] 1631; 1632 %mul = shl <2 x i32> %x, <i32 7, i32 7> 1633 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1634 ret <2 x i1> %cmp 1635} 1636 1637define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) { 1638; CHECK-LABEL: @icmp_shl_nuw_ne_vec( 1639; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 2) 1640; CHECK-NEXT: ret <2 x i1> [[CMP]] 1641; 1642 %shl = shl nuw <2 x i32> %x, <i32 7, i32 7> 1643 %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256> 1644 ret <2 x i1> %cmp 1645} 1646 1647; If the (mul x, C) preserved the sign and this is sign test, 1648; compare the LHS operand instead 1649define i1 @icmp_mul_nsw(i32 %x) { 1650; CHECK-LABEL: @icmp_mul_nsw( 1651; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0 1652; CHECK-NEXT: ret i1 [[CMP]] 1653; 1654 %mul = mul nsw i32 %x, 12 1655 %cmp = icmp sgt i32 %mul, 0 1656 ret i1 %cmp 1657} 1658 1659define i1 @icmp_mul_nsw1(i32 %x) { 1660; CHECK-LABEL: @icmp_mul_nsw1( 1661; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 1662; CHECK-NEXT: ret i1 [[CMP]] 1663; 1664 %mul = mul nsw i32 %x, 12 1665 %cmp = icmp sle i32 %mul, -1 1666 ret i1 %cmp 1667} 1668 1669define i1 @icmp_mul_nsw_neg(i32 %x) { 1670; CHECK-LABEL: @icmp_mul_nsw_neg( 1671; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1 1672; CHECK-NEXT: ret i1 [[CMP]] 1673; 1674 %mul = mul nsw i32 %x, -12 1675 %cmp = icmp sge i32 %mul, 0 1676 ret i1 %cmp 1677} 1678 1679define i1 @icmp_mul_nsw_neg1(i32 %x) { 1680; CHECK-LABEL: @icmp_mul_nsw_neg1( 1681; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 1682; CHECK-NEXT: ret i1 [[CMP]] 1683; 1684 %mul = mul nsw i32 %x, -12 1685 %cmp = icmp sge i32 %mul, 1 1686 ret i1 %cmp 1687} 1688 1689define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) { 1690; CHECK-LABEL: @icmp_mul_nsw_neg1_vec( 1691; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer 1692; CHECK-NEXT: ret <2 x i1> [[CMP]] 1693; 1694 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12> 1695 %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1> 1696 ret <2 x i1> %cmp 1697} 1698 1699define i1 @icmp_mul_nsw_0(i32 %x) { 1700; CHECK-LABEL: @icmp_mul_nsw_0( 1701; CHECK-NEXT: ret i1 false 1702; 1703 %mul = mul nsw i32 %x, 0 1704 %cmp = icmp sgt i32 %mul, 0 1705 ret i1 %cmp 1706} 1707 1708define i1 @icmp_mul(i32 %x) { 1709; CHECK-LABEL: @icmp_mul( 1710; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X:%.*]], -12 1711; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1 1712; CHECK-NEXT: ret i1 [[CMP]] 1713; 1714 %mul = mul i32 %x, -12 1715 %cmp = icmp sge i32 %mul, 0 1716 ret i1 %cmp 1717} 1718 1719; Checks for icmp (eq|ne) (mul x, C), 0 1720define i1 @icmp_mul_neq0(i32 %x) { 1721; CHECK-LABEL: @icmp_mul_neq0( 1722; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0 1723; CHECK-NEXT: ret i1 [[CMP]] 1724; 1725 %mul = mul nsw i32 %x, -12 1726 %cmp = icmp ne i32 %mul, 0 1727 ret i1 %cmp 1728} 1729 1730define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) { 1731; CHECK-LABEL: @icmp_mul_neq0_vec( 1732; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer 1733; CHECK-NEXT: ret <2 x i1> [[CMP]] 1734; 1735 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12> 1736 %cmp = icmp ne <2 x i32> %mul, zeroinitializer 1737 ret <2 x i1> %cmp 1738} 1739 1740define i1 @icmp_mul_eq0(i32 %x) { 1741; CHECK-LABEL: @icmp_mul_eq0( 1742; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 1743; CHECK-NEXT: ret i1 [[CMP]] 1744; 1745 %mul = mul nsw i32 %x, 12 1746 %cmp = icmp eq i32 %mul, 0 1747 ret i1 %cmp 1748} 1749 1750define i1 @icmp_mul0_eq0(i32 %x) { 1751; CHECK-LABEL: @icmp_mul0_eq0( 1752; CHECK-NEXT: ret i1 true 1753; 1754 %mul = mul i32 %x, 0 1755 %cmp = icmp eq i32 %mul, 0 1756 ret i1 %cmp 1757} 1758 1759define i1 @icmp_mul0_ne0(i32 %x) { 1760; CHECK-LABEL: @icmp_mul0_ne0( 1761; CHECK-NEXT: ret i1 false 1762; 1763 %mul = mul i32 %x, 0 1764 %cmp = icmp ne i32 %mul, 0 1765 ret i1 %cmp 1766} 1767 1768define i1 @icmp_add20_eq_add57(i32 %x, i32 %y) { 1769; CHECK-LABEL: @icmp_add20_eq_add57( 1770; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 37 1771; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[TMP1]] 1772; CHECK-NEXT: ret i1 [[CMP]] 1773; 1774 %1 = add i32 %x, 20 1775 %2 = add i32 %y, 57 1776 %cmp = icmp eq i32 %1, %2 1777 ret i1 %cmp 1778} 1779 1780define <2 x i1> @icmp_add20_eq_add57_splat(<2 x i32> %x, <2 x i32> %y) { 1781; CHECK-LABEL: @icmp_add20_eq_add57_splat( 1782; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37) 1783; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]] 1784; CHECK-NEXT: ret <2 x i1> [[CMP]] 1785; 1786 %1 = add <2 x i32> %x, <i32 20, i32 20> 1787 %2 = add <2 x i32> %y, <i32 57, i32 57> 1788 %cmp = icmp eq <2 x i32> %1, %2 1789 ret <2 x i1> %cmp 1790} 1791 1792define <2 x i1> @icmp_add20_eq_add57_poison(<2 x i32> %x, <2 x i32> %y) { 1793; CHECK-LABEL: @icmp_add20_eq_add57_poison( 1794; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37) 1795; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]] 1796; CHECK-NEXT: ret <2 x i1> [[CMP]] 1797; 1798 %1 = add <2 x i32> %x, <i32 20, i32 20> 1799 %2 = add <2 x i32> %y, <i32 57, i32 poison> 1800 %cmp = icmp eq <2 x i32> %1, %2 1801 ret <2 x i1> %cmp 1802} 1803 1804define <2 x i1> @icmp_add20_eq_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) { 1805; CHECK-LABEL: @icmp_add20_eq_add57_vec_nonsplat( 1806; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], <i32 37, i32 39> 1807; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]] 1808; CHECK-NEXT: ret <2 x i1> [[CMP]] 1809; 1810 %1 = add <2 x i32> %x, <i32 20, i32 19> 1811 %2 = add <2 x i32> %y, <i32 57, i32 58> 1812 %cmp = icmp eq <2 x i32> %1, %2 1813 ret <2 x i1> %cmp 1814} 1815 1816define i1 @icmp_sub57_ne_sub20(i32 %x, i32 %y) { 1817; CHECK-LABEL: @icmp_sub57_ne_sub20( 1818; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -37 1819; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], [[Y:%.*]] 1820; CHECK-NEXT: ret i1 [[CMP]] 1821; 1822 %1 = add i32 %x, -57 1823 %2 = add i32 %y, -20 1824 %cmp = icmp ne i32 %1, %2 1825 ret i1 %cmp 1826} 1827 1828define <2 x i1> @icmp_sub57_ne_sub20_splat(<2 x i32> %x, <2 x i32> %y) { 1829; CHECK-LABEL: @icmp_sub57_ne_sub20_splat( 1830; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -37) 1831; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[Y:%.*]] 1832; CHECK-NEXT: ret <2 x i1> [[CMP]] 1833; 1834 %1 = add <2 x i32> %x, <i32 -57, i32 -57> 1835 %2 = add <2 x i32> %y, <i32 -20, i32 -20> 1836 %cmp = icmp ne <2 x i32> %1, %2 1837 ret <2 x i1> %cmp 1838} 1839 1840define <2 x i1> @icmp_sub57_ne_sub20_vec_poison(<2 x i32> %x, <2 x i32> %y) { 1841; CHECK-LABEL: @icmp_sub57_ne_sub20_vec_poison( 1842; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -37) 1843; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[Y:%.*]] 1844; CHECK-NEXT: ret <2 x i1> [[CMP]] 1845; 1846 %1 = add <2 x i32> %x, <i32 -57, i32 poison> 1847 %2 = add <2 x i32> %y, <i32 -20, i32 poison> 1848 %cmp = icmp ne <2 x i32> %1, %2 1849 ret <2 x i1> %cmp 1850} 1851 1852define <2 x i1> @icmp_sub57_ne_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) { 1853; CHECK-LABEL: @icmp_sub57_ne_sub20_vec_nonsplat( 1854; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37) 1855; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[TMP1]] 1856; CHECK-NEXT: ret <2 x i1> [[CMP]] 1857; 1858 %1 = add <2 x i32> %x, <i32 -57, i32 -58> 1859 %2 = add <2 x i32> %y, <i32 -20, i32 -21> 1860 %cmp = icmp ne <2 x i32> %1, %2 1861 ret <2 x i1> %cmp 1862} 1863 1864define i1 @icmp_sub1_sge(i32 %x, i32 %y) { 1865; CHECK-LABEL: @icmp_sub1_sge( 1866; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 1867; CHECK-NEXT: ret i1 [[CMP]] 1868; 1869 %sub = add nsw i32 %x, -1 1870 %cmp = icmp sge i32 %sub, %y 1871 ret i1 %cmp 1872} 1873 1874define i1 @icmp_add1_sgt(i32 %x, i32 %y) { 1875; CHECK-LABEL: @icmp_add1_sgt( 1876; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]] 1877; CHECK-NEXT: ret i1 [[CMP]] 1878; 1879 %add = add nsw i32 %x, 1 1880 %cmp = icmp sgt i32 %add, %y 1881 ret i1 %cmp 1882} 1883 1884define i1 @icmp_sub1_slt(i32 %x, i32 %y) { 1885; CHECK-LABEL: @icmp_sub1_slt( 1886; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]] 1887; CHECK-NEXT: ret i1 [[CMP]] 1888; 1889 %sub = add nsw i32 %x, -1 1890 %cmp = icmp slt i32 %sub, %y 1891 ret i1 %cmp 1892} 1893 1894define i1 @icmp_add1_sle(i32 %x, i32 %y) { 1895; CHECK-LABEL: @icmp_add1_sle( 1896; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 1897; CHECK-NEXT: ret i1 [[CMP]] 1898; 1899 %add = add nsw i32 %x, 1 1900 %cmp = icmp sle i32 %add, %y 1901 ret i1 %cmp 1902} 1903 1904define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) { 1905; CHECK-LABEL: @icmp_add20_sge_add57( 1906; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37 1907; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[TMP1]] 1908; CHECK-NEXT: ret i1 [[CMP]] 1909; 1910 %1 = add nsw i32 %x, 20 1911 %2 = add nsw i32 %y, 57 1912 %cmp = icmp sge i32 %1, %2 1913 ret i1 %cmp 1914} 1915 1916define <2 x i1> @icmp_add20_sge_add57_splat(<2 x i32> %x, <2 x i32> %y) { 1917; CHECK-LABEL: @icmp_add20_sge_add57_splat( 1918; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[Y:%.*]], splat (i32 37) 1919; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[X:%.*]], [[TMP1]] 1920; CHECK-NEXT: ret <2 x i1> [[CMP]] 1921; 1922 %1 = add nsw <2 x i32> %x, <i32 20, i32 20> 1923 %2 = add nsw <2 x i32> %y, <i32 57, i32 57> 1924 %cmp = icmp sge <2 x i32> %1, %2 1925 ret <2 x i1> %cmp 1926} 1927 1928define <2 x i1> @icmp_add20_sge_add57_poison(<2 x i32> %x, <2 x i32> %y) { 1929; CHECK-LABEL: @icmp_add20_sge_add57_poison( 1930; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[Y:%.*]], splat (i32 37) 1931; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[X:%.*]], [[TMP1]] 1932; CHECK-NEXT: ret <2 x i1> [[CMP]] 1933; 1934 %1 = add nsw <2 x i32> %x, <i32 20, i32 20> 1935 %2 = add nsw <2 x i32> %y, <i32 57, i32 poison> 1936 %cmp = icmp sge <2 x i32> %1, %2 1937 ret <2 x i1> %cmp 1938} 1939 1940define <2 x i1> @icmp_add20_sge_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) { 1941; CHECK-LABEL: @icmp_add20_sge_add57_vec_nonsplat( 1942; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], <i32 20, i32 19> 1943; CHECK-NEXT: [[TMP2:%.*]] = add nsw <2 x i32> [[Y:%.*]], <i32 57, i32 58> 1944; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[TMP2]] 1945; CHECK-NEXT: ret <2 x i1> [[CMP]] 1946; 1947 %1 = add nsw <2 x i32> %x, <i32 20, i32 19> 1948 %2 = add nsw <2 x i32> %y, <i32 57, i32 58> 1949 %cmp = icmp sge <2 x i32> %1, %2 1950 ret <2 x i1> %cmp 1951} 1952 1953define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) { 1954; CHECK-LABEL: @icmp_sub57_sge_sub20( 1955; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37 1956; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]] 1957; CHECK-NEXT: ret i1 [[CMP]] 1958; 1959 %1 = add nsw i32 %x, -57 1960 %2 = add nsw i32 %y, -20 1961 %cmp = icmp sge i32 %1, %2 1962 ret i1 %cmp 1963} 1964 1965define <2 x i1> @icmp_sub57_sge_sub20_splat(<2 x i32> %x, <2 x i32> %y) { 1966; CHECK-LABEL: @icmp_sub57_sge_sub20_splat( 1967; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], splat (i32 -37) 1968; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[Y:%.*]] 1969; CHECK-NEXT: ret <2 x i1> [[CMP]] 1970; 1971 %1 = add nsw <2 x i32> %x, <i32 -57, i32 -57> 1972 %2 = add nsw <2 x i32> %y, <i32 -20, i32 -20> 1973 %cmp = icmp sge <2 x i32> %1, %2 1974 ret <2 x i1> %cmp 1975} 1976 1977define <2 x i1> @icmp_sub57_sge_sub20_vec_poison(<2 x i32> %x, <2 x i32> %y) { 1978; CHECK-LABEL: @icmp_sub57_sge_sub20_vec_poison( 1979; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], splat (i32 -37) 1980; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[Y:%.*]] 1981; CHECK-NEXT: ret <2 x i1> [[CMP]] 1982; 1983 %1 = add nsw <2 x i32> %x, <i32 -57, i32 poison> 1984 %2 = add nsw <2 x i32> %y, <i32 -20, i32 poison> 1985 %cmp = icmp sge <2 x i32> %1, %2 1986 ret <2 x i1> %cmp 1987} 1988 1989define <2 x i1> @icmp_sub57_sge_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) { 1990; CHECK-LABEL: @icmp_sub57_sge_sub20_vec_nonsplat( 1991; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], <i32 -57, i32 -58> 1992; CHECK-NEXT: [[TMP2:%.*]] = add nsw <2 x i32> [[Y:%.*]], <i32 -20, i32 -21> 1993; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[TMP2]] 1994; CHECK-NEXT: ret <2 x i1> [[CMP]] 1995; 1996 %1 = add nsw <2 x i32> %x, <i32 -57, i32 -58> 1997 %2 = add nsw <2 x i32> %y, <i32 -20, i32 -21> 1998 %cmp = icmp sge <2 x i32> %1, %2 1999 ret <2 x i1> %cmp 2000} 2001 2002define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) { 2003; CHECK-LABEL: @icmp_and_shl_neg_ne_0( 2004; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]] 2005; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]] 2006; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 2007; CHECK-NEXT: ret i1 [[CMP]] 2008; 2009 %neg = xor i32 %A, -1 2010 %shl = shl i32 1, %B 2011 %and = and i32 %shl, %neg 2012 %cmp = icmp ne i32 %and, 0 2013 ret i1 %cmp 2014} 2015 2016define i1 @icmp_and_shl_neg_ne_0_shl2_no_flags(i32 %A, i32 %B) { 2017; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_no_flags( 2018; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[A:%.*]], -1 2019; CHECK-NEXT: [[SHL:%.*]] = shl i32 2, [[B:%.*]] 2020; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[NEG]] 2021; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 2022; CHECK-NEXT: ret i1 [[CMP]] 2023; 2024 %neg = xor i32 %A, -1 2025 %shl = shl i32 2, %B 2026 %and = and i32 %shl, %neg 2027 %cmp = icmp ne i32 %and, 0 2028 ret i1 %cmp 2029} 2030 2031define i1 @icmp_and_shl_neg_ne_0_shl2_nuw(i32 %A, i32 %B) { 2032; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_nuw( 2033; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 2, [[B:%.*]] 2034; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]] 2035; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 2036; CHECK-NEXT: ret i1 [[CMP]] 2037; 2038 %neg = xor i32 %A, -1 2039 %shl = shl nuw i32 2, %B 2040 %and = and i32 %shl, %neg 2041 %cmp = icmp ne i32 %and, 0 2042 ret i1 %cmp 2043} 2044 2045define i1 @icmp_and_shl_neg_ne_0_shl2_nsw(i32 %A, i32 %B) { 2046; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_nsw( 2047; CHECK-NEXT: [[SHL:%.*]] = shl nsw i32 2, [[B:%.*]] 2048; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]] 2049; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 2050; CHECK-NEXT: ret i1 [[CMP]] 2051; 2052 %neg = xor i32 %A, -1 2053 %shl = shl nsw i32 2, %B 2054 %and = and i32 %shl, %neg 2055 %cmp = icmp ne i32 %and, 0 2056 ret i1 %cmp 2057} 2058 2059define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) { 2060; CHECK-LABEL: @icmp_and_shl_neg_eq_0( 2061; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]] 2062; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]] 2063; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0 2064; CHECK-NEXT: ret i1 [[CMP]] 2065; 2066 %neg = xor i32 %A, -1 2067 %shl = shl i32 1, %B 2068 %and = and i32 %shl, %neg 2069 %cmp = icmp eq i32 %and, 0 2070 ret i1 %cmp 2071} 2072 2073define i1 @icmp_add_and_shr_ne_0(i32 %X) { 2074; CHECK-LABEL: @icmp_add_and_shr_ne_0( 2075; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 2076; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 2077; CHECK-NEXT: ret i1 [[TOBOOL]] 2078; 2079 %shr = lshr i32 %X, 4 2080 %and = and i32 %shr, 15 2081 %add = add i32 %and, -14 2082 %tobool = icmp ne i32 %add, 0 2083 ret i1 %tobool 2084} 2085 2086define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) { 2087; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec( 2088; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 240) 2089; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 224) 2090; CHECK-NEXT: ret <2 x i1> [[TOBOOL]] 2091; 2092 %shr = lshr <2 x i32> %X, <i32 4, i32 4> 2093 %and = and <2 x i32> %shr, <i32 15, i32 15> 2094 %add = add <2 x i32> %and, <i32 -14, i32 -14> 2095 %tobool = icmp ne <2 x i32> %add, zeroinitializer 2096 ret <2 x i1> %tobool 2097} 2098 2099; Variation of the above with an extra use of the shift 2100define i1 @icmp_and_shr_multiuse(i32 %X) { 2101; CHECK-LABEL: @icmp_and_shr_multiuse( 2102; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 2103; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 2104; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 2105; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 2106; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] 2107; CHECK-NEXT: ret i1 [[AND3]] 2108; 2109 %shr = lshr i32 %X, 4 2110 %and = and i32 %shr, 15 2111 %and2 = and i32 %shr, 31 ; second use of the shift 2112 %tobool = icmp ne i32 %and, 14 2113 %tobool2 = icmp ne i32 %and2, 27 2114 %and3 = and i1 %tobool, %tobool2 2115 ret i1 %and3 2116} 2117 2118define i1 @icmp_and_shr_multiuse_logical(i32 %X) { 2119; CHECK-LABEL: @icmp_and_shr_multiuse_logical( 2120; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 2121; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 2122; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 2123; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 2124; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] 2125; CHECK-NEXT: ret i1 [[AND3]] 2126; 2127 %shr = lshr i32 %X, 4 2128 %and = and i32 %shr, 15 2129 %and2 = and i32 %shr, 31 ; second use of the shift 2130 %tobool = icmp ne i32 %and, 14 2131 %tobool2 = icmp ne i32 %and2, 27 2132 %and3 = select i1 %tobool, i1 %tobool2, i1 false 2133 ret i1 %and3 2134} 2135 2136; Variation of the above with an ashr 2137define i1 @icmp_and_ashr_multiuse(i32 %X) { 2138; CHECK-LABEL: @icmp_and_ashr_multiuse( 2139; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 2140; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 2141; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 2142; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 2143; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] 2144; CHECK-NEXT: ret i1 [[AND3]] 2145; 2146 %shr = ashr i32 %X, 4 2147 %and = and i32 %shr, 15 2148 %and2 = and i32 %shr, 31 ; second use of the shift 2149 %tobool = icmp ne i32 %and, 14 2150 %tobool2 = icmp ne i32 %and2, 27 2151 %and3 = and i1 %tobool, %tobool2 2152 ret i1 %and3 2153} 2154 2155define i1 @icmp_and_ashr_multiuse_logical(i32 %X) { 2156; CHECK-LABEL: @icmp_and_ashr_multiuse_logical( 2157; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 2158; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 2159; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 2160; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 2161; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] 2162; CHECK-NEXT: ret i1 [[AND3]] 2163; 2164 %shr = ashr i32 %X, 4 2165 %and = and i32 %shr, 15 2166 %and2 = and i32 %shr, 31 ; second use of the shift 2167 %tobool = icmp ne i32 %and, 14 2168 %tobool2 = icmp ne i32 %and2, 27 2169 %and3 = select i1 %tobool, i1 %tobool2, i1 false 2170 ret i1 %and3 2171} 2172 2173define i1 @icmp_lshr_and_overshift(i8 %X) { 2174; CHECK-LABEL: @icmp_lshr_and_overshift( 2175; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31 2176; CHECK-NEXT: ret i1 [[TOBOOL]] 2177; 2178 %shr = lshr i8 %X, 5 2179 %and = and i8 %shr, 15 2180 %tobool = icmp ne i8 %and, 0 2181 ret i1 %tobool 2182} 2183 2184; We shouldn't simplify this because the and uses bits that are shifted in. 2185define i1 @icmp_ashr_and_overshift(i8 %X) { 2186; CHECK-LABEL: @icmp_ashr_and_overshift( 2187; CHECK-NEXT: [[SHR:%.*]] = ashr i8 [[X:%.*]], 5 2188; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHR]], 15 2189; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0 2190; CHECK-NEXT: ret i1 [[TOBOOL]] 2191; 2192 %shr = ashr i8 %X, 5 2193 %and = and i8 %shr, 15 2194 %tobool = icmp ne i8 %and, 0 2195 ret i1 %tobool 2196} 2197 2198define i1 @icmp_and_ashr_neg_and_legal(i8 %x) { 2199; CHECK-LABEL: @icmp_and_ashr_neg_and_legal( 2200; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 32 2201; CHECK-NEXT: ret i1 [[CMP]] 2202; 2203 %ashr = ashr i8 %x, 4 2204 %and = and i8 %ashr, -2 2205 %cmp = icmp slt i8 %and, 1 2206 ret i1 %cmp 2207} 2208 2209; Negative test. 2210define i1 @icmp_and_ashr_mixed_and_shiftout(i8 %x) { 2211; CHECK-LABEL: @icmp_and_ashr_mixed_and_shiftout( 2212; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4 2213; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], 31 2214; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i8 [[AND]], 8 2215; CHECK-NEXT: ret i1 [[CMP]] 2216; 2217 %ashr = ashr i8 %x, 4 2218 %and = and i8 %ashr, 31 2219 %cmp = icmp ugt i8 %and, 8 2220 ret i1 %cmp 2221} 2222 2223define i1 @icmp_and_ashr_neg_cmp_slt_legal(i8 %x) { 2224; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_legal( 2225; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 2226; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], -64 2227; CHECK-NEXT: ret i1 [[CMP]] 2228; 2229 %ashr = ashr i8 %x, 4 2230 %and = and i8 %ashr, -2 2231 %cmp = icmp slt i8 %and, -4 2232 ret i1 %cmp 2233} 2234 2235; Negative test. 2236define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(i8 %x) { 2237; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_shiftout( 2238; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4 2239; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], -2 2240; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[AND]], -68 2241; CHECK-NEXT: ret i1 [[CMP]] 2242; 2243 %ashr = ashr i8 %x, 4 2244 %and = and i8 %ashr, -2 2245 %cmp = icmp slt i8 %and, -68 2246 ret i1 %cmp 2247} 2248 2249define i1 @icmp_and_ashr_neg_cmp_eq_legal(i8 %x) { 2250; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_legal( 2251; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 2252; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], -64 2253; CHECK-NEXT: ret i1 [[CMP]] 2254; 2255 %ashr = ashr i8 %x, 4 2256 %and = and i8 %ashr, -2 2257 %cmp = icmp eq i8 %and, -4 2258 ret i1 %cmp 2259} 2260 2261define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(i8 %x) { 2262; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_shiftout( 2263; CHECK-NEXT: ret i1 false 2264; 2265 %ashr = ashr i8 %x, 4 2266 %and = and i8 %ashr, -2 2267 %cmp = icmp eq i8 %and, -68 2268 ret i1 %cmp 2269} 2270 2271define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(i8 %x) { 2272; CHECK-LABEL: @icmp_and_ashr_neg_cmp_ne_shiftout( 2273; CHECK-NEXT: ret i1 true 2274; 2275 %ashr = ashr i8 %x, 4 2276 %and = and i8 %ashr, -2 2277 %cmp = icmp ne i8 %and, -68 2278 ret i1 %cmp 2279} 2280 2281define i1 @icmp_shl_1_V_ult_32(i32 %V) { 2282; CHECK-LABEL: @icmp_shl_1_V_ult_32( 2283; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 2284; CHECK-NEXT: ret i1 [[CMP]] 2285; 2286 %shl = shl i32 1, %V 2287 %cmp = icmp ult i32 %shl, 32 2288 ret i1 %cmp 2289} 2290 2291define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) { 2292; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec( 2293; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5) 2294; CHECK-NEXT: ret <2 x i1> [[CMP]] 2295; 2296 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2297 %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32> 2298 ret <2 x i1> %cmp 2299} 2300 2301define i1 @icmp_shl_1_V_eq_32(i32 %V) { 2302; CHECK-LABEL: @icmp_shl_1_V_eq_32( 2303; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5 2304; CHECK-NEXT: ret i1 [[CMP]] 2305; 2306 %shl = shl i32 1, %V 2307 %cmp = icmp eq i32 %shl, 32 2308 ret i1 %cmp 2309} 2310 2311define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) { 2312; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec( 2313; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 5) 2314; CHECK-NEXT: ret <2 x i1> [[CMP]] 2315; 2316 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2317 %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32> 2318 ret <2 x i1> %cmp 2319} 2320 2321define i1 @icmp_shl_1_V_ult_30(i32 %V) { 2322; CHECK-LABEL: @icmp_shl_1_V_ult_30( 2323; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 2324; CHECK-NEXT: ret i1 [[CMP]] 2325; 2326 %shl = shl i32 1, %V 2327 %cmp = icmp ult i32 %shl, 30 2328 ret i1 %cmp 2329} 2330 2331define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) { 2332; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec( 2333; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5) 2334; CHECK-NEXT: ret <2 x i1> [[CMP]] 2335; 2336 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2337 %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30> 2338 ret <2 x i1> %cmp 2339} 2340 2341define i1 @icmp_shl_1_V_ugt_30(i32 %V) { 2342; CHECK-LABEL: @icmp_shl_1_V_ugt_30( 2343; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4 2344; CHECK-NEXT: ret i1 [[CMP]] 2345; 2346 %shl = shl i32 1, %V 2347 %cmp = icmp ugt i32 %shl, 30 2348 ret i1 %cmp 2349} 2350 2351define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) { 2352; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec( 2353; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], splat (i32 4) 2354; CHECK-NEXT: ret <2 x i1> [[CMP]] 2355; 2356 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2357 %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30> 2358 ret <2 x i1> %cmp 2359} 2360 2361define i1 @icmp_shl_1_V_ule_30(i32 %V) { 2362; CHECK-LABEL: @icmp_shl_1_V_ule_30( 2363; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5 2364; CHECK-NEXT: ret i1 [[CMP]] 2365; 2366 %shl = shl i32 1, %V 2367 %cmp = icmp ule i32 %shl, 30 2368 ret i1 %cmp 2369} 2370 2371define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) { 2372; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec( 2373; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5) 2374; CHECK-NEXT: ret <2 x i1> [[CMP]] 2375; 2376 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2377 %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30> 2378 ret <2 x i1> %cmp 2379} 2380 2381define i1 @icmp_shl_1_V_uge_30(i32 %V) { 2382; CHECK-LABEL: @icmp_shl_1_V_uge_30( 2383; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4 2384; CHECK-NEXT: ret i1 [[CMP]] 2385; 2386 %shl = shl i32 1, %V 2387 %cmp = icmp uge i32 %shl, 30 2388 ret i1 %cmp 2389} 2390 2391define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) { 2392; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec( 2393; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], splat (i32 4) 2394; CHECK-NEXT: ret <2 x i1> [[CMP]] 2395; 2396 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2397 %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30> 2398 ret <2 x i1> %cmp 2399} 2400 2401define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) { 2402; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648( 2403; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31 2404; CHECK-NEXT: ret i1 [[CMP]] 2405; 2406 %shl = shl i32 1, %V 2407 %cmp = icmp uge i32 %shl, 2147483648 2408 ret i1 %cmp 2409} 2410 2411define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) { 2412; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec( 2413; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31) 2414; CHECK-NEXT: ret <2 x i1> [[CMP]] 2415; 2416 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2417 %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648> 2418 ret <2 x i1> %cmp 2419} 2420 2421define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) { 2422; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648( 2423; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31 2424; CHECK-NEXT: ret i1 [[CMP]] 2425; 2426 %shl = shl i32 1, %V 2427 %cmp = icmp ult i32 %shl, 2147483648 2428 ret i1 %cmp 2429} 2430 2431define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) { 2432; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec( 2433; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31) 2434; CHECK-NEXT: ret <2 x i1> [[CMP]] 2435; 2436 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2437 %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648> 2438 ret <2 x i1> %cmp 2439} 2440 2441define i1 @icmp_shl_1_V_sle_0(i32 %V) { 2442; CHECK-LABEL: @icmp_shl_1_V_sle_0( 2443; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31 2444; CHECK-NEXT: ret i1 [[CMP]] 2445; 2446 %shl = shl i32 1, %V 2447 %cmp = icmp sle i32 %shl, 0 2448 ret i1 %cmp 2449} 2450 2451define <2 x i1> @icmp_shl_1_V_sle_0_vec(<2 x i32> %V) { 2452; CHECK-LABEL: @icmp_shl_1_V_sle_0_vec( 2453; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31) 2454; CHECK-NEXT: ret <2 x i1> [[CMP]] 2455; 2456 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2457 %cmp = icmp sle <2 x i32> %shl, <i32 0, i32 0> 2458 ret <2 x i1> %cmp 2459} 2460 2461define i1 @icmp_shl_1_V_sle_negative(i32 %V) { 2462; CHECK-LABEL: @icmp_shl_1_V_sle_negative( 2463; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31 2464; CHECK-NEXT: ret i1 [[CMP]] 2465; 2466 %shl = shl i32 1, %V 2467 %cmp = icmp sle i32 %shl, -42 2468 ret i1 %cmp 2469} 2470 2471define <2 x i1> @icmp_shl_1_V_sle_0_negative(<2 x i32> %V) { 2472; CHECK-LABEL: @icmp_shl_1_V_sle_0_negative( 2473; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31) 2474; CHECK-NEXT: ret <2 x i1> [[CMP]] 2475; 2476 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2477 %cmp = icmp sle <2 x i32> %shl, <i32 -2147483647, i32 -2147483647> 2478 ret <2 x i1> %cmp 2479} 2480 2481define i1 @icmp_shl_1_V_sgt_0(i32 %V) { 2482; CHECK-LABEL: @icmp_shl_1_V_sgt_0( 2483; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31 2484; CHECK-NEXT: ret i1 [[CMP]] 2485; 2486 %shl = shl i32 1, %V 2487 %cmp = icmp sgt i32 %shl, 0 2488 ret i1 %cmp 2489} 2490 2491define <2 x i1> @icmp_shl_1_V_sgt_0_vec(<2 x i32> %V) { 2492; CHECK-LABEL: @icmp_shl_1_V_sgt_0_vec( 2493; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31) 2494; CHECK-NEXT: ret <2 x i1> [[CMP]] 2495; 2496 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2497 %cmp = icmp sgt <2 x i32> %shl, <i32 0, i32 0> 2498 ret <2 x i1> %cmp 2499} 2500 2501define i1 @icmp_shl_1_V_sgt_negative(i32 %V) { 2502; CHECK-LABEL: @icmp_shl_1_V_sgt_negative( 2503; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31 2504; CHECK-NEXT: ret i1 [[CMP]] 2505; 2506 %shl = shl i32 1, %V 2507 %cmp = icmp sgt i32 %shl, -12345 2508 ret i1 %cmp 2509} 2510 2511define <2 x i1> @icmp_shl_1_V_sgt_negative_vec(<2 x i32> %V) { 2512; CHECK-LABEL: @icmp_shl_1_V_sgt_negative_vec( 2513; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31) 2514; CHECK-NEXT: ret <2 x i1> [[CMP]] 2515; 2516 %shl = shl <2 x i32> <i32 1, i32 1>, %V 2517 %cmp = icmp sgt <2 x i32> %shl, <i32 -2, i32 -2> 2518 ret <2 x i1> %cmp 2519} 2520 2521define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) { 2522; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B( 2523; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1 2524; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]] 2525; CHECK-NEXT: ret i1 [[TMP2]] 2526; 2527 %1 = icmp eq i64 %b, 0 2528 %2 = icmp ult i64 %a, %b 2529 %3 = or i1 %1, %2 2530 ret i1 %3 2531} 2532 2533define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) { 2534; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_logical( 2535; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]] 2536; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1 2537; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i64 [[TMP2]], [[TMP1]] 2538; CHECK-NEXT: ret i1 [[TMP3]] 2539; 2540 %1 = icmp eq i64 %b, 0 2541 %2 = icmp ult i64 %a, %b 2542 %3 = select i1 %1, i1 true, i1 %2 2543 ret i1 %3 2544} 2545 2546define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) { 2547; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform( 2548; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1) 2549; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]] 2550; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2551; 2552 %1 = icmp eq <2 x i64> %b, zeroinitializer 2553 %2 = icmp ult <2 x i64> %a, %b 2554 %3 = or <2 x i1> %1, %2 2555 ret <2 x i1> %3 2556} 2557 2558define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_poison(<2 x i64> %a, <2 x i64> %b) { 2559; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_poison( 2560; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1) 2561; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]] 2562; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2563; 2564 %1 = icmp eq <2 x i64> %b, <i64 0, i64 poison> 2565 %2 = icmp ult <2 x i64> %a, %b 2566 %3 = or <2 x i1> %1, %2 2567 ret <2 x i1> %3 2568} 2569 2570define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) { 2571; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0( 2572; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]] 2573; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0 2574; CHECK-NEXT: ret i1 [[TMP2]] 2575; 2576 %1 = icmp ne i64 %a, 0 2577 %2 = icmp ne i64 %b, 0 2578 %3 = or i1 %1, %2 2579 ret i1 %3 2580} 2581 2582define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) { 2583; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_logical( 2584; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[A:%.*]], 0 2585; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[B:%.*]], 0 2586; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]] 2587; CHECK-NEXT: ret i1 [[TMP3]] 2588; 2589 %1 = icmp ne i64 %a, 0 2590 %2 = icmp ne i64 %b, 0 2591 %3 = select i1 %1, i1 true, i1 %2 2592 ret i1 %3 2593} 2594 2595define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) { 2596; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform( 2597; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]] 2598; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer 2599; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2600; 2601 %1 = icmp ne <2 x i64> %a, zeroinitializer 2602 %2 = icmp ne <2 x i64> %b, zeroinitializer 2603 %3 = or <2 x i1> %1, %2 2604 ret <2 x i1> %3 2605} 2606 2607define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_poison(<2 x i64> %a, <2 x i64> %b) { 2608; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_poison( 2609; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]] 2610; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer 2611; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2612; 2613 %1 = icmp ne <2 x i64> %a, <i64 0, i64 poison> 2614 %2 = icmp ne <2 x i64> %b, <i64 0, i64 poison> 2615 %3 = or <2 x i1> %1, %2 2616 ret <2 x i1> %3 2617} 2618 2619define i1 @and_icmp_ne_B_0_icmp_uge_A_B(i64 %a, i64 %b) { 2620; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B( 2621; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1 2622; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]] 2623; CHECK-NEXT: ret i1 [[TMP2]] 2624; 2625 %1 = icmp ne i64 %b, 0 2626 %2 = icmp uge i64 %a, %b 2627 %3 = and i1 %1, %2 2628 ret i1 %3 2629} 2630 2631define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1(i64 %a, i64 %b) { 2632; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted1( 2633; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1 2634; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]] 2635; CHECK-NEXT: ret i1 [[TMP2]] 2636; 2637 %1 = icmp uge i64 %a, %b 2638 %2 = icmp ne i64 %b, 0 2639 %3 = and i1 %1, %2 2640 ret i1 %3 2641} 2642 2643define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2(i64 %a, i64 %b) { 2644; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted2( 2645; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1 2646; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]] 2647; CHECK-NEXT: ret i1 [[TMP2]] 2648; 2649 %1 = icmp ne i64 %b, 0 2650 %2 = icmp ule i64 %b, %a 2651 %3 = and i1 %1, %2 2652 ret i1 %3 2653} 2654 2655define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical(i64 %a, i64 %b) { 2656; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical( 2657; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1 2658; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]] 2659; CHECK-NEXT: ret i1 [[TMP2]] 2660; 2661 %1 = icmp uge i64 %a, %b 2662 %2 = icmp ne i64 %b, 0 2663 %3 = select i1 %1, i1 %2, i1 false 2664 ret i1 %3 2665} 2666 2667define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(i64 %a, i64 %b) { 2668; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical( 2669; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]] 2670; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1 2671; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]] 2672; CHECK-NEXT: ret i1 [[TMP3]] 2673; 2674 %1 = icmp ne i64 %b, 0 2675 %2 = icmp ule i64 %b, %a 2676 %3 = select i1 %1, i1 %2, i1 false 2677 ret i1 %3 2678} 2679 2680define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use1(i64 %a, i64 %b) { 2681; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use1( 2682; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0 2683; CHECK-NEXT: call void @use_i1(i1 [[TMP1]]) 2684; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -1 2685; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[A:%.*]] 2686; CHECK-NEXT: ret i1 [[TMP3]] 2687; 2688 %1 = icmp ne i64 %b, 0 2689 call void @use_i1(i1 %1) 2690 %2 = icmp uge i64 %a, %b 2691 %3 = and i1 %1, %2 2692 ret i1 %3 2693} 2694 2695define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use2(i64 %a, i64 %b) { 2696; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use2( 2697; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i64 [[A:%.*]], [[B:%.*]] 2698; CHECK-NEXT: call void @use_i1(i1 [[TMP1]]) 2699; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -1 2700; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[A]] 2701; CHECK-NEXT: ret i1 [[TMP3]] 2702; 2703 %1 = icmp ne i64 %b, 0 2704 %2 = icmp uge i64 %a, %b 2705 call void @use_i1(i1 %2) 2706 %3 = and i1 %1, %2 2707 ret i1 %3 2708} 2709 2710define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use3(i64 %a, i64 %b) { 2711; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use3( 2712; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0 2713; CHECK-NEXT: call void @use_i1(i1 [[TMP1]]) 2714; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]] 2715; CHECK-NEXT: call void @use_i1(i1 [[TMP2]]) 2716; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 2717; CHECK-NEXT: ret i1 [[TMP3]] 2718; 2719 %1 = icmp ne i64 %b, 0 2720 call void @use_i1(i1 %1) 2721 %2 = icmp uge i64 %a, %b 2722 call void @use_i1(i1 %2) 2723 %3 = and i1 %1, %2 2724 ret i1 %3 2725} 2726 2727define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred1(i64 %a, i64 %b) { 2728; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred1( 2729; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[B:%.*]], 0 2730; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]] 2731; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 2732; CHECK-NEXT: ret i1 [[TMP3]] 2733; 2734 %1 = icmp sgt i64 %b, 0 2735 %2 = icmp uge i64 %a, %b 2736 %3 = and i1 %1, %2 2737 ret i1 %3 2738} 2739 2740define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred2(i64 %a, i64 %b) { 2741; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred2( 2742; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0 2743; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[A:%.*]], [[B]] 2744; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 2745; CHECK-NEXT: ret i1 [[TMP3]] 2746; 2747 %1 = icmp ne i64 %b, 0 2748 %2 = icmp ugt i64 %a, %b 2749 %3 = and i1 %1, %2 2750 ret i1 %3 2751} 2752 2753define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op1(i64 %a, i64 %b) { 2754; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op1( 2755; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 1 2756; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]] 2757; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 2758; CHECK-NEXT: ret i1 [[TMP3]] 2759; 2760 %1 = icmp ne i64 %b, 1 2761 %2 = icmp uge i64 %a, %b 2762 %3 = and i1 %1, %2 2763 ret i1 %3 2764} 2765 2766define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2(i64 %a, i64 %b, i64 %c) { 2767; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2( 2768; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0 2769; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[C:%.*]] 2770; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 2771; CHECK-NEXT: ret i1 [[TMP3]] 2772; 2773 %1 = icmp ne i64 %b, 0 2774 %2 = icmp uge i64 %a, %c 2775 %3 = and i1 %1, %2 2776 ret i1 %3 2777} 2778 2779define i1 @and_icmp_ne_B_0_icmp_uge_A_B_logical(i64 %a, i64 %b) { 2780; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_logical( 2781; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]] 2782; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1 2783; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]] 2784; CHECK-NEXT: ret i1 [[TMP3]] 2785; 2786 %1 = icmp ne i64 %b, 0 2787 %2 = icmp uge i64 %a, %b 2788 %3 = select i1 %1, i1 %2, i1 false 2789 ret i1 %3 2790} 2791 2792define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_uniform(<2 x i64> %a, <2 x i64> %b) { 2793; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_uniform( 2794; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1) 2795; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], [[A:%.*]] 2796; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2797; 2798 %1 = icmp ne <2 x i64> %b, zeroinitializer 2799 %2 = icmp uge <2 x i64> %a, %b 2800 %3 = and <2 x i1> %1, %2 2801 ret <2 x i1> %3 2802} 2803 2804define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_poison(<2 x i64> %a, <2 x i64> %b) { 2805; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_poison( 2806; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1) 2807; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], [[A:%.*]] 2808; CHECK-NEXT: ret <2 x i1> [[TMP2]] 2809; 2810 %1 = icmp ne <2 x i64> %b, <i64 0, i64 poison> 2811 %2 = icmp uge <2 x i64> %a, %b 2812 %3 = and <2 x i1> %1, %2 2813 ret <2 x i1> %3 2814} 2815 2816define i1 @icmp_add_ult_2(i32 %X) { 2817; CHECK-LABEL: @icmp_add_ult_2( 2818; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2819; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14 2820; CHECK-NEXT: ret i1 [[CMP]] 2821; 2822 %add = add i32 %X, -14 2823 %cmp = icmp ult i32 %add, 2 2824 ret i1 %cmp 2825} 2826 2827define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) { 2828; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec( 2829; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2) 2830; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 14) 2831; CHECK-NEXT: ret <2 x i1> [[CMP]] 2832; 2833 %add = add <2 x i32> %X, <i32 -14, i32 -14> 2834 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2> 2835 ret <2 x i1> %cmp 2836} 2837 2838define i1 @icmp_sub_3_X_ult_2(i32 %X) { 2839; CHECK-LABEL: @icmp_sub_3_X_ult_2( 2840; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2841; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 2 2842; CHECK-NEXT: ret i1 [[CMP]] 2843; 2844 %add = sub i32 3, %X 2845 %cmp = icmp ult i32 %add, 2 2846 ret i1 %cmp 2847} 2848 2849define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) { 2850; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec( 2851; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2) 2852; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 2) 2853; CHECK-NEXT: ret <2 x i1> [[CMP]] 2854; 2855 %add = sub <2 x i32> <i32 3, i32 3>, %X 2856 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2> 2857 ret <2 x i1> %cmp 2858} 2859 2860define i1 @icmp_add_X_-14_uge_2(i32 %X) { 2861; CHECK-LABEL: @icmp_add_X_-14_uge_2( 2862; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2863; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14 2864; CHECK-NEXT: ret i1 [[CMP]] 2865; 2866 %add = add i32 %X, -14 2867 %cmp = icmp uge i32 %add, 2 2868 ret i1 %cmp 2869} 2870 2871define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) { 2872; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec( 2873; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2) 2874; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 14) 2875; CHECK-NEXT: ret <2 x i1> [[CMP]] 2876; 2877 %add = add <2 x i32> %X, <i32 -14, i32 -14> 2878 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2> 2879 ret <2 x i1> %cmp 2880} 2881 2882define i1 @icmp_sub_3_X_uge_2(i32 %X) { 2883; CHECK-LABEL: @icmp_sub_3_X_uge_2( 2884; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 2885; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 2 2886; CHECK-NEXT: ret i1 [[CMP]] 2887; 2888 %add = sub i32 3, %X 2889 %cmp = icmp uge i32 %add, 2 2890 ret i1 %cmp 2891} 2892 2893define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) { 2894; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec( 2895; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2) 2896; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 2) 2897; CHECK-NEXT: ret <2 x i1> [[CMP]] 2898; 2899 %add = sub <2 x i32> <i32 3, i32 3>, %X 2900 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2> 2901 ret <2 x i1> %cmp 2902} 2903 2904define i1 @icmp_and_X_-16_eq-16(i32 %X) { 2905; CHECK-LABEL: @icmp_and_X_-16_eq-16( 2906; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17 2907; CHECK-NEXT: ret i1 [[CMP]] 2908; 2909 %and = and i32 %X, -16 2910 %cmp = icmp eq i32 %and, -16 2911 ret i1 %cmp 2912} 2913 2914define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) { 2915; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec( 2916; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 -17) 2917; CHECK-NEXT: ret <2 x i1> [[CMP]] 2918; 2919 %and = and <2 x i32> %X, <i32 -16, i32 -16> 2920 %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16> 2921 ret <2 x i1> %cmp 2922} 2923 2924define i1 @icmp_and_X_-16_ne-16(i32 %X) { 2925; CHECK-LABEL: @icmp_and_X_-16_ne-16( 2926; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16 2927; CHECK-NEXT: ret i1 [[CMP]] 2928; 2929 %and = and i32 %X, -16 2930 %cmp = icmp ne i32 %and, -16 2931 ret i1 %cmp 2932} 2933 2934define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) { 2935; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec( 2936; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 -16) 2937; CHECK-NEXT: ret <2 x i1> [[CMP]] 2938; 2939 %and = and <2 x i32> %X, <i32 -16, i32 -16> 2940 %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16> 2941 ret <2 x i1> %cmp 2942} 2943 2944; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524 2945; X | C == C --> X <=u C (when C+1 is PowerOf2). 2946 2947define i1 @or1_eq1(i32 %x) { 2948; CHECK-LABEL: @or1_eq1( 2949; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2 2950; CHECK-NEXT: ret i1 [[T1]] 2951; 2952 %t0 = or i32 %x, 1 2953 %t1 = icmp eq i32 %t0, 1 2954 ret i1 %t1 2955} 2956 2957; X | C == C --> X <=u C (when C+1 is PowerOf2). 2958 2959define <2 x i1> @or3_eq3_vec(<2 x i8> %x) { 2960; CHECK-LABEL: @or3_eq3_vec( 2961; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], splat (i8 4) 2962; CHECK-NEXT: ret <2 x i1> [[T1]] 2963; 2964 %t0 = or <2 x i8> %x, <i8 3, i8 3> 2965 %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3> 2966 ret <2 x i1> %t1 2967} 2968 2969; X | C != C --> X >u C (when C+1 is PowerOf2). 2970 2971define i1 @or7_ne7(i32 %x) { 2972; CHECK-LABEL: @or7_ne7( 2973; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7 2974; CHECK-NEXT: ret i1 [[T1]] 2975; 2976 %t0 = or i32 %x, 7 2977 %t1 = icmp ne i32 %t0, 7 2978 ret i1 %t1 2979} 2980 2981; X | C != C --> X >u C (when C+1 is PowerOf2). 2982 2983define <2 x i1> @or63_ne63_vec(<2 x i8> %x) { 2984; CHECK-LABEL: @or63_ne63_vec( 2985; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 63) 2986; CHECK-NEXT: ret <2 x i1> [[T1]] 2987; 2988 %t0 = or <2 x i8> %x, <i8 63, i8 63> 2989 %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63> 2990 ret <2 x i1> %t1 2991} 2992 2993; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611 2994; X | C == C --> (X & ~C) == 0 2995 2996define i1 @orC_eqC(i32 %x) { 2997; CHECK-LABEL: @orC_eqC( 2998; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 2999; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[TMP1]], 0 3000; CHECK-NEXT: ret i1 [[T1]] 3001; 3002 %t0 = or i32 %x, 42 3003 %t1 = icmp eq i32 %t0, 42 3004 ret i1 %t1 3005} 3006 3007; X | C == C --> (X & ~C) == 0 3008 3009define <2 x i1> @orC_eqC_vec(<2 x i8> %x) { 3010; CHECK-LABEL: @orC_eqC_vec( 3011; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -44) 3012; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer 3013; CHECK-NEXT: ret <2 x i1> [[T1]] 3014; 3015 %t0 = or <2 x i8> %x, <i8 43, i8 43> 3016 %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43> 3017 ret <2 x i1> %t1 3018} 3019 3020; X | C != C --> (X & ~C) != 0 3021 3022define i1 @orC_neC(i32 %x) { 3023; CHECK-LABEL: @orC_neC( 3024; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 41 3025; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[TMP1]], 0 3026; CHECK-NEXT: ret i1 [[T1]] 3027; 3028 %t0 = or i32 %x, -42 3029 %t1 = icmp ne i32 %t0, -42 3030 ret i1 %t1 3031} 3032 3033; X | C != C --> (X & ~C) != 0 3034 3035define <2 x i1> @orC_neC_vec(<2 x i8> %x) { 3036; CHECK-LABEL: @orC_neC_vec( 3037; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 42) 3038; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer 3039; CHECK-NEXT: ret <2 x i1> [[T1]] 3040; 3041 %t0 = or <2 x i8> %x, <i8 -43, i8 -43> 3042 %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43> 3043 ret <2 x i1> %t1 3044} 3045 3046define i1 @shrink_constant(i32 %X) { 3047; CHECK-LABEL: @shrink_constant( 3048; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], -12 3049; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[XOR]], 4 3050; CHECK-NEXT: ret i1 [[CMP]] 3051; 3052 %xor = xor i32 %X, -9 3053 %cmp = icmp ult i32 %xor, 4 3054 ret i1 %cmp 3055} 3056 3057define <2 x i1> @shrink_constant_vec(<2 x i32> %X) { 3058; CHECK-LABEL: @shrink_constant_vec( 3059; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], splat (i32 -12) 3060; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], splat (i32 4) 3061; CHECK-NEXT: ret <2 x i1> [[CMP]] 3062; 3063 %xor = xor <2 x i32> %X, <i32 -9, i32 -9> 3064 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4> 3065 ret <2 x i1> %cmp 3066} 3067 3068; This test requires 3 different transforms to get to the result. 3069define i1 @icmp_sub_-1_X_ult_4(i32 %X) { 3070; CHECK-LABEL: @icmp_sub_-1_X_ult_4( 3071; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5 3072; CHECK-NEXT: ret i1 [[CMP]] 3073; 3074 %sub = sub i32 -1, %X 3075 %cmp = icmp ult i32 %sub, 4 3076 ret i1 %cmp 3077} 3078 3079define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) { 3080; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec( 3081; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 -5) 3082; CHECK-NEXT: ret <2 x i1> [[CMP]] 3083; 3084 %xor = xor <2 x i32> %X, <i32 -4, i32 -4> 3085 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4> 3086 ret <2 x i1> %cmp 3087} 3088 3089define i1 @icmp_sub_-1_X_uge_4(i32 %X) { 3090; CHECK-LABEL: @icmp_sub_-1_X_uge_4( 3091; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4 3092; CHECK-NEXT: ret i1 [[CMP]] 3093; 3094 %sub = sub i32 -1, %X 3095 %cmp = icmp uge i32 %sub, 4 3096 ret i1 %cmp 3097} 3098 3099define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) { 3100; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec( 3101; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 -4) 3102; CHECK-NEXT: ret <2 x i1> [[CMP]] 3103; 3104 %xor = xor <2 x i32> %X, <i32 -4, i32 -4> 3105 %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4> 3106 ret <2 x i1> %cmp 3107} 3108 3109define <2 x i1> @xor_ult(<2 x i8> %x) { 3110; CHECK-LABEL: @xor_ult( 3111; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 3) 3112; CHECK-NEXT: ret <2 x i1> [[R]] 3113; 3114 %xor = xor <2 x i8> %x, <i8 -4, i8 -4> 3115 %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4> 3116 ret <2 x i1> %r 3117} 3118 3119define i1 @xor_ult_extra_use(i8 %x, ptr %p) { 3120; CHECK-LABEL: @xor_ult_extra_use( 3121; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32 3122; CHECK-NEXT: store i8 [[XOR]], ptr [[P:%.*]], align 1 3123; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31 3124; CHECK-NEXT: ret i1 [[R]] 3125; 3126 %xor = xor i8 %x, -32 3127 store i8 %xor, ptr %p 3128 %r = icmp ult i8 %xor, -32 3129 ret i1 %r 3130} 3131 3132define <2 x i1> @xor_ugt(<2 x i8> %x) { 3133; CHECK-LABEL: @xor_ugt( 3134; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 7) 3135; CHECK-NEXT: ret <2 x i1> [[R]] 3136; 3137 %xor = xor <2 x i8> %x, <i8 7, i8 7> 3138 %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7> 3139 ret <2 x i1> %r 3140} 3141 3142define i1 @xor_ugt_extra_use(i8 %x, ptr %p) { 3143; CHECK-LABEL: @xor_ugt_extra_use( 3144; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63 3145; CHECK-NEXT: store i8 [[XOR]], ptr [[P:%.*]], align 1 3146; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63 3147; CHECK-NEXT: ret i1 [[R]] 3148; 3149 %xor = xor i8 %x, 63 3150 store i8 %xor, ptr %p 3151 %r = icmp ugt i8 %xor, 63 3152 ret i1 %r 3153} 3154 3155define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) { 3156; CHECK-LABEL: @icmp_lshr_lshr_eq( 3157; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 3158; CHECK-NEXT: [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824 3159; CHECK-NEXT: ret i1 [[Z]] 3160; 3161 %x = lshr i32 %a, 30 3162 %y = lshr i32 %b, 30 3163 %z = icmp eq i32 %x, %y 3164 ret i1 %z 3165} 3166 3167define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) { 3168; CHECK-LABEL: @icmp_ashr_ashr_ne( 3169; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 3170; CHECK-NEXT: [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255 3171; CHECK-NEXT: ret i1 [[Z]] 3172; 3173 %x = ashr i32 %a, 8 3174 %y = ashr i32 %b, 8 3175 %z = icmp ne i32 %x, %y 3176 ret i1 %z 3177} 3178 3179define i1 @icmp_neg_cst_slt(i32 %a) { 3180; CHECK-LABEL: @icmp_neg_cst_slt( 3181; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10 3182; CHECK-NEXT: ret i1 [[TMP1]] 3183; 3184 %1 = sub nsw i32 0, %a 3185 %2 = icmp slt i32 %1, -10 3186 ret i1 %2 3187} 3188 3189define i1 @icmp_and_or_lshr(i32 %x, i32 %y) { 3190; CHECK-LABEL: @icmp_and_or_lshr( 3191; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]] 3192; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1 3193; CHECK-NEXT: [[AND3:%.*]] = and i32 [[X:%.*]], [[OR2]] 3194; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0 3195; CHECK-NEXT: ret i1 [[RET]] 3196; 3197 %shf = lshr i32 %x, %y 3198 %or = or i32 %shf, %x 3199 %and = and i32 %or, 1 3200 %ret = icmp ne i32 %and, 0 3201 ret i1 %ret 3202} 3203 3204define i1 @icmp_and_or_lshr_samesign(i32 %x, i32 %y) { 3205; CHECK-LABEL: @icmp_and_or_lshr_samesign( 3206; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]] 3207; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1 3208; CHECK-NEXT: [[AND3:%.*]] = and i32 [[X:%.*]], [[OR2]] 3209; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0 3210; CHECK-NEXT: ret i1 [[RET]] 3211; 3212 %shf = lshr i32 %x, %y 3213 %or = or i32 %shf, %x 3214 %and = and i32 %or, 1 3215 %ret = icmp samesign ne i32 %and, 0 3216 ret i1 %ret 3217} 3218 3219define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) { 3220; CHECK-LABEL: @icmp_and_or_lshr_vec( 3221; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]] 3222; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]] 3223; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1> 3224; CHECK-NEXT: ret <2 x i1> [[RET]] 3225; 3226 %shf = lshr <2 x i32> %x, %y 3227 %or = or <2 x i32> %shf, %x 3228 %and = and <2 x i32> %or, <i32 1, i32 1> 3229 %ret = icmp ne <2 x i32> %and, zeroinitializer 3230 ret <2 x i1> %ret 3231} 3232 3233define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) { 3234; CHECK-LABEL: @icmp_and_or_lshr_vec_commute( 3235; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42) 3236; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]] 3237; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]] 3238; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1> 3239; CHECK-NEXT: ret <2 x i1> [[RET]] 3240; 3241 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 3242 %shf = lshr <2 x i32> %x, %y 3243 %or = or <2 x i32> %x, %shf 3244 %and = and <2 x i32> %or, <i32 1, i32 1> 3245 %ret = icmp ne <2 x i32> %and, zeroinitializer 3246 ret <2 x i1> %ret 3247} 3248 3249define i1 @icmp_and_or_lshr_cst(i32 %x) { 3250; CHECK-LABEL: @icmp_and_or_lshr_cst( 3251; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], 3 3252; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND1]], 0 3253; CHECK-NEXT: ret i1 [[RET]] 3254; 3255 %shf = lshr i32 %x, 1 3256 %or = or i32 %shf, %x 3257 %and = and i32 %or, 1 3258 %ret = icmp ne i32 %and, 0 3259 ret i1 %ret 3260} 3261 3262define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) { 3263; CHECK-LABEL: @icmp_and_or_lshr_cst_vec( 3264; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 3) 3265; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 3266; CHECK-NEXT: ret <2 x i1> [[RET]] 3267; 3268 %shf = lshr <2 x i32> %x, <i32 1, i32 1> 3269 %or = or <2 x i32> %shf, %x 3270 %and = and <2 x i32> %or, <i32 1, i32 1> 3271 %ret = icmp ne <2 x i32> %and, zeroinitializer 3272 ret <2 x i1> %ret 3273} 3274 3275define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) { 3276; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform( 3277; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 5> 3278; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 3279; CHECK-NEXT: ret <2 x i1> [[RET]] 3280; 3281 %shf = lshr <2 x i32> %x, <i32 1, i32 2> 3282 %or = or <2 x i32> %shf, %x 3283 %and = and <2 x i32> %or, <i32 1, i32 1> 3284 %ret = icmp ne <2 x i32> %and, zeroinitializer 3285 ret <2 x i1> %ret 3286} 3287 3288define <2 x i1> @icmp_and_or_lshr_cst_vec_poison(<2 x i32> %x) { 3289; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_poison( 3290; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 poison> 3291; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 3292; CHECK-NEXT: ret <2 x i1> [[RET]] 3293; 3294 %shf = lshr <2 x i32> %x, <i32 1, i32 poison> 3295 %or = or <2 x i32> %shf, %x 3296 %and = and <2 x i32> %or, <i32 1, i32 1> 3297 %ret = icmp ne <2 x i32> %and, zeroinitializer 3298 ret <2 x i1> %ret 3299} 3300 3301define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) { 3302; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute( 3303; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42) 3304; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 3) 3305; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 3306; CHECK-NEXT: ret <2 x i1> [[RET]] 3307; 3308 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 3309 %shf = lshr <2 x i32> %x, <i32 1, i32 1> 3310 %or = or <2 x i32> %x, %shf 3311 %and = and <2 x i32> %or, <i32 1, i32 1> 3312 %ret = icmp ne <2 x i32> %and, zeroinitializer 3313 ret <2 x i1> %ret 3314} 3315 3316define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) { 3317; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform_commute( 3318; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42) 3319; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5> 3320; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 3321; CHECK-NEXT: ret <2 x i1> [[RET]] 3322; 3323 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 3324 %shf = lshr <2 x i32> %x, <i32 1, i32 2> 3325 %or = or <2 x i32> %x, %shf 3326 %and = and <2 x i32> %or, <i32 1, i32 1> 3327 %ret = icmp ne <2 x i32> %and, zeroinitializer 3328 ret <2 x i1> %ret 3329} 3330 3331define <2 x i1> @icmp_and_or_lshr_cst_vec_poison_commute(<2 x i32> %xp) { 3332; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_poison_commute( 3333; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42) 3334; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison> 3335; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 3336; CHECK-NEXT: ret <2 x i1> [[RET]] 3337; 3338 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization 3339 %shf = lshr <2 x i32> %x, <i32 1, i32 poison> 3340 %or = or <2 x i32> %x, %shf 3341 %and = and <2 x i32> %or, <i32 1, i32 1> 3342 %ret = icmp ne <2 x i32> %and, zeroinitializer 3343 ret <2 x i1> %ret 3344} 3345 3346define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) { 3347; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2( 3348; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29 3349; CHECK-NEXT: ret i1 [[CMP]] 3350; 3351 %shl = shl i32 4, %a 3352 %cmp = icmp eq i32 %shl, 0 3353 ret i1 %cmp 3354} 3355 3356define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) { 3357; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec( 3358; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 29) 3359; CHECK-NEXT: ret <2 x i1> [[CMP]] 3360; 3361 %shl = shl <2 x i32> <i32 4, i32 4>, %a 3362 %cmp = icmp eq <2 x i32> %shl, zeroinitializer 3363 ret <2 x i1> %cmp 3364} 3365 3366define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) { 3367; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform( 3368; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A:%.*]] 3369; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer 3370; CHECK-NEXT: ret <2 x i1> [[CMP]] 3371; 3372 %shl = shl <2 x i32> <i32 4, i32 5>, %a 3373 %cmp = icmp eq <2 x i32> %shl, zeroinitializer 3374 ret <2 x i1> %cmp 3375} 3376 3377define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) { 3378; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4( 3379; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30 3380; CHECK-NEXT: ret i1 [[CMP]] 3381; 3382 %shl = shl i32 -2, %a 3383 %cmp = icmp eq i32 %shl, 0 3384 ret i1 %cmp 3385} 3386 3387define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) { 3388; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive( 3389; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 3390; CHECK-NEXT: ret i1 [[CMP]] 3391; 3392 %shl = shl i32 50, %a 3393 %cmp = icmp eq i32 %shl, 50 3394 ret i1 %cmp 3395} 3396 3397define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) { 3398; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative( 3399; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 3400; CHECK-NEXT: ret i1 [[CMP]] 3401; 3402 %shl = shl i32 -50, %a 3403 %cmp = icmp eq i32 %shl, -50 3404 ret i1 %cmp 3405} 3406 3407define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) { 3408; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1( 3409; CHECK-NEXT: ret i1 false 3410; 3411 %shl = shl i32 50, %a 3412 %cmp = icmp eq i32 %shl, 25 3413 ret i1 %cmp 3414} 3415 3416define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) { 3417; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2( 3418; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1 3419; CHECK-NEXT: ret i1 [[CMP]] 3420; 3421 %shl = shl i32 25, %a 3422 %cmp = icmp eq i32 %shl, 50 3423 ret i1 %cmp 3424} 3425 3426define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) { 3427; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3( 3428; CHECK-NEXT: ret i1 false 3429; 3430 %shl = shl i32 26, %a 3431 %cmp = icmp eq i32 %shl, 50 3432 ret i1 %cmp 3433} 3434 3435define i1 @icmp_sgt_zero_add_nsw(i32 %a) { 3436; CHECK-LABEL: @icmp_sgt_zero_add_nsw( 3437; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1 3438; CHECK-NEXT: ret i1 [[CMP]] 3439; 3440 %add = add nsw i32 %a, 1 3441 %cmp = icmp sgt i32 %add, 0 3442 ret i1 %cmp 3443} 3444 3445define i1 @icmp_sge_zero_add_nsw(i32 %a) { 3446; CHECK-LABEL: @icmp_sge_zero_add_nsw( 3447; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2 3448; CHECK-NEXT: ret i1 [[CMP]] 3449; 3450 %add = add nsw i32 %a, 1 3451 %cmp = icmp sge i32 %add, 0 3452 ret i1 %cmp 3453} 3454 3455define i1 @icmp_sle_zero_add_nsw(i32 %a) { 3456; CHECK-LABEL: @icmp_sle_zero_add_nsw( 3457; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0 3458; CHECK-NEXT: ret i1 [[CMP]] 3459; 3460 %add = add nsw i32 %a, 1 3461 %cmp = icmp sle i32 %add, 0 3462 ret i1 %cmp 3463} 3464 3465define zeroext i1 @icmp_cmpxchg_strong(ptr %sc, i32 %old_val, i32 %new_val) { 3466; CHECK-LABEL: @icmp_cmpxchg_strong( 3467; CHECK-NEXT: [[XCHG:%.*]] = cmpxchg ptr [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst, align 4 3468; CHECK-NEXT: [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1 3469; CHECK-NEXT: ret i1 [[ICMP]] 3470; 3471 %xchg = cmpxchg ptr %sc, i32 %old_val, i32 %new_val seq_cst seq_cst 3472 %xtrc = extractvalue { i32, i1 } %xchg, 0 3473 %icmp = icmp eq i32 %xtrc, %old_val 3474 ret i1 %icmp 3475} 3476 3477define i1 @f1(i64 %a, i64 %b) { 3478; CHECK-LABEL: @f1( 3479; CHECK-NEXT: [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]] 3480; CHECK-NEXT: ret i1 [[V]] 3481; 3482 %t = sub nsw i64 %a, %b 3483 %v = icmp sge i64 %t, 0 3484 ret i1 %v 3485} 3486 3487define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) { 3488; CHECK-LABEL: @f1_vec( 3489; CHECK-NEXT: [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]] 3490; CHECK-NEXT: ret <2 x i1> [[V]] 3491; 3492 %t = sub nsw <2 x i64> %a, %b 3493 %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1> 3494 ret <2 x i1> %v 3495} 3496 3497define i1 @f2(i64 %a, i64 %b) { 3498; CHECK-LABEL: @f2( 3499; CHECK-NEXT: [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]] 3500; CHECK-NEXT: ret i1 [[V]] 3501; 3502 %t = sub nsw i64 %a, %b 3503 %v = icmp sgt i64 %t, 0 3504 ret i1 %v 3505} 3506 3507define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) { 3508; CHECK-LABEL: @f2_vec( 3509; CHECK-NEXT: [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]] 3510; CHECK-NEXT: ret <2 x i1> [[V]] 3511; 3512 %t = sub nsw <2 x i64> %a, %b 3513 %v = icmp sgt <2 x i64> %t, zeroinitializer 3514 ret <2 x i1> %v 3515} 3516 3517define i1 @f3(i64 %a, i64 %b) { 3518; CHECK-LABEL: @f3( 3519; CHECK-NEXT: [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]] 3520; CHECK-NEXT: ret i1 [[V]] 3521; 3522 %t = sub nsw i64 %a, %b 3523 %v = icmp slt i64 %t, 0 3524 ret i1 %v 3525} 3526 3527define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) { 3528; CHECK-LABEL: @f3_vec( 3529; CHECK-NEXT: [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]] 3530; CHECK-NEXT: ret <2 x i1> [[V]] 3531; 3532 %t = sub nsw <2 x i64> %a, %b 3533 %v = icmp slt <2 x i64> %t, zeroinitializer 3534 ret <2 x i1> %v 3535} 3536 3537define i1 @f4(i64 %a, i64 %b) { 3538; CHECK-LABEL: @f4( 3539; CHECK-NEXT: [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]] 3540; CHECK-NEXT: ret i1 [[V]] 3541; 3542 %t = sub nsw i64 %a, %b 3543 %v = icmp sle i64 %t, 0 3544 ret i1 %v 3545} 3546 3547define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) { 3548; CHECK-LABEL: @f4_vec( 3549; CHECK-NEXT: [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]] 3550; CHECK-NEXT: ret <2 x i1> [[V]] 3551; 3552 %t = sub nsw <2 x i64> %a, %b 3553 %v = icmp slt <2 x i64> %t, <i64 1, i64 1> 3554 ret <2 x i1> %v 3555} 3556 3557define i32 @f5(i8 %a, i8 %b) { 3558; CHECK-LABEL: @f5( 3559; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 3560; CHECK-NEXT: [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32 3561; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]] 3562; CHECK-NEXT: [[SUB7_SUB:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true) 3563; CHECK-NEXT: ret i32 [[SUB7_SUB]] 3564; 3565 %conv = zext i8 %a to i32 3566 %conv3 = zext i8 %b to i32 3567 %sub = sub nsw i32 %conv, %conv3 3568 %cmp4 = icmp slt i32 %sub, 0 3569 %sub7 = sub nsw i32 0, %sub 3570 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub 3571 ret i32 %sub7.sub 3572} 3573 3574define i32 @f6(i32 %a, i32 %b) { 3575; CHECK-LABEL: @f6( 3576; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 3577; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255 3578; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0 3579; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0 3580; CHECK-NEXT: ret i32 [[S]] 3581; 3582 %sext = shl i32 %a, 24 3583 %conv = ashr i32 %sext, 24 3584 %sext6 = shl i32 %b, 24 3585 %conv4 = ashr i32 %sext6, 24 3586 %cmp = icmp eq i32 %conv, %conv4 3587 %s = select i1 %cmp, i32 10000, i32 0 3588 ret i32 %s 3589} 3590 3591define i32 @f7(i32 %a, i32 %b) { 3592; CHECK-LABEL: @f7( 3593; CHECK-NEXT: [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 3594; CHECK-NEXT: [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 511 3595; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 0 3596; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 10000 3597; CHECK-NEXT: ret i32 [[S]] 3598; 3599 %sext = shl i32 %a, 23 3600 %sext6 = shl i32 %b, 23 3601 %cmp = icmp ne i32 %sext, %sext6 3602 %s = select i1 %cmp, i32 10000, i32 0 3603 ret i32 %s 3604} 3605 3606define i1 @f8(i32 %val, i32 %lim) { 3607; CHECK-LABEL: @f8( 3608; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0 3609; CHECK-NEXT: ret i1 [[R]] 3610; 3611 %lim.sub = add i32 %lim, -1 3612 %val.and = and i32 %val, %lim.sub 3613 %r = icmp ult i32 %val.and, %lim 3614 ret i1 %r 3615} 3616 3617define i1 @f9(i32 %val, i32 %lim) { 3618; CHECK-LABEL: @f9( 3619; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0 3620; CHECK-NEXT: ret i1 [[R]] 3621; 3622 %lim.sub = sub i32 %lim, 1 3623 %val.and = and i32 %val, %lim.sub 3624 %r = icmp ult i32 %val.and, %lim 3625 ret i1 %r 3626} 3627 3628define i1 @f10(i16 %p) { 3629; CHECK-LABEL: @f10( 3630; CHECK-NEXT: [[EXT1:%.*]] = zext i8 ptrtoint (ptr @f10 to i8) to i16 3631; CHECK-NEXT: [[EXT2:%.*]] = zext i8 ptrtoint (ptr @f10 to i8) to i16 3632; CHECK-NEXT: [[MUL:%.*]] = mul nuw i16 [[EXT1]], [[EXT2]] 3633; CHECK-NEXT: [[CMP580:%.*]] = icmp ule i16 [[MUL]], [[P:%.*]] 3634; CHECK-NEXT: ret i1 [[CMP580]] 3635; 3636 %ext1 = zext i8 ptrtoint (ptr @f10 to i8) to i16 3637 %ext2 = zext i8 ptrtoint (ptr @f10 to i8) to i16 3638 %mul = mul i16 %ext1, %ext2 3639 %cmp580 = icmp ule i16 %mul, %p 3640 ret i1 %cmp580 3641} 3642 3643; Note: fptosi is used in various tests below to ensure that operand complexity 3644; canonicalization does not kick in, which would make some of the tests 3645; equivalent to one another. 3646 3647define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) { 3648; CHECK-LABEL: @cmp_sgt_rhs_dec( 3649; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3650; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[I:%.*]], [[CONV]] 3651; CHECK-NEXT: ret i1 [[CMP]] 3652; 3653 %conv = fptosi float %x to i32 3654 %dec = sub nsw i32 %i, 1 3655 %cmp = icmp sgt i32 %conv, %dec 3656 ret i1 %cmp 3657} 3658 3659define i1 @cmp_sle_rhs_dec(float %x, i32 %i) { 3660; CHECK-LABEL: @cmp_sle_rhs_dec( 3661; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3662; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[I:%.*]], [[CONV]] 3663; CHECK-NEXT: ret i1 [[CMP]] 3664; 3665 %conv = fptosi float %x to i32 3666 %dec = sub nsw i32 %i, 1 3667 %cmp = icmp sle i32 %conv, %dec 3668 ret i1 %cmp 3669} 3670 3671define i1 @cmp_sge_rhs_inc(float %x, i32 %i) { 3672; CHECK-LABEL: @cmp_sge_rhs_inc( 3673; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3674; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I:%.*]], [[CONV]] 3675; CHECK-NEXT: ret i1 [[CMP]] 3676; 3677 %conv = fptosi float %x to i32 3678 %inc = add nsw i32 %i, 1 3679 %cmp = icmp sge i32 %conv, %inc 3680 ret i1 %cmp 3681} 3682 3683define i1 @cmp_slt_rhs_inc(float %x, i32 %i) { 3684; CHECK-LABEL: @cmp_slt_rhs_inc( 3685; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3686; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[I:%.*]], [[CONV]] 3687; CHECK-NEXT: ret i1 [[CMP]] 3688; 3689 %conv = fptosi float %x to i32 3690 %inc = add nsw i32 %i, 1 3691 %cmp = icmp slt i32 %conv, %inc 3692 ret i1 %cmp 3693} 3694 3695define i1 @PR26407(i32 %x, i32 %y) { 3696; CHECK-LABEL: @PR26407( 3697; CHECK-NEXT: [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647 3698; CHECK-NEXT: [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647 3699; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]] 3700; CHECK-NEXT: ret i1 [[CMP]] 3701; 3702 %addx = add i32 %x, 2147483647 3703 %addy = add i32 %y, 2147483647 3704 %cmp = icmp uge i32 %addx, %addy 3705 ret i1 %cmp 3706} 3707 3708define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) { 3709; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq( 3710; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 3711; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43 3712; CHECK-NEXT: ret i1 [[CMP]] 3713; 3714 %or = or i32 %x, 42 3715 %cmp = icmp eq i32 %or, -1 3716 ret i1 %cmp 3717} 3718 3719define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) { 3720; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec( 3721; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -43) 3722; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 -43) 3723; CHECK-NEXT: ret <2 x i1> [[CMP]] 3724; 3725 %or = or <2 x i32> %x, <i32 42, i32 42> 3726 %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1> 3727 ret <2 x i1> %cmp 3728} 3729 3730define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) { 3731; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne( 3732; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43 3733; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43 3734; CHECK-NEXT: ret i1 [[CMP]] 3735; 3736 %or = or i32 %x, 42 3737 %cmp = icmp ne i32 %or, -1 3738 ret i1 %cmp 3739} 3740 3741; When canonicalizing to 'gt/lt', make sure the constant is correct. 3742 3743define i1 @PR27792(i128 %a) { 3744; CHECK-LABEL: @PR27792( 3745; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1 3746; CHECK-NEXT: ret i1 [[CMP]] 3747; 3748 %cmp = icmp sge i128 %a, 0 3749 ret i1 %cmp 3750} 3751 3752define i1 @PR27792_2(i128 %a) { 3753; CHECK-LABEL: @PR27792_2( 3754; CHECK-NEXT: [[B:%.*]] = icmp ne i128 [[A:%.*]], 0 3755; CHECK-NEXT: ret i1 [[B]] 3756; 3757 %b = icmp uge i128 %a, 1 3758 ret i1 %b 3759} 3760 3761define i1 @ugtMaxSignedVal(i8 %a) { 3762; CHECK-LABEL: @ugtMaxSignedVal( 3763; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0 3764; CHECK-NEXT: ret i1 [[CMP]] 3765; 3766 %cmp = icmp ugt i8 %a, 127 3767 ret i1 %cmp 3768} 3769 3770define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) { 3771; CHECK-LABEL: @ugtMaxSignedValVec( 3772; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer 3773; CHECK-NEXT: ret <2 x i1> [[CMP]] 3774; 3775 %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127> 3776 ret <2 x i1> %cmp 3777} 3778 3779define i1 @ugtKnownBits(i8 %a) { 3780; CHECK-LABEL: @ugtKnownBits( 3781; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 17 3782; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 17 3783; CHECK-NEXT: ret i1 [[CMP]] 3784; 3785 %b = and i8 %a, 17 3786 %cmp = icmp ugt i8 %b, 16 3787 ret i1 %cmp 3788} 3789 3790define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) { 3791; CHECK-LABEL: @ugtKnownBitsVec( 3792; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 17) 3793; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], splat (i8 17) 3794; CHECK-NEXT: ret <2 x i1> [[CMP]] 3795; 3796 %b = and <2 x i8> %a, <i8 17, i8 17> 3797 %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16> 3798 ret <2 x i1> %cmp 3799} 3800 3801define i1 @or_ptrtoint_mismatch(ptr %p, ptr %q) { 3802; CHECK-LABEL: @or_ptrtoint_mismatch( 3803; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[P:%.*]], null 3804; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[Q:%.*]], null 3805; CHECK-NEXT: [[B:%.*]] = and i1 [[TMP1]], [[TMP2]] 3806; CHECK-NEXT: ret i1 [[B]] 3807; 3808 3809 %pp = ptrtoint ptr %p to i64 3810 %qq = ptrtoint ptr %q to i64 3811 %o = or i64 %pp, %qq 3812 %b = icmp eq i64 %o, 0 3813 ret i1 %b 3814} 3815 3816define i1 @icmp_add1_ugt(i32 %x, i32 %y) { 3817; CHECK-LABEL: @icmp_add1_ugt( 3818; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 3819; CHECK-NEXT: ret i1 [[CMP]] 3820; 3821 %add = add nuw i32 %x, 1 3822 %cmp = icmp ugt i32 %add, %y 3823 ret i1 %cmp 3824} 3825 3826define i1 @icmp_add1_ule(i32 %x, i32 %y) { 3827; CHECK-LABEL: @icmp_add1_ule( 3828; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 3829; CHECK-NEXT: ret i1 [[CMP]] 3830; 3831 %add = add nuw i32 %x, 1 3832 %cmp = icmp ule i32 %add, %y 3833 ret i1 %cmp 3834} 3835 3836define i1 @cmp_uge_rhs_inc(float %x, i32 %i) { 3837; CHECK-LABEL: @cmp_uge_rhs_inc( 3838; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3839; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[I:%.*]], [[CONV]] 3840; CHECK-NEXT: ret i1 [[CMP]] 3841; 3842 %conv = fptosi float %x to i32 3843 %inc = add nuw i32 %i, 1 3844 %cmp = icmp uge i32 %conv, %inc 3845 ret i1 %cmp 3846} 3847 3848define i1 @cmp_ult_rhs_inc(float %x, i32 %i) { 3849; CHECK-LABEL: @cmp_ult_rhs_inc( 3850; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3851; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[I:%.*]], [[CONV]] 3852; CHECK-NEXT: ret i1 [[CMP]] 3853; 3854 %conv = fptosi float %x to i32 3855 %inc = add nuw i32 %i, 1 3856 %cmp = icmp ult i32 %conv, %inc 3857 ret i1 %cmp 3858} 3859 3860define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) { 3861; CHECK-LABEL: @cmp_sge_lhs_inc( 3862; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[X:%.*]], 1 3863; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]] 3864; CHECK-NEXT: ret i1 [[CMP]] 3865; 3866 %inc = add nsw i32 %x, 1 3867 %cmp = icmp sge i32 %inc, %y 3868 ret i1 %cmp 3869} 3870 3871define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) { 3872; CHECK-LABEL: @cmp_uge_lhs_inc( 3873; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[X:%.*]], 1 3874; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]] 3875; CHECK-NEXT: ret i1 [[CMP]] 3876; 3877 %inc = add nuw i32 %x, 1 3878 %cmp = icmp uge i32 %inc, %y 3879 ret i1 %cmp 3880} 3881 3882define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) { 3883; CHECK-LABEL: @cmp_sgt_lhs_dec( 3884; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1 3885; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]] 3886; CHECK-NEXT: ret i1 [[CMP]] 3887; 3888 %dec = sub nsw i32 %x, 1 3889 %cmp = icmp sgt i32 %dec, %y 3890 ret i1 %cmp 3891} 3892 3893define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) { 3894; CHECK-LABEL: @cmp_ugt_lhs_dec( 3895; CHECK-NEXT: [[DEC:%.*]] = add i32 [[X:%.*]], -1 3896; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]] 3897; CHECK-NEXT: ret i1 [[CMP]] 3898; 3899 %dec = sub nuw i32 %x, 1 3900 %cmp = icmp ugt i32 %dec, %y 3901 ret i1 %cmp 3902} 3903 3904define i1 @cmp_sle_rhs_inc(float %x, i32 %y) { 3905; CHECK-LABEL: @cmp_sle_rhs_inc( 3906; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3907; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1 3908; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]] 3909; CHECK-NEXT: ret i1 [[CMP]] 3910; 3911 %conv = fptosi float %x to i32 3912 %inc = add nsw i32 %y, 1 3913 %cmp = icmp sle i32 %conv, %inc 3914 ret i1 %cmp 3915} 3916 3917define i1 @cmp_ule_rhs_inc(float %x, i32 %y) { 3918; CHECK-LABEL: @cmp_ule_rhs_inc( 3919; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3920; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1 3921; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]] 3922; CHECK-NEXT: ret i1 [[CMP]] 3923; 3924 %conv = fptosi float %x to i32 3925 %inc = add nuw i32 %y, 1 3926 %cmp = icmp ule i32 %conv, %inc 3927 ret i1 %cmp 3928} 3929 3930define i1 @cmp_slt_rhs_dec(float %x, i32 %y) { 3931; CHECK-LABEL: @cmp_slt_rhs_dec( 3932; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3933; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1 3934; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]] 3935; CHECK-NEXT: ret i1 [[CMP]] 3936; 3937 %conv = fptosi float %x to i32 3938 %dec = sub nsw i32 %y, 1 3939 %cmp = icmp slt i32 %conv, %dec 3940 ret i1 %cmp 3941} 3942 3943define i1 @cmp_ult_rhs_dec(float %x, i32 %y) { 3944; CHECK-LABEL: @cmp_ult_rhs_dec( 3945; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32 3946; CHECK-NEXT: [[DEC:%.*]] = add i32 [[Y:%.*]], -1 3947; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]] 3948; CHECK-NEXT: ret i1 [[CMP]] 3949; 3950 %conv = fptosi float %x to i32 3951 %dec = sub nuw i32 %y, 1 3952 %cmp = icmp ult i32 %conv, %dec 3953 ret i1 %cmp 3954} 3955 3956define i1 @eq_add_constants(i32 %x, i32 %y) { 3957; CHECK-LABEL: @eq_add_constants( 3958; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 3959; CHECK-NEXT: ret i1 [[C]] 3960; 3961 %A = add i32 %x, 5 3962 %B = add i32 %y, 5 3963 %C = icmp eq i32 %A, %B 3964 ret i1 %C 3965} 3966 3967declare i32 @llvm.bswap.i32(i32) 3968 3969define i1 @bswap_ne(i32 %x, i32 %y) { 3970; CHECK-LABEL: @bswap_ne( 3971; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 3972; CHECK-NEXT: ret i1 [[CMP]] 3973; 3974 %swapx = call i32 @llvm.bswap.i32(i32 %x) 3975 %swapy = call i32 @llvm.bswap.i32(i32 %y) 3976 %cmp = icmp ne i32 %swapx, %swapy 3977 ret i1 %cmp 3978} 3979 3980declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>) 3981 3982define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) { 3983; CHECK-LABEL: @bswap_vec_eq( 3984; CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]] 3985; CHECK-NEXT: ret <8 x i1> [[CMP]] 3986; 3987 %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x) 3988 %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y) 3989 %cmp = icmp eq <8 x i16> %swapx, %swapy 3990 ret <8 x i1> %cmp 3991} 3992 3993declare i64 @llvm.bitreverse.i64(i64) 3994 3995define i1 @bitreverse_eq(i64 %x, i64 %y) { 3996; CHECK-LABEL: @bitreverse_eq( 3997; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] 3998; CHECK-NEXT: ret i1 [[CMP]] 3999; 4000 %revx = call i64 @llvm.bitreverse.i64(i64 %x) 4001 %revy = call i64 @llvm.bitreverse.i64(i64 %y) 4002 %cmp = icmp eq i64 %revx, %revy 4003 ret i1 %cmp 4004} 4005 4006declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>) 4007 4008define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) { 4009; CHECK-LABEL: @bitreverse_vec_ne( 4010; CHECK-NEXT: [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]] 4011; CHECK-NEXT: ret <8 x i1> [[CMP]] 4012; 4013 %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x) 4014 %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y) 4015 %cmp = icmp ne <8 x i16> %revx, %revy 4016 ret <8 x i1> %cmp 4017} 4018 4019; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7. 4020; They should all simplify to equality compares. 4021define i1 @knownbits1(i8 %a, i8 %b) { 4022; CHECK-LABEL: @knownbits1( 4023; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 4024; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 4025; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 4026; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]] 4027; CHECK-NEXT: ret i1 [[C]] 4028; 4029 %a1 = and i8 %a, 5 4030 %a2 = or i8 %a1, 4 4031 %b1 = and i8 %b, 7 4032 %b2 = or i8 %b1, 5 4033 %c = icmp uge i8 %a2, %b2 4034 ret i1 %c 4035} 4036 4037define i1 @knownbits2(i8 %a, i8 %b) { 4038; CHECK-LABEL: @knownbits2( 4039; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 4040; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 4041; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 4042; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]] 4043; CHECK-NEXT: ret i1 [[C]] 4044; 4045 %a1 = and i8 %a, 5 4046 %a2 = or i8 %a1, 4 4047 %b1 = and i8 %b, 7 4048 %b2 = or i8 %b1, 5 4049 %c = icmp ult i8 %a2, %b2 4050 ret i1 %c 4051} 4052 4053define i1 @knownbits3(i8 %a, i8 %b) { 4054; CHECK-LABEL: @knownbits3( 4055; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1 4056; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 4057; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 4058; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A1]] 4059; CHECK-NEXT: ret i1 [[C]] 4060; 4061 %a1 = and i8 %a, 5 4062 %a2 = or i8 %a1, 4 4063 %b1 = and i8 %b, 7 4064 %b2 = or i8 %b1, 5 4065 %c = icmp ule i8 %b2, %a2 4066 ret i1 %c 4067} 4068 4069define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) { 4070; CHECK-LABEL: @knownbits4( 4071; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 1) 4072; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 2) 4073; CHECK-NEXT: [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], splat (i8 1) 4074; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], [[A1]] 4075; CHECK-NEXT: ret <2 x i1> [[C]] 4076; 4077 %a1 = and <2 x i8> %a, <i8 5, i8 5> 4078 %a2 = or <2 x i8> %a1, <i8 4, i8 4> 4079 %b1 = and <2 x i8> %b, <i8 7, i8 7> 4080 %b2 = or <2 x i8> %b1, <i8 5, i8 5> 4081 %c = icmp ugt <2 x i8> %b2, %a2 4082 ret <2 x i1> %c 4083} 4084 4085; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative. 4086; The other is known to be a value 5-7. These should simplify to equality comparisons. 4087define i1 @knownbits5(i8 %a, i8 %b) { 4088; CHECK-LABEL: @knownbits5( 4089; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 4090; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 4091; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 4092; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]] 4093; CHECK-NEXT: ret i1 [[C]] 4094; 4095 %a1 = and i8 %a, 133 4096 %a2 = or i8 %a1, 4 4097 %b1 = and i8 %b, 7 4098 %b2 = or i8 %b1, 5 4099 %c = icmp sge i8 %a2, %b2 4100 ret i1 %c 4101} 4102 4103define i1 @knownbits6(i8 %a, i8 %b) { 4104; CHECK-LABEL: @knownbits6( 4105; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 4106; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 4107; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 4108; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]] 4109; CHECK-NEXT: ret i1 [[C]] 4110; 4111 %a1 = and i8 %a, 133 4112 %a2 = or i8 %a1, 4 4113 %b1 = and i8 %b, 7 4114 %b2 = or i8 %b1, 5 4115 %c = icmp slt i8 %a2, %b2 4116 ret i1 %c 4117} 4118 4119define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) { 4120; CHECK-LABEL: @knownbits7( 4121; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 -127) 4122; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 2) 4123; CHECK-NEXT: [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], splat (i8 1) 4124; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[TMP1]], [[A1]] 4125; CHECK-NEXT: ret <2 x i1> [[C]] 4126; 4127 %a1 = and <2 x i8> %a, <i8 133, i8 133> 4128 %a2 = or <2 x i8> %a1, <i8 4, i8 4> 4129 %b1 = and <2 x i8> %b, <i8 7, i8 7> 4130 %b2 = or <2 x i8> %b1, <i8 5, i8 5> 4131 %c = icmp sle <2 x i8> %b2, %a2 4132 ret <2 x i1> %c 4133} 4134 4135define i1 @knownbits8(i8 %a, i8 %b) { 4136; CHECK-LABEL: @knownbits8( 4137; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127 4138; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2 4139; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1 4140; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[TMP1]], [[A1]] 4141; CHECK-NEXT: ret i1 [[C]] 4142; 4143 %a1 = and i8 %a, 133 4144 %a2 = or i8 %a1, 4 4145 %b1 = and i8 %b, 7 4146 %b2 = or i8 %b1, 5 4147 %c = icmp sgt i8 %b2, %a2 4148 ret i1 %c 4149} 4150 4151; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom 4152define i32 @abs_preserve(i32 %x) { 4153; CHECK-LABEL: @abs_preserve( 4154; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X:%.*]], 1 4155; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[A]], i1 false) 4156; CHECK-NEXT: ret i32 [[ABS]] 4157; 4158 %a = mul nsw i32 %x, 2 4159 %c = icmp sge i32 %a, 0 4160 %nega = sub i32 0, %a 4161 %abs = select i1 %c, i32 %a, i32 %nega 4162 ret i32 %abs 4163} 4164 4165; Don't crash by assuming the compared values are integers. 4166 4167declare void @llvm.assume(i1) 4168define i1 @PR35794(ptr %a) { 4169; CHECK-LABEL: @PR35794( 4170; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq ptr [[A:%.*]], null 4171; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 4172; CHECK-NEXT: ret i1 true 4173; 4174 %cmp = icmp sgt ptr %a, inttoptr (i64 -1 to ptr) 4175 %maskcond = icmp eq ptr %a, null 4176 tail call void @llvm.assume(i1 %maskcond) 4177 ret i1 %cmp 4178} 4179 4180; Don't crash by assuming the compared values are integers. 4181define <2 x i1> @PR36583(<2 x ptr>) { 4182; CHECK-LABEL: @PR36583( 4183; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x ptr> [[TMP0:%.*]], zeroinitializer 4184; CHECK-NEXT: ret <2 x i1> [[RES]] 4185; 4186 %cast = ptrtoint <2 x ptr> %0 to <2 x i64> 4187 %res = icmp eq <2 x i64> %cast, zeroinitializer 4188 ret <2 x i1> %res 4189} 4190 4191; fold (icmp pred (sub (0, X)) C1) for vec type 4192define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) { 4193; CHECK-LABEL: @Op1Negated_Vec( 4194; CHECK-NEXT: [[COND:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[X:%.*]], i1 true) 4195; CHECK-NEXT: ret <2 x i32> [[COND]] 4196; 4197 %sub = sub nsw <2 x i32> zeroinitializer, %x 4198 %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1> 4199 %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x 4200 ret <2 x i32> %cond 4201} 4202 4203define i1 @signbit_bitcast_fpext(float %x) { 4204; CHECK-LABEL: @signbit_bitcast_fpext( 4205; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32 4206; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 4207; CHECK-NEXT: ret i1 [[R]] 4208; 4209 %f = fpext float %x to double 4210 %b = bitcast double %f to i64 4211 %r = icmp slt i64 %b, 0 4212 ret i1 %r 4213} 4214 4215define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) { 4216; CHECK-LABEL: @signbit_bitcast_fpext_vec( 4217; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x half> [[X:%.*]] to <2 x i16> 4218; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer 4219; CHECK-NEXT: ret <2 x i1> [[R]] 4220; 4221 %f = fpext <2 x half> %x to <2 x float> 4222 %b = bitcast <2 x float> %f to <2 x i32> 4223 %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647> 4224 ret <2 x i1> %r 4225} 4226 4227define i1 @signbit_bitcast_fptrunc(float %x) { 4228; CHECK-LABEL: @signbit_bitcast_fptrunc( 4229; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32 4230; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 4231; CHECK-NEXT: ret i1 [[R]] 4232; 4233 %f = fptrunc float %x to half 4234 %b = bitcast half %f to i16 4235 %r = icmp ult i16 %b, 32768 4236 ret i1 %r 4237} 4238 4239define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) { 4240; CHECK-LABEL: @signbit_bitcast_fptrunc_vec( 4241; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64> 4242; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], splat (i64 -1) 4243; CHECK-NEXT: ret <2 x i1> [[R]] 4244; 4245 %f = fptrunc <2 x double> %x to <2 x half> 4246 %b = bitcast <2 x half> %f to <2 x i16> 4247 %r = icmp sge <2 x i16> %b, zeroinitializer 4248 ret <2 x i1> %r 4249} 4250 4251define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) { 4252; CHECK-LABEL: @signbit_bitcast_fpext_wrong_cmp( 4253; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double 4254; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 4255; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 1 4256; CHECK-NEXT: ret i1 [[R]] 4257; 4258 %f = fpext float %x to double 4259 %b = bitcast double %f to i64 4260 %r = icmp slt i64 %b, 1 4261 ret i1 %r 4262} 4263 4264define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) { 4265; CHECK-LABEL: @signbit_bitcast_fpext_vec_wrong_bitcast( 4266; CHECK-NEXT: [[F:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x float> 4267; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16> 4268; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i16> [[B]], splat (i16 -1) 4269; CHECK-NEXT: ret <4 x i1> [[R]] 4270; 4271 %f = fpext <2 x half> %x to <2 x float> 4272 %b = bitcast <2 x float> %f to <4 x i16> 4273 %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1> 4274 ret <4 x i1> %r 4275} 4276 4277define i1 @signbit_bitcast_fpext_extra_use(float %x, ptr %p) { 4278; CHECK-LABEL: @signbit_bitcast_fpext_extra_use( 4279; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double 4280; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64 4281; CHECK-NEXT: call void @use_i64(i64 [[B]]) 4282; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 0 4283; CHECK-NEXT: ret i1 [[R]] 4284; 4285 %f = fpext float %x to double 4286 %b = bitcast double %f to i64 4287 call void @use_i64(i64 %b) 4288 %r = icmp slt i64 %b, 0 4289 ret i1 %r 4290} 4291 4292define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) { 4293; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128( 4294; CHECK-NEXT: [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128 4295; CHECK-NEXT: [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128 4296; CHECK-NEXT: [[S4:%.*]] = icmp slt i128 [[S3]], 0 4297; CHECK-NEXT: ret i1 [[S4]] 4298; 4299 %s2 = fpext float %x to ppc_fp128 4300 %s3 = bitcast ppc_fp128 %s2 to i128 4301 %s4 = icmp slt i128 %s3, 0 4302 ret i1 %s4 4303} 4304 4305define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) { 4306; CHECK-LABEL: @signbit_bitcast_fptrunc_ppc_fp128( 4307; CHECK-NEXT: [[S2:%.*]] = fptrunc ppc_fp128 [[X:%.*]] to float 4308; CHECK-NEXT: [[S3:%.*]] = bitcast float [[S2]] to i32 4309; CHECK-NEXT: [[S4:%.*]] = icmp slt i32 [[S3]], 0 4310; CHECK-NEXT: ret i1 [[S4]] 4311; 4312 %s2 = fptrunc ppc_fp128 %x to float 4313 %s3 = bitcast float %s2 to i32 4314 %s4 = icmp slt i32 %s3, 0 4315 ret i1 %s4 4316} 4317 4318@x = external dso_local local_unnamed_addr global i32, align 4 4319@y = external dso_local local_unnamed_addr global i32, align 4 4320define i1 @pr47997(i32 %arg) { 4321; CHECK-LABEL: @pr47997( 4322; CHECK-NEXT: bb: 4323; CHECK-NEXT: [[I:%.*]] = add nsw i32 [[ARG:%.*]], -1 4324; CHECK-NEXT: store i32 [[I]], ptr @x, align 4 4325; CHECK-NEXT: [[I1:%.*]] = sub nsw i32 1, [[ARG]] 4326; CHECK-NEXT: store i32 [[I1]], ptr @y, align 4 4327; CHECK-NEXT: ret i1 true 4328; 4329bb: 4330 %i = add nsw i32 %arg, -1 4331 store i32 %i, ptr @x 4332 %i1 = sub nsw i32 1, %arg 4333 store i32 %i1, ptr @y 4334 %i2 = sub nsw i32 0, %i1 4335 %i3 = icmp eq i32 %i, %i2 4336 ret i1 %i3 4337} 4338 4339; PR50944 4340 4341define i1 @thread_cmp_over_select_with_poison_trueval(i1 %b) { 4342; CHECK-LABEL: @thread_cmp_over_select_with_poison_trueval( 4343; CHECK-NEXT: ret i1 false 4344; 4345 %s = select i1 %b, i32 poison, i32 0 4346 %tobool = icmp ne i32 %s, 0 4347 ret i1 %tobool 4348} 4349 4350define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) { 4351; CHECK-LABEL: @thread_cmp_over_select_with_poison_falseval( 4352; CHECK-NEXT: ret i1 true 4353; 4354 %s = select i1 %b, i32 1, i32 poison 4355 %tobool = icmp ne i32 %s, 0 4356 ret i1 %tobool 4357} 4358 4359define i1 @signbit_true_logic(i8 %x) { 4360; CHECK-LABEL: @signbit_true_logic( 4361; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 0 4362; CHECK-NEXT: ret i1 [[R]] 4363; 4364 %dec = add i8 %x, -1 4365 %not = xor i8 %x, -1 4366 %and = and i8 %dec, %not 4367 %r = icmp slt i8 %and, 0 4368 ret i1 %r 4369} 4370 4371define <2 x i1> @signbit_false_logic(<2 x i5> %x) { 4372; CHECK-LABEL: @signbit_false_logic( 4373; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], zeroinitializer 4374; CHECK-NEXT: ret <2 x i1> [[R]] 4375; 4376 %dec = add <2 x i5> %x, <i5 -1, i5 poison> 4377 %not = xor <2 x i5> %x, <i5 -1, i5 -1> 4378 %and = and <2 x i5> %dec, %not 4379 %r = icmp sgt <2 x i5> %and, <i5 -1, i5 -1> 4380 ret <2 x i1> %r 4381} 4382 4383; Confirm that complexity canonicalization works for commuted pattern. 4384 4385define i1 @signbit_true_logic_uses_commute(i64 %x) { 4386; CHECK-LABEL: @signbit_true_logic_uses_commute( 4387; CHECK-NEXT: [[DEC:%.*]] = add i64 [[X:%.*]], -1 4388; CHECK-NEXT: call void @use_i64(i64 [[DEC]]) 4389; CHECK-NEXT: [[NOT:%.*]] = xor i64 [[X]], -1 4390; CHECK-NEXT: call void @use_i64(i64 [[NOT]]) 4391; CHECK-NEXT: [[AND:%.*]] = and i64 [[DEC]], [[NOT]] 4392; CHECK-NEXT: call void @use_i64(i64 [[AND]]) 4393; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[X]], 0 4394; CHECK-NEXT: ret i1 [[R]] 4395; 4396 %dec = add i64 %x, -1 4397 call void @use_i64(i64 %dec) 4398 %not = xor i64 %x, -1 4399 call void @use_i64(i64 %not) 4400 %and = and i64 %not, %dec 4401 call void @use_i64(i64 %and) 4402 %r = icmp slt i64 %and, 0 4403 ret i1 %r 4404} 4405 4406define i1 @redundant_sign_bit_count_ult_1_2(i32 %x) { 4407; CHECK-LABEL: @redundant_sign_bit_count_ult_1_2( 4408; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 4 4409; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 8 4410; CHECK-NEXT: ret i1 [[C]] 4411; 4412 %y = ashr i32 %x, 1 4413 %z = xor i32 %y, %x 4414 %c = icmp ult i32 %z, 4 4415 ret i1 %c 4416} 4417 4418define i1 @redundant_sign_bit_count_ult_1_30(i32 %x) { 4419; CHECK-LABEL: @redundant_sign_bit_count_ult_1_30( 4420; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824 4421; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -1 4422; CHECK-NEXT: ret i1 [[C]] 4423; 4424 %y = ashr i32 %x, 1 4425 %z = xor i32 %y, %x 4426 %c = icmp ult i32 %z, 1073741824 4427 ret i1 %c 4428} 4429 4430define i1 @redundant_sign_bit_count_ult_31_2(i32 %x) { 4431; CHECK-LABEL: @redundant_sign_bit_count_ult_31_2( 4432; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 4 4433; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 8 4434; CHECK-NEXT: ret i1 [[C]] 4435; 4436 %y = ashr i32 %x, 31 4437 %z = xor i32 %y, %x 4438 %c = icmp ult i32 %z, 4 4439 ret i1 %c 4440} 4441 4442define i1 @redundant_sign_bit_count_ult_31_30(i32 %x) { 4443; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30( 4444; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824 4445; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -1 4446; CHECK-NEXT: ret i1 [[C]] 4447; 4448 %y = ashr i32 %x, 31 4449 %z = xor i32 %y, %x 4450 %c = icmp ult i32 %z, 1073741824 4451 ret i1 %c 4452} 4453 4454define i1 @redundant_sign_bit_count_ult_31_30_extra_use_ashr(i32 %x) { 4455; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_extra_use_ashr( 4456; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X:%.*]], 31 4457; CHECK-NEXT: call void @use_i32(i32 [[Y]]) 4458; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 1073741824 4459; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -1 4460; CHECK-NEXT: ret i1 [[C]] 4461; 4462 %y = ashr i32 %x, 31 4463 call void @use_i32(i32 %y) 4464 %z = xor i32 %y, %x 4465 %c = icmp ult i32 %z, 1073741824 4466 ret i1 %c 4467} 4468 4469define i1 @redundant_sign_bit_count_ult_31_30_extra_use_xor(i32 %x) { 4470; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_extra_use_xor( 4471; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X:%.*]], 31 4472; CHECK-NEXT: [[Z:%.*]] = xor i32 [[Y]], [[X]] 4473; CHECK-NEXT: call void @use_i32(i32 [[Z]]) 4474; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[Z]], 1073741824 4475; CHECK-NEXT: ret i1 [[C]] 4476; 4477 %y = ashr i32 %x, 31 4478 %z = xor i32 %y, %x 4479 call void @use_i32(i32 %z) 4480 %c = icmp ult i32 %z, 1073741824 4481 ret i1 %c 4482} 4483 4484define i1 @not_redundant_sign_bit_count_ult(i32 %w, i32 %x) { 4485; CHECK-LABEL: @not_redundant_sign_bit_count_ult( 4486; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X:%.*]], 31 4487; CHECK-NEXT: [[Z:%.*]] = xor i32 [[Y]], [[W:%.*]] 4488; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[Z]], 1073741824 4489; CHECK-NEXT: ret i1 [[C]] 4490; 4491 %y = ashr i32 %x, 31 4492 %z = xor i32 %y, %w 4493 %c = icmp ult i32 %z, 1073741824 4494 ret i1 %c 4495} 4496 4497define i1 @wrong_shift_opcode_i8(i8 %x) { 4498; CHECK-LABEL: @wrong_shift_opcode_i8( 4499; CHECK-NEXT: [[Y:%.*]] = lshr i8 [[X:%.*]], 5 4500; CHECK-NEXT: [[Z:%.*]] = xor i8 [[Y]], [[X]] 4501; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[Z]], 2 4502; CHECK-NEXT: ret i1 [[C]] 4503; 4504 %y = lshr i8 %x, 5 4505 %z = xor i8 %y, %x 4506 %c = icmp ult i8 %z, 2 4507 ret i1 %c 4508} 4509 4510define i1 @redundant_sign_bit_count_ult_31_30_commute(i32 %xsrc) { 4511; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_commute( 4512; CHECK-NEXT: [[X:%.*]] = mul i32 [[XSRC:%.*]], 13 4513; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 1073741824 4514; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -1 4515; CHECK-NEXT: ret i1 [[C]] 4516; 4517 %x = mul i32 %xsrc, 13 ; thwart complexity-based canonicalization 4518 %y = ashr i32 %x, 31 4519 %z = xor i32 %x, %y 4520 %c = icmp ult i32 %z, 1073741824 4521 ret i1 %c 4522} 4523 4524define i1 @redundant_sign_bit_count_i8(i8 %x) { 4525; CHECK-LABEL: @redundant_sign_bit_count_i8( 4526; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 2 4527; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[TMP1]], 4 4528; CHECK-NEXT: ret i1 [[C]] 4529; 4530 %y = ashr i8 %x, 5 4531 %z = xor i8 %y, %x 4532 %c = icmp ult i8 %z, 2 4533 ret i1 %c 4534} 4535 4536define <2 x i1> @redundant_sign_bit_count_ult_31_30_vector(<2 x i32> %xsrc) { 4537; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_vector( 4538; CHECK-NEXT: [[X:%.*]] = mul <2 x i32> [[XSRC:%.*]], splat (i32 13) 4539; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X]], splat (i32 1073741824) 4540; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i32> [[TMP1]], splat (i32 -1) 4541; CHECK-NEXT: ret <2 x i1> [[C]] 4542; 4543 %x = mul <2 x i32> %xsrc, <i32 13, i32 13> ; thwart complexity-based canonicalization 4544 %y = ashr <2 x i32> %x, <i32 31, i32 31> 4545 %z = xor <2 x i32> %x, %y 4546 %c = icmp ult <2 x i32> %z, <i32 1073741824, i32 1073741824> 4547 ret <2 x i1> %c 4548} 4549 4550define i1 @redundant_sign_bit_count_ugt_1_2(i32 %x) { 4551; CHECK-LABEL: @redundant_sign_bit_count_ugt_1_2( 4552; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -4 4553; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -8 4554; CHECK-NEXT: ret i1 [[C]] 4555; 4556 %y = ashr i32 %x, 1 4557 %z = xor i32 %y, %x 4558 %c = icmp ugt i32 %z, 3 4559 ret i1 %c 4560} 4561 4562define i1 @redundant_sign_bit_count_ugt_1_30(i32 %x) { 4563; CHECK-LABEL: @redundant_sign_bit_count_ugt_1_30( 4564; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824 4565; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 0 4566; CHECK-NEXT: ret i1 [[C]] 4567; 4568 %y = ashr i32 %x, 1 4569 %z = xor i32 %y, %x 4570 %c = icmp ugt i32 %z, 1073741823 4571 ret i1 %c 4572} 4573 4574define i1 @redundant_sign_bit_count_ugt_31_2(i32 %x) { 4575; CHECK-LABEL: @redundant_sign_bit_count_ugt_31_2( 4576; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -4 4577; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -8 4578; CHECK-NEXT: ret i1 [[C]] 4579; 4580 %y = ashr i32 %x, 31 4581 %z = xor i32 %y, %x 4582 %c = icmp ugt i32 %z, 3 4583 ret i1 %c 4584} 4585 4586define i1 @redundant_sign_bit_count_ugt_31_30(i32 %x) { 4587; CHECK-LABEL: @redundant_sign_bit_count_ugt_31_30( 4588; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824 4589; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 0 4590; CHECK-NEXT: ret i1 [[C]] 4591; 4592 %y = ashr i32 %x, 31 4593 %z = xor i32 %y, %x 4594 %c = icmp ugt i32 %z, 1073741823 4595 ret i1 %c 4596} 4597 4598define i1 @zext_bool_and_eq0(i1 %x, i8 %y) { 4599; CHECK-LABEL: @zext_bool_and_eq0( 4600; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 1 4601; CHECK-NEXT: [[R1:%.*]] = icmp eq i8 [[TMP1]], 0 4602; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true 4603; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]] 4604; CHECK-NEXT: ret i1 [[R]] 4605; 4606 %zx = zext i1 %x to i8 4607 %a = and i8 %zx, %y 4608 %r = icmp eq i8 %a, 0 4609 ret i1 %r 4610} 4611 4612define <2 x i1> @zext_bool_and_eq0_commute(<2 x i1> %x, <2 x i8> %p) { 4613; CHECK-LABEL: @zext_bool_and_eq0_commute( 4614; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[P:%.*]], splat (i8 1) 4615; CHECK-NEXT: [[R1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer 4616; CHECK-NEXT: [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true) 4617; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT_X]], <2 x i1> splat (i1 true), <2 x i1> [[R1]] 4618; CHECK-NEXT: ret <2 x i1> [[R]] 4619; 4620 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization 4621 %zx = zext <2 x i1> %x to <2 x i8> 4622 %a = and <2 x i8> %y, %zx 4623 %r = icmp eq <2 x i8> %a, zeroinitializer 4624 ret <2 x i1> %r 4625} 4626 4627define i1 @zext_bool_and_ne0(i1 %x, i8 %y) { 4628; CHECK-LABEL: @zext_bool_and_ne0( 4629; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 1 4630; CHECK-NEXT: [[R1:%.*]] = icmp ne i8 [[TMP1]], 0 4631; CHECK-NEXT: [[R:%.*]] = select i1 [[X:%.*]], i1 [[R1]], i1 false 4632; CHECK-NEXT: ret i1 [[R]] 4633; 4634 %zx = zext i1 %x to i8 4635 %a = and i8 %zx, %y 4636 %r = icmp ne i8 %a, 0 4637 ret i1 %r 4638} 4639 4640define i1 @zext_bool_and_ne1(i1 %x, i8 %y) { 4641; CHECK-LABEL: @zext_bool_and_ne1( 4642; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 1 4643; CHECK-NEXT: [[R1:%.*]] = icmp eq i8 [[TMP1]], 0 4644; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true 4645; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]] 4646; CHECK-NEXT: ret i1 [[R]] 4647; 4648 %zx = zext i1 %x to i8 4649 %a = and i8 %zx, %y 4650 %r = icmp ne i8 %a, 1 4651 ret i1 %r 4652} 4653 4654define <2 x i1> @zext_bool_and_eq1(<2 x i1> %x, <2 x i8> %y) { 4655; CHECK-LABEL: @zext_bool_and_eq1( 4656; CHECK-NEXT: [[R1:%.*]] = trunc <2 x i8> [[Y:%.*]] to <2 x i1> 4657; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[R1]], <2 x i1> zeroinitializer 4658; CHECK-NEXT: ret <2 x i1> [[R]] 4659; 4660 %zx = zext <2 x i1> %x to <2 x i8> 4661 %a = and <2 x i8> %zx, %y 4662 %r = icmp eq <2 x i8> %a, <i8 1, i8 1> 4663 ret <2 x i1> %r 4664} 4665 4666; negative test - wrong logic op 4667 4668define i1 @zext_bool_or_eq0(i1 %x, i8 %y) { 4669; CHECK-LABEL: @zext_bool_or_eq0( 4670; CHECK-NEXT: [[ZX:%.*]] = zext i1 [[X:%.*]] to i8 4671; CHECK-NEXT: [[A:%.*]] = or i8 [[Y:%.*]], [[ZX]] 4672; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[A]], 0 4673; CHECK-NEXT: ret i1 [[R]] 4674; 4675 %zx = zext i1 %x to i8 4676 %a = or i8 %zx, %y 4677 %r = icmp eq i8 %a, 0 4678 ret i1 %r 4679} 4680 4681; negative test - extra use 4682 4683define i1 @zext_bool_and_eq0_use(i1 %x, i64 %y) { 4684; CHECK-LABEL: @zext_bool_and_eq0_use( 4685; CHECK-NEXT: [[ZX:%.*]] = zext i1 [[X:%.*]] to i64 4686; CHECK-NEXT: call void @use_i64(i64 [[ZX]]) 4687; CHECK-NEXT: [[A:%.*]] = and i64 [[Y:%.*]], [[ZX]] 4688; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[A]], 0 4689; CHECK-NEXT: ret i1 [[R]] 4690; 4691 %zx = zext i1 %x to i64 4692 call void @use_i64(i64 %zx) 4693 %a = and i64 %zx, %y 4694 %r = icmp eq i64 %a, 0 4695 ret i1 %r 4696} 4697 4698; negative test - extra use 4699 4700define i1 @zext_bool_and_ne0_use(i1 %x, i64 %y) { 4701; CHECK-LABEL: @zext_bool_and_ne0_use( 4702; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[Y:%.*]], 1 4703; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i64 [[TMP1]], i64 0 4704; CHECK-NEXT: call void @use_i64(i64 [[A]]) 4705; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[A]], 0 4706; CHECK-NEXT: ret i1 [[R]] 4707; 4708 %zx = zext i1 %x to i64 4709 %a = and i64 %zx, %y 4710 call void @use_i64(i64 %a) 4711 %r = icmp ne i64 %a, 0 4712 ret i1 %r 4713} 4714 4715; negative test - must zext from i1 4716 4717define i1 @zext_notbool_and_ne0(i2 %x, i8 %y) { 4718; CHECK-LABEL: @zext_notbool_and_ne0( 4719; CHECK-NEXT: [[ZX:%.*]] = zext i2 [[X:%.*]] to i8 4720; CHECK-NEXT: [[A:%.*]] = and i8 [[Y:%.*]], [[ZX]] 4721; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[A]], 0 4722; CHECK-NEXT: ret i1 [[R]] 4723; 4724 %zx = zext i2 %x to i8 4725 %a = and i8 %zx, %y 4726 %r = icmp ne i8 %a, 0 4727 ret i1 %r 4728} 4729 4730; fold icmp(X | OrC, C) --> icmp(X, 0) 4731 4732define i1 @or_positive_sgt_zero(i8 %a) { 4733; CHECK-LABEL: @or_positive_sgt_zero( 4734; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1 4735; CHECK-NEXT: ret i1 [[CMP]] 4736; 4737 %b = or i8 %a, 24 4738 %cmp = icmp sgt i8 %b, 0 4739 ret i1 %cmp 4740} 4741 4742define <2 x i1> @or_postive_sgt_zero_vec(<2 x i8> %a) { 4743; CHECK-LABEL: @or_postive_sgt_zero_vec( 4744; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1) 4745; CHECK-NEXT: ret <2 x i1> [[CMP]] 4746; 4747 4748 %b = or <2 x i8> %a, <i8 24, i8 24> 4749 %cmp = icmp sgt <2 x i8> %b, <i8 0, i8 0> 4750 ret <2 x i1> %cmp 4751} 4752 4753define <2 x i1> @or_poison_vec_sgt_zero_vec(<2 x i8> %a) { 4754; CHECK-LABEL: @or_poison_vec_sgt_zero_vec( 4755; CHECK-NEXT: ret <2 x i1> poison 4756; 4757 4758 %b = or <2 x i8> %a, <i8 poison, i8 poison> 4759 %cmp = icmp sgt <2 x i8> %b, <i8 0, i8 0> 4760 ret <2 x i1> %cmp 4761} 4762 4763define i1 @or_positive_sge_zero(i8 %a) { 4764; CHECK-LABEL: @or_positive_sge_zero( 4765; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1 4766; CHECK-NEXT: ret i1 [[CMP]] 4767; 4768 %b = or i8 %a, 24 4769 %cmp = icmp sge i8 %b, 0 4770 ret i1 %cmp 4771} 4772 4773define <2 x i1> @or_postive_sge_zero_vec(<2 x i8> %a) { 4774; CHECK-LABEL: @or_postive_sge_zero_vec( 4775; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1) 4776; CHECK-NEXT: ret <2 x i1> [[CMP]] 4777; 4778 4779 %b = or <2 x i8> %a, <i8 24, i8 24> 4780 %cmp = icmp sge <2 x i8> %b, <i8 0, i8 0> 4781 ret <2 x i1> %cmp 4782} 4783 4784define <2 x i1> @or_poison_vec_sge_zero_vec(<2 x i8> %a) { 4785; CHECK-LABEL: @or_poison_vec_sge_zero_vec( 4786; CHECK-NEXT: ret <2 x i1> poison 4787; 4788 4789 %b = or <2 x i8> %a, <i8 poison, i8 poison> 4790 %cmp = icmp sge <2 x i8> %b, <i8 0, i8 0> 4791 ret <2 x i1> %cmp 4792} 4793 4794define i1 @or_positive_sge_postive(i8 %a) { 4795; CHECK-LABEL: @or_positive_sge_postive( 4796; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1 4797; CHECK-NEXT: ret i1 [[CMP]] 4798; 4799 %b = or i8 %a, 24 4800 %cmp = icmp sge i8 %b, 24 4801 ret i1 %cmp 4802} 4803 4804define <2 x i1> @or_postive_sge_positive_vec(<2 x i8> %a) { 4805; CHECK-LABEL: @or_postive_sge_positive_vec( 4806; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1) 4807; CHECK-NEXT: ret <2 x i1> [[CMP]] 4808; 4809 4810 %b = or <2 x i8> %a, <i8 24, i8 24> 4811 %cmp = icmp sge <2 x i8> %b, <i8 24, i8 24> 4812 ret <2 x i1> %cmp 4813} 4814 4815define <2 x i1> @or_poison_vec_sge_positive_vec(<2 x i8> %a) { 4816; CHECK-LABEL: @or_poison_vec_sge_positive_vec( 4817; CHECK-NEXT: ret <2 x i1> poison 4818; 4819 4820 %b = or <2 x i8> %a, <i8 poison, i8 poison> 4821 %cmp = icmp sge <2 x i8> %b, <i8 24, i8 24> 4822 ret <2 x i1> %cmp 4823} 4824 4825define i1 @or_positive_sle_zero(i8 %a) { 4826; CHECK-LABEL: @or_positive_sle_zero( 4827; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0 4828; CHECK-NEXT: ret i1 [[CMP]] 4829; 4830 %b = or i8 %a, 24 4831 %cmp = icmp sle i8 %b, 0 4832 ret i1 %cmp 4833} 4834 4835define <2 x i1> @or_postive_sle_zero_vec(<2 x i8> %a) { 4836; CHECK-LABEL: @or_postive_sle_zero_vec( 4837; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer 4838; CHECK-NEXT: ret <2 x i1> [[CMP]] 4839; 4840 4841 %b = or <2 x i8> %a, <i8 24, i8 24> 4842 %cmp = icmp sle <2 x i8> %b, <i8 0, i8 0> 4843 ret <2 x i1> %cmp 4844} 4845 4846define <2 x i1> @or_poison_vec_sle_zero_vec(<2 x i8> %a) { 4847; CHECK-LABEL: @or_poison_vec_sle_zero_vec( 4848; CHECK-NEXT: ret <2 x i1> poison 4849; 4850 4851 %b = or <2 x i8> %a, <i8 poison, i8 poison> 4852 %cmp = icmp sle <2 x i8> %b, <i8 0, i8 0> 4853 ret <2 x i1> %cmp 4854} 4855 4856define i1 @or_positive_slt_zero(i8 %a) { 4857; CHECK-LABEL: @or_positive_slt_zero( 4858; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0 4859; CHECK-NEXT: ret i1 [[CMP]] 4860; 4861 %b = or i8 %a, 24 4862 %cmp = icmp slt i8 %b, 0 4863 ret i1 %cmp 4864} 4865 4866define <2 x i1> @or_postive_slt_zero_vec(<2 x i8> %a) { 4867; CHECK-LABEL: @or_postive_slt_zero_vec( 4868; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer 4869; CHECK-NEXT: ret <2 x i1> [[CMP]] 4870; 4871 4872 %b = or <2 x i8> %a, <i8 24, i8 24> 4873 %cmp = icmp slt <2 x i8> %b, <i8 0, i8 0> 4874 ret <2 x i1> %cmp 4875} 4876 4877define <2 x i1> @or_poison_vec_slt_zero_vec(<2 x i8> %a) { 4878; CHECK-LABEL: @or_poison_vec_slt_zero_vec( 4879; CHECK-NEXT: ret <2 x i1> poison 4880; 4881 4882 %b = or <2 x i8> %a, <i8 poison, i8 poison> 4883 %cmp = icmp slt <2 x i8> %b, <i8 0, i8 0> 4884 ret <2 x i1> %cmp 4885} 4886 4887define i1 @or_positive_slt_postive(i8 %a) { 4888; CHECK-LABEL: @or_positive_slt_postive( 4889; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0 4890; CHECK-NEXT: ret i1 [[CMP]] 4891; 4892 %b = or i8 %a, 24 4893 %cmp = icmp slt i8 %b, 24 4894 ret i1 %cmp 4895} 4896 4897define <2 x i1> @or_postive_slt_positive_vec(<2 x i8> %a) { 4898; CHECK-LABEL: @or_postive_slt_positive_vec( 4899; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer 4900; CHECK-NEXT: ret <2 x i1> [[CMP]] 4901; 4902 4903 %b = or <2 x i8> %a, <i8 24, i8 24> 4904 %cmp = icmp slt <2 x i8> %b, <i8 24, i8 24> 4905 ret <2 x i1> %cmp 4906} 4907 4908define <2 x i1> @or_poison_vec_slt_positive_vec(<2 x i8> %a) { 4909; CHECK-LABEL: @or_poison_vec_slt_positive_vec( 4910; CHECK-NEXT: ret <2 x i1> poison 4911; 4912 4913 %b = or <2 x i8> %a, <i8 poison, i8 poison> 4914 %cmp = icmp slt <2 x i8> %b, <i8 24, i8 24> 4915 ret <2 x i1> %cmp 4916} 4917 4918; negative tests for icmp(X | OrC, C) --> icmp(X, 0) 4919 4920define i1 @or_positive_sgt_neg(i8 %a) { 4921; CHECK-LABEL: @or_positive_sgt_neg( 4922; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1 4923; CHECK-NEXT: ret i1 [[CMP]] 4924; 4925 %b = or i8 %a, 24 4926 %cmp = icmp sgt i8 %b, -1 4927 ret i1 %cmp 4928} 4929 4930define <2 x i1> @or_postive_sgt_neg_vec(<2 x i8> %a) { 4931; CHECK-LABEL: @or_postive_sgt_neg_vec( 4932; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1) 4933; CHECK-NEXT: ret <2 x i1> [[CMP]] 4934; 4935 4936 %b = or <2 x i8> %a, <i8 24, i8 24> 4937 %cmp = icmp sgt <2 x i8> %b, <i8 -1, i8 -1> 4938 ret <2 x i1> %cmp 4939} 4940 4941define i1 @mul_or_positive_sge_neg(i8 %a) { 4942; CHECK-LABEL: @mul_or_positive_sge_neg( 4943; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24 4944; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], -2 4945; CHECK-NEXT: ret i1 [[CMP]] 4946; 4947 %b = or i8 %a, 24 4948 %cmp = icmp sge i8 %b, -1 4949 ret i1 %cmp 4950} 4951 4952define <2 x i1> @or_postive_sge_neg_vec(<2 x i8> %a) { 4953; CHECK-LABEL: @or_postive_sge_neg_vec( 4954; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24) 4955; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], splat (i8 -2) 4956; CHECK-NEXT: ret <2 x i1> [[CMP]] 4957; 4958 4959 %b = or <2 x i8> %a, <i8 24, i8 24> 4960 %cmp = icmp sge <2 x i8> %b, <i8 -1, i8 -1> 4961 ret <2 x i1> %cmp 4962} 4963 4964define i1 @mul_or_small_sge_large(i8 %a) { 4965; CHECK-LABEL: @mul_or_small_sge_large( 4966; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24 4967; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 24 4968; CHECK-NEXT: ret i1 [[CMP]] 4969; 4970 %b = or i8 %a, 24 4971 %cmp = icmp sge i8 %b, 25 4972 ret i1 %cmp 4973} 4974 4975define <2 x i1> @or_small_sge_large_vec(<2 x i8> %a) { 4976; CHECK-LABEL: @or_small_sge_large_vec( 4977; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24) 4978; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], splat (i8 24) 4979; CHECK-NEXT: ret <2 x i1> [[CMP]] 4980; 4981 4982 %b = or <2 x i8> %a, <i8 24, i8 24> 4983 %cmp = icmp sge <2 x i8> %b, <i8 25, i8 25> 4984 ret <2 x i1> %cmp 4985} 4986 4987define i1 @or_positive_sle_neg(i8 %a) { 4988; CHECK-LABEL: @or_positive_sle_neg( 4989; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0 4990; CHECK-NEXT: ret i1 [[CMP]] 4991; 4992 %b = or i8 %a, 24 4993 %cmp = icmp sle i8 %b, -1 4994 ret i1 %cmp 4995} 4996 4997define <2 x i1> @or_sle_neg_vec(<2 x i8> %a) { 4998; CHECK-LABEL: @or_sle_neg_vec( 4999; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer 5000; CHECK-NEXT: ret <2 x i1> [[CMP]] 5001; 5002 5003 %b = or <2 x i8> %a, <i8 24, i8 24> 5004 %cmp = icmp sle <2 x i8> %b, <i8 -1, i8 -1> 5005 ret <2 x i1> %cmp 5006} 5007 5008define i1 @or_positive_slt_neg(i8 %a) { 5009; CHECK-LABEL: @or_positive_slt_neg( 5010; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24 5011; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], -1 5012; CHECK-NEXT: ret i1 [[CMP]] 5013; 5014 %b = or i8 %a, 24 5015 %cmp = icmp slt i8 %b, -1 5016 ret i1 %cmp 5017} 5018 5019define <2 x i1> @or_postive_slt_neg_vec(<2 x i8> %a) { 5020; CHECK-LABEL: @or_postive_slt_neg_vec( 5021; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24) 5022; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], splat (i8 -1) 5023; CHECK-NEXT: ret <2 x i1> [[CMP]] 5024; 5025 5026 %b = or <2 x i8> %a, <i8 24, i8 24> 5027 %cmp = icmp slt <2 x i8> %b, <i8 -1, i8 -1> 5028 ret <2 x i1> %cmp 5029} 5030 5031define i1 @or_small_slt_large(i8 %a) { 5032; CHECK-LABEL: @or_small_slt_large( 5033; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24 5034; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], 25 5035; CHECK-NEXT: ret i1 [[CMP]] 5036; 5037 %b = or i8 %a, 24 5038 %cmp = icmp slt i8 %b, 25 5039 ret i1 %cmp 5040} 5041 5042define <2 x i1> @or_small_slt_large_vec(<2 x i8> %a) { 5043; CHECK-LABEL: @or_small_slt_large_vec( 5044; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24) 5045; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], splat (i8 25) 5046; CHECK-NEXT: ret <2 x i1> [[CMP]] 5047; 5048 5049 %b = or <2 x i8> %a, <i8 24, i8 24> 5050 %cmp = icmp slt <2 x i8> %b, <i8 25, i8 25> 5051 ret <2 x i1> %cmp 5052} 5053 5054define i1 @or_positive_sgt_zero_multi_use(i8 %a) { 5055; CHECK-LABEL: @or_positive_sgt_zero_multi_use( 5056; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24 5057; CHECK-NEXT: call void @use_i8(i8 [[B]]) 5058; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -1 5059; CHECK-NEXT: ret i1 [[CMP]] 5060; 5061 %b = or i8 %a, 24 5062 call void @use_i8(i8 %b) 5063 %cmp = icmp sgt i8 %b, 0 5064 ret i1 %cmp 5065} 5066 5067 5068define i1 @disjoint_or_sgt_1(i8 %a, i8 %b) { 5069; CHECK-LABEL: @disjoint_or_sgt_1( 5070; CHECK-NEXT: [[B1:%.*]] = add nsw i8 [[B:%.*]], 2 5071; CHECK-NEXT: [[ICMP_:%.*]] = icmp sge i8 [[A:%.*]], [[B1]] 5072; CHECK-NEXT: ret i1 [[ICMP_]] 5073; 5074 %a1 = or disjoint i8 %a, 1 5075 %b1 = add nsw i8 %b, 2 5076 %icmp_ = icmp sgt i8 %a1, %b1 5077 ret i1 %icmp_ 5078} 5079 5080define i1 @disjoint_or_sgt_2(i8 %a, i8 %b) { 5081; CHECK-LABEL: @disjoint_or_sgt_2( 5082; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2 5083; CHECK-NEXT: [[B1:%.*]] = add i8 [[B:%.*]], 1 5084; CHECK-NEXT: [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]] 5085; CHECK-NEXT: ret i1 [[ICMP_]] 5086; 5087 %a1 = or disjoint i8 %a, 2 5088 %b1 = add i8 %b, 1 5089 %icmp_ = icmp sgt i8 %a1, %b1 5090 ret i1 %icmp_ 5091} 5092 5093define i1 @disjoint_or_sgt_3(i8 %a, i8 %b) { 5094; CHECK-LABEL: @disjoint_or_sgt_3( 5095; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2 5096; CHECK-NEXT: [[B1:%.*]] = add nuw i8 [[B:%.*]], 1 5097; CHECK-NEXT: [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]] 5098; CHECK-NEXT: ret i1 [[ICMP_]] 5099; 5100 %a1 = or disjoint i8 %a, 2 5101 %b1 = add nuw i8 %b, 1 5102 %icmp_ = icmp sgt i8 %a1, %b1 5103 ret i1 %icmp_ 5104} 5105 5106define i1 @disjoint_or_ugt_1(i8 %a, i8 %b) { 5107; CHECK-LABEL: @disjoint_or_ugt_1( 5108; CHECK-NEXT: [[B1:%.*]] = add nsw i8 [[B:%.*]], 2 5109; CHECK-NEXT: [[ICMP_:%.*]] = icmp uge i8 [[A:%.*]], [[B1]] 5110; CHECK-NEXT: ret i1 [[ICMP_]] 5111; 5112 %a1 = or disjoint i8 %a, 1 5113 %b1 = add nsw i8 %b, 2 5114 %icmp_ = icmp ugt i8 %a1, %b1 5115 ret i1 %icmp_ 5116} 5117 5118define i1 @disjoint_or_ugt_2(i8 %a, i8 %b) { 5119; CHECK-LABEL: @disjoint_or_ugt_2( 5120; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2 5121; CHECK-NEXT: [[B1:%.*]] = add i8 [[B:%.*]], 1 5122; CHECK-NEXT: [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]] 5123; CHECK-NEXT: ret i1 [[ICMP_]] 5124; 5125 %a1 = or disjoint i8 %a, 2 5126 %b1 = add i8 %b, 1 5127 %icmp_ = icmp ugt i8 %a1, %b1 5128 ret i1 %icmp_ 5129} 5130 5131define i1 @disjoint_or_ugt_3(i8 %a, i8 %b) { 5132; CHECK-LABEL: @disjoint_or_ugt_3( 5133; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2 5134; CHECK-NEXT: [[B1:%.*]] = add nuw i8 [[B:%.*]], 1 5135; CHECK-NEXT: [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]] 5136; CHECK-NEXT: ret i1 [[ICMP_]] 5137; 5138 %a1 = or disjoint i8 %a, 2 5139 %b1 = add nuw i8 %b, 1 5140 %icmp_ = icmp ugt i8 %a1, %b1 5141 ret i1 %icmp_ 5142} 5143 5144define i1 @deduce_nuw_flag_1(i8 %a, i8 %b) { 5145; CHECK-LABEL: @deduce_nuw_flag_1( 5146; CHECK-NEXT: entry: 5147; CHECK-NEXT: [[TMP0:%.*]] = add nuw i8 [[B:%.*]], 1 5148; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], [[A:%.*]] 5149; CHECK-NEXT: ret i1 [[CMP]] 5150; 5151entry: 5152 %add1 = add nuw i8 %b, 2 5153 %add2 = add i8 %a, 1 5154 %cmp = icmp eq i8 %add1, %add2 5155 ret i1 %cmp 5156} 5157 5158define i1 @deduce_nuw_flag_2(i8 %a, i8 %b) { 5159; CHECK-LABEL: @deduce_nuw_flag_2( 5160; CHECK-NEXT: entry: 5161; CHECK-NEXT: [[TMP0:%.*]] = add nuw i8 [[B:%.*]], 1 5162; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[TMP0]] 5163; CHECK-NEXT: ret i1 [[CMP]] 5164; 5165entry: 5166 %add1 = add nuw i8 %b, 2 5167 %add2 = add i8 %a, 1 5168 %cmp = icmp eq i8 %add2, %add1 5169 ret i1 %cmp 5170} 5171 5172define i1 @dont_deduce_nuw_flag_1(i8 %a, i8 %b) { 5173; CHECK-LABEL: @dont_deduce_nuw_flag_1( 5174; CHECK-NEXT: entry: 5175; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[B:%.*]], -1 5176; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], [[A:%.*]] 5177; CHECK-NEXT: ret i1 [[CMP]] 5178; 5179entry: 5180 %add1 = add nuw i8 %b, -2 5181 %add2 = add i8 %a, -1 5182 %cmp = icmp eq i8 %add1, %add2 5183 ret i1 %cmp 5184} 5185 5186define i1 @dont_deduce_nuw_flag_2(i8 %a, i8 %b) { 5187; CHECK-LABEL: @dont_deduce_nuw_flag_2( 5188; CHECK-NEXT: entry: 5189; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[B:%.*]], -1 5190; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[TMP0]] 5191; CHECK-NEXT: ret i1 [[CMP]] 5192; 5193entry: 5194 %add1 = add nuw i8 %b, -2 5195 %add2 = add i8 %a, -1 5196 %cmp = icmp eq i8 %add2, %add1 5197 ret i1 %cmp 5198} 5199 5200define i1 @icmp_freeze_sext(i16 %x, i16 %y) { 5201; CHECK-LABEL: @icmp_freeze_sext( 5202; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i16 [[X:%.*]], [[Y:%.*]] 5203; CHECK-NEXT: [[CMP1_FR:%.*]] = freeze i1 [[CMP1]] 5204; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[Y]], 0 5205; CHECK-NEXT: [[CMP2:%.*]] = or i1 [[TMP1]], [[CMP1_FR]] 5206; CHECK-NEXT: ret i1 [[CMP2]] 5207; 5208 %cmp1 = icmp uge i16 %x, %y 5209 %ext = sext i1 %cmp1 to i16 5210 %ext.fr = freeze i16 %ext 5211 %cmp2 = icmp uge i16 %ext.fr, %y 5212 ret i1 %cmp2 5213} 5214 5215define i1 @test_icmp_shl(i64 %x) { 5216; CHECK-LABEL: @test_icmp_shl( 5217; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32 5218; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], 3 5219; CHECK-NEXT: ret i1 [[CMP]] 5220; 5221 %shl = shl i64 %x, 32 5222 %cmp = icmp ult i64 %shl, 8589934593 5223 ret i1 %cmp 5224} 5225 5226define i1 @test_icmp_shl_multiuse(i64 %x) { 5227; CHECK-LABEL: @test_icmp_shl_multiuse( 5228; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X:%.*]], 32 5229; CHECK-NEXT: call void @use_i64(i64 [[SHL]]) 5230; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934593 5231; CHECK-NEXT: ret i1 [[CMP]] 5232; 5233 %shl = shl i64 %x, 32 5234 call void @use_i64(i64 %shl) 5235 %cmp = icmp ult i64 %shl, 8589934593 5236 ret i1 %cmp 5237} 5238 5239define i1 @test_icmp_shl_illegal_length(i64 %x) { 5240; CHECK-LABEL: @test_icmp_shl_illegal_length( 5241; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X:%.*]], 31 5242; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934593 5243; CHECK-NEXT: ret i1 [[CMP]] 5244; 5245 %shl = shl i64 %x, 31 5246 %cmp = icmp ult i64 %shl, 8589934593 5247 ret i1 %cmp 5248} 5249 5250define i1 @test_icmp_shl_invalid_rhsc(i64 %x) { 5251; CHECK-LABEL: @test_icmp_shl_invalid_rhsc( 5252; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X:%.*]], 32 5253; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934595 5254; CHECK-NEXT: ret i1 [[CMP]] 5255; 5256 %shl = shl i64 %x, 32 5257 %cmp = icmp ult i64 %shl, 8589934595 5258 ret i1 %cmp 5259} 5260 5261define i1 @test_icmp_shl_nuw(i64 %x) { 5262; CHECK-LABEL: @test_icmp_shl_nuw( 5263; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 3 5264; CHECK-NEXT: ret i1 [[CMP]] 5265; 5266 %shl = shl nuw i64 %x, 32 5267 %cmp = icmp ult i64 %shl, 8589934593 5268 ret i1 %cmp 5269} 5270 5271define i1 @test_icmp_shl_nuw_i31(i31 %x) { 5272; CHECK-LABEL: @test_icmp_shl_nuw_i31( 5273; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i31 [[X:%.*]], 250 5274; CHECK-NEXT: ret i1 [[CMP]] 5275; 5276 %shl = shl nuw i31 %x, 23 5277 %cmp = icmp ugt i31 %shl, -50331648 5278 ret i1 %cmp 5279} 5280 5281define i1 @test_icmp_shl_nsw(i64 %x) { 5282; CHECK-LABEL: @test_icmp_shl_nsw( 5283; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 3 5284; CHECK-NEXT: ret i1 [[CMP]] 5285; 5286 %shl = shl nsw i64 %x, 32 5287 %cmp = icmp ult i64 %shl, 8589934593 5288 ret i1 %cmp 5289} 5290 5291define i1 @test_icmp_shl_nsw_i31(i31 %x) { 5292; CHECK-LABEL: @test_icmp_shl_nsw_i31( 5293; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i31 [[X:%.*]] to i8 5294; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[TMP1]], -6 5295; CHECK-NEXT: ret i1 [[CMP]] 5296; 5297 %shl = shl nsw i31 %x, 23 5298 %cmp = icmp ugt i31 %shl, -50331648 5299 ret i1 %cmp 5300} 5301 5302define <2 x i1> @test_icmp_shl_vec(<2 x i64> %x) { 5303; CHECK-LABEL: @test_icmp_shl_vec( 5304; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i64> [[X:%.*]] to <2 x i32> 5305; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 3) 5306; CHECK-NEXT: ret <2 x i1> [[CMP]] 5307; 5308 %shl = shl <2 x i64> %x, splat(i64 32) 5309 %cmp = icmp ult <2 x i64> %shl, splat(i64 8589934593) 5310 ret <2 x i1> %cmp 5311} 5312 5313define i1 @test_icmp_shl_eq(i64 %x) { 5314; CHECK-LABEL: @test_icmp_shl_eq( 5315; CHECK-NEXT: ret i1 false 5316; 5317 %shl = shl i64 %x, 32 5318 %cmp = icmp eq i64 %shl, 8589934593 5319 ret i1 %cmp 5320} 5321 5322define i1 @test_icmp_shl_sgt(i64 %x) { 5323; CHECK-LABEL: @test_icmp_shl_sgt( 5324; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32 5325; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 1 5326; CHECK-NEXT: ret i1 [[CMP]] 5327; 5328 %shl = shl i64 %x, 32 5329 %cmp = icmp sgt i64 %shl, 8589934591 5330 ret i1 %cmp 5331} 5332 5333define i1 @pr94897(i32 range(i32 -2147483648, 0) %x) { 5334; CHECK-LABEL: @pr94897( 5335; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[X:%.*]], -3 5336; CHECK-NEXT: ret i1 [[CMP]] 5337; 5338 %shl = shl nsw i32 %x, 24 5339 %cmp = icmp ugt i32 %shl, -50331648 5340 ret i1 %cmp 5341} 5342 5343define i1 @icmp_and_inv_pow2_ne_0(i32 %A, i32 %B) { 5344; CHECK-LABEL: @icmp_and_inv_pow2_ne_0( 5345; CHECK-NEXT: [[POPCNT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[A:%.*]]) 5346; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[POPCNT]], 1 5347; CHECK-NEXT: call void @llvm.assume(i1 [[COND]]) 5348; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A]], [[B:%.*]] 5349; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 5350; CHECK-NEXT: ret i1 [[CMP]] 5351; 5352 %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A) 5353 %cond = icmp eq i32 %popcnt, 1 5354 call void @llvm.assume(i1 %cond) 5355 5356 %inv = xor i32 %B, -1 5357 %and = and i32 %A, %inv 5358 %cmp = icmp ne i32 %and, 0 5359 ret i1 %cmp 5360} 5361 5362define i1 @icmp_and_inv_pow2_or_zero_ne_0(i32 %A, i32 %B) { 5363; CHECK-LABEL: @icmp_and_inv_pow2_or_zero_ne_0( 5364; CHECK-NEXT: [[POPCNT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[A:%.*]]) 5365; CHECK-NEXT: [[COND:%.*]] = icmp samesign ult i32 [[POPCNT]], 2 5366; CHECK-NEXT: call void @llvm.assume(i1 [[COND]]) 5367; CHECK-NEXT: [[INV:%.*]] = xor i32 [[B:%.*]], -1 5368; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], [[INV]] 5369; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 5370; CHECK-NEXT: ret i1 [[CMP]] 5371; 5372 %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A) 5373 %cond = icmp ult i32 %popcnt, 2 5374 call void @llvm.assume(i1 %cond) 5375 5376 %inv = xor i32 %B, -1 5377 %and = and i32 %A, %inv 5378 %cmp = icmp ne i32 %and, 0 5379 ret i1 %cmp 5380} 5381 5382define i1 @icmp_samesign_logical_and(i32 %In) { 5383; CHECK-LABEL: @icmp_samesign_logical_and( 5384; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[IN:%.*]], 1 5385; CHECK-NEXT: ret i1 [[C2]] 5386; 5387 %c1 = icmp samesign sgt i32 %In, -1 5388 %c2 = icmp samesign eq i32 %In, 1 5389 %V = select i1 %c1, i1 %c2, i1 false 5390 ret i1 %V 5391} 5392 5393define i1 @icmp_samesign_logical_or(i32 %In) { 5394; CHECK-LABEL: @icmp_samesign_logical_or( 5395; CHECK-NEXT: [[V:%.*]] = icmp ne i32 [[IN:%.*]], 1 5396; CHECK-NEXT: ret i1 [[V]] 5397; 5398 %c1 = icmp samesign slt i32 %In, 0 5399 %c2 = icmp samesign ne i32 %In, 1 5400 %V = select i1 %c1, i1 true, i1 %c2 5401 ret i1 %V 5402} 5403