1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "n32" 5 6define i1 @is_rem2_neg_i8(i8 %x) { 7; CHECK-LABEL: @is_rem2_neg_i8( 8; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -127 9; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], -127 10; CHECK-NEXT: ret i1 [[R]] 11; 12 %s = srem i8 %x, 2 13 %r = icmp slt i8 %s, 0 14 ret i1 %r 15} 16 17define <2 x i1> @is_rem2_pos_v2i8(<2 x i8> %x) { 18; CHECK-LABEL: @is_rem2_pos_v2i8( 19; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -127) 20; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], splat (i8 1) 21; CHECK-NEXT: ret <2 x i1> [[R]] 22; 23 %s = srem <2 x i8> %x, <i8 2, i8 2> 24 %r = icmp sgt <2 x i8> %s, zeroinitializer 25 ret <2 x i1> %r 26} 27 28; i8 -97 == 159 == 0b10011111 29 30define i1 @is_rem32_pos_i8(i8 %x) { 31; CHECK-LABEL: @is_rem32_pos_i8( 32; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -97 33; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[TMP1]], 0 34; CHECK-NEXT: ret i1 [[R]] 35; 36 %s = srem i8 %x, 32 37 %r = icmp sgt i8 %s, 0 38 ret i1 %r 39} 40 41; i16 -32765 == 32771 == 0b1000000000000011 42 43define i1 @is_rem4_neg_i16(i16 %x) { 44; CHECK-LABEL: @is_rem4_neg_i16( 45; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], -32765 46; CHECK-NEXT: [[R:%.*]] = icmp ugt i16 [[TMP1]], -32768 47; CHECK-NEXT: ret i1 [[R]] 48; 49 %s = srem i16 %x, 4 50 %r = icmp slt i16 %s, 0 51 ret i1 %r 52} 53 54declare void @use(i32) 55 56; TODO: This is still worth folding because srem is difficult? 57 58define i1 @is_rem32_neg_i32_extra_use(i32 %x) { 59; CHECK-LABEL: @is_rem32_neg_i32_extra_use( 60; CHECK-NEXT: [[S:%.*]] = srem i32 [[X:%.*]], 32 61; CHECK-NEXT: call void @use(i32 [[S]]) 62; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[S]], 0 63; CHECK-NEXT: ret i1 [[R]] 64; 65 %s = srem i32 %x, 32 66 call void @use(i32 %s) 67 %r = icmp slt i32 %s, 0 68 ret i1 %r 69} 70 71; Negative test - wrong compare constant 72 73define i1 @is_rem8_nonneg_i16(i16 %x) { 74; CHECK-LABEL: @is_rem8_nonneg_i16( 75; CHECK-NEXT: [[S:%.*]] = srem i16 [[X:%.*]], 8 76; CHECK-NEXT: [[R:%.*]] = icmp sgt i16 [[S]], -1 77; CHECK-NEXT: ret i1 [[R]] 78; 79 %s = srem i16 %x, 8 80 %r = icmp sgt i16 %s, -1 81 ret i1 %r 82} 83 84; Negative test - wrong remainder constant 85 86define i1 @is_rem3_neg_i8(i8 %x) { 87; CHECK-LABEL: @is_rem3_neg_i8( 88; CHECK-NEXT: [[S:%.*]] = srem i8 [[X:%.*]], 3 89; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[S]], 0 90; CHECK-NEXT: ret i1 [[R]] 91; 92 %s = srem i8 %x, 3 93 %r = icmp slt i8 %s, 0 94 ret i1 %r 95} 96 97; Negative test - wrong compare constant 98 99define i1 @is_rem16_something_i8(i8 %x) { 100; CHECK-LABEL: @is_rem16_something_i8( 101; CHECK-NEXT: [[S:%.*]] = srem i8 [[X:%.*]], 16 102; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[S]], 7 103; CHECK-NEXT: ret i1 [[R]] 104; 105 %s = srem i8 %x, 16 106 %r = icmp slt i8 %s, 7 107 ret i1 %r 108} 109 110; PR30281 - https://llvm.org/bugs/show_bug.cgi?id=30281 111 112; All of these tests contain foldable division-by-constant instructions, but we 113; can't assert that those folds have occurred before we process the later icmp. 114 115define i32 @icmp_div(i16 %a, i16 %c) { 116; CHECK-LABEL: @icmp_div( 117; CHECK-NEXT: entry: 118; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0 119; CHECK-NEXT: br i1 [[TOBOOL]], label [[THEN:%.*]], label [[EXIT:%.*]] 120; CHECK: then: 121; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i16 [[C:%.*]], 0 122; CHECK-NEXT: [[TMP0:%.*]] = sext i1 [[CMP_NOT]] to i32 123; CHECK-NEXT: br label [[EXIT]] 124; CHECK: exit: 125; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[TMP0]], [[THEN]] ] 126; CHECK-NEXT: ret i32 [[PHI]] 127; 128entry: 129 %tobool = icmp eq i16 %a, 0 130 br i1 %tobool, label %then, label %exit 131 132then: 133 %div = sdiv i16 %c, -1 134 %cmp = icmp ne i16 %div, 0 135 br label %exit 136 137exit: 138 %phi = phi i1 [ false, %entry ], [ %cmp, %then ] 139 %zext = zext i1 %phi to i32 140 %add = add nsw i32 %zext, -1 141 ret i32 %add 142} 143 144define i32 @icmp_div2(i16 %a, i16 %c) { 145; CHECK-LABEL: @icmp_div2( 146; CHECK-NEXT: entry: 147; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0 148; CHECK-NEXT: br i1 [[TOBOOL]], label [[THEN:%.*]], label [[EXIT:%.*]] 149; CHECK: then: 150; CHECK-NEXT: br label [[EXIT]] 151; CHECK: exit: 152; CHECK-NEXT: ret i32 -1 153; 154entry: 155 %tobool = icmp eq i16 %a, 0 156 br i1 %tobool, label %then, label %exit 157 158then: 159 %div = sdiv i16 %c, 0 160 %cmp = icmp ne i16 %div, 0 161 br label %exit 162 163exit: 164 %phi = phi i1 [ false, %entry ], [ %cmp, %then ] 165 %zext = zext i1 %phi to i32 166 %add = add nsw i32 %zext, -1 167 ret i32 %add 168} 169 170define i32 @icmp_div3(i16 %a, i16 %c) { 171; CHECK-LABEL: @icmp_div3( 172; CHECK-NEXT: entry: 173; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0 174; CHECK-NEXT: br i1 [[TOBOOL]], label [[THEN:%.*]], label [[EXIT:%.*]] 175; CHECK: then: 176; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i16 [[C:%.*]], 0 177; CHECK-NEXT: [[TMP0:%.*]] = sext i1 [[CMP_NOT]] to i32 178; CHECK-NEXT: br label [[EXIT]] 179; CHECK: exit: 180; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[TMP0]], [[THEN]] ] 181; CHECK-NEXT: ret i32 [[PHI]] 182; 183entry: 184 %tobool = icmp eq i16 %a, 0 185 br i1 %tobool, label %then, label %exit 186 187then: 188 %div = sdiv i16 %c, 1 189 %cmp = icmp ne i16 %div, 0 190 br label %exit 191 192exit: 193 %phi = phi i1 [ false, %entry ], [ %cmp, %then ] 194 %zext = zext i1 %phi to i32 195 %add = add nsw i32 %zext, -1 196 ret i32 %add 197} 198 199define i1 @udiv_eq_umax(i8 %x, i8 %y) { 200; CHECK-LABEL: @udiv_eq_umax( 201; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -1 202; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[Y:%.*]], 1 203; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[TMP2]] 204; CHECK-NEXT: ret i1 [[R]] 205; 206 %d = udiv i8 %x, %y 207 %r = icmp eq i8 %d, 255 208 ret i1 %r 209} 210 211define <2 x i1> @udiv_ne_umax(<2 x i5> %x, <2 x i5> %y) { 212; CHECK-LABEL: @udiv_ne_umax( 213; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i5> [[X:%.*]], splat (i5 -1) 214; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i5> [[Y:%.*]], splat (i5 1) 215; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]] 216; CHECK-NEXT: ret <2 x i1> [[R]] 217; 218 %d = udiv <2 x i5> %x, %y 219 %r = icmp ne <2 x i5> %d, <i5 -1, i5 -1> 220 ret <2 x i1> %r 221} 222 223define i1 @udiv_eq_big(i8 %x, i8 %y) { 224; CHECK-LABEL: @udiv_eq_big( 225; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128 226; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[Y:%.*]], 1 227; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[TMP2]] 228; CHECK-NEXT: ret i1 [[R]] 229; 230 %d = udiv i8 %x, %y 231 %r = icmp eq i8 %d, 128 232 ret i1 %r 233} 234 235define i1 @udiv_ne_big(i8 %x, i8 %y) { 236; CHECK-LABEL: @udiv_ne_big( 237; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], -128 238; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[Y:%.*]], 1 239; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[TMP2]] 240; CHECK-NEXT: ret i1 [[R]] 241; 242 %d = udiv i8 %x, %y 243 %r = icmp ne i8 %d, 128 244 ret i1 %r 245} 246 247; negative test - must have negative compare constant 248 249define i1 @udiv_eq_not_big(i8 %x, i8 %y) { 250; CHECK-LABEL: @udiv_eq_not_big( 251; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 252; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[D]], 127 253; CHECK-NEXT: ret i1 [[R]] 254; 255 %d = udiv i8 %x, %y 256 %r = icmp eq i8 %d, 127 257 ret i1 %r 258} 259 260; negative test - must be equality predicate 261 262define i1 @udiv_slt_umax(i8 %x, i8 %y) { 263; CHECK-LABEL: @udiv_slt_umax( 264; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 265; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[D]], -1 266; CHECK-NEXT: ret i1 [[R]] 267; 268 %d = udiv i8 %x, %y 269 %r = icmp slt i8 %d, 255 270 ret i1 %r 271} 272 273; negative test - extra use 274 275define i1 @udiv_eq_umax_use(i32 %x, i32 %y) { 276; CHECK-LABEL: @udiv_eq_umax_use( 277; CHECK-NEXT: [[D:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]] 278; CHECK-NEXT: call void @use(i32 [[D]]) 279; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[D]], -1 280; CHECK-NEXT: ret i1 [[R]] 281; 282 %d = udiv i32 %x, %y 283 call void @use(i32 %d) 284 %r = icmp eq i32 %d, -1 285 ret i1 %r 286} 287 288define i1 @sdiv_eq_smin(i8 %x, i8 %y) { 289; CHECK-LABEL: @sdiv_eq_smin( 290; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128 291; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[Y:%.*]], 1 292; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[TMP2]] 293; CHECK-NEXT: ret i1 [[R]] 294; 295 %d = sdiv i8 %x, %y 296 %r = icmp eq i8 %d, -128 297 ret i1 %r 298} 299 300define <2 x i1> @sdiv_ne_smin(<2 x i5> %x, <2 x i5> %y) { 301; CHECK-LABEL: @sdiv_ne_smin( 302; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i5> [[X:%.*]], splat (i5 -16) 303; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i5> [[Y:%.*]], splat (i5 1) 304; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]] 305; CHECK-NEXT: ret <2 x i1> [[R]] 306; 307 %d = sdiv <2 x i5> %x, %y 308 %r = icmp ne <2 x i5> %d, <i5 -16, i5 -16> 309 ret <2 x i1> %r 310} 311 312; negative test - must be SMIN 313 314define i1 @sdiv_eq_small(i8 %x, i8 %y) { 315; CHECK-LABEL: @sdiv_eq_small( 316; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]] 317; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[D]], -127 318; CHECK-NEXT: ret i1 [[R]] 319; 320 %d = sdiv i8 %x, %y 321 %r = icmp eq i8 %d, -127 322 ret i1 %r 323} 324 325; negative test - must be SMIN 326 327define i1 @sdiv_ne_big(i8 %x, i8 %y) { 328; CHECK-LABEL: @sdiv_ne_big( 329; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]] 330; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[D]], 127 331; CHECK-NEXT: ret i1 [[R]] 332; 333 %d = sdiv i8 %x, %y 334 %r = icmp ne i8 %d, 127 335 ret i1 %r 336} 337 338; negative test - must be SMIN 339 340define i1 @sdiv_eq_not_big(i8 %x, i8 %y) { 341; CHECK-LABEL: @sdiv_eq_not_big( 342; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]] 343; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[D]], 100 344; CHECK-NEXT: ret i1 [[R]] 345; 346 %d = sdiv i8 %x, %y 347 %r = icmp eq i8 %d, 100 348 ret i1 %r 349} 350 351; negative test - must be equality predicate 352 353define i1 @sdiv_ult_smin(i8 %x, i8 %y) { 354; CHECK-LABEL: @sdiv_ult_smin( 355; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]] 356; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[D]], -1 357; CHECK-NEXT: ret i1 [[R]] 358; 359 %d = sdiv i8 %x, %y 360 %r = icmp ult i8 %d, 128 361 ret i1 %r 362} 363 364; negative test - extra use 365 366define i1 @sdiv_eq_smin_use(i32 %x, i32 %y) { 367; CHECK-LABEL: @sdiv_eq_smin_use( 368; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], [[Y:%.*]] 369; CHECK-NEXT: call void @use(i32 [[D]]) 370; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[D]], -2147483648 371; CHECK-NEXT: ret i1 [[R]] 372; 373 %d = sdiv i32 %x, %y 374 call void @use(i32 %d) 375 %r = icmp eq i32 %d, -2147483648 376 ret i1 %r 377} 378 379; Fold (X / C) cmp X into X ~cmp 0 (~cmp is the inverse predicate of cmp), for some C != 1 380; Alternative form of this fold is when division is replaced with logic right shift 381 382define i1 @sdiv_x_by_const_cmp_x(i32 %x) { 383; CHECK-LABEL: @sdiv_x_by_const_cmp_x( 384; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 0 385; CHECK-NEXT: ret i1 [[R]] 386; 387 %v = sdiv i32 %x, 13 388 %r = icmp eq i32 %v, %x 389 ret i1 %r 390} 391 392define i1 @udiv_x_by_const_cmp_x(i32 %x) { 393; CHECK-LABEL: @udiv_x_by_const_cmp_x( 394; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], 0 395; CHECK-NEXT: ret i1 [[TMP1]] 396; 397 %1 = udiv i32 %x, 123 398 %2 = icmp slt i32 %1, %x 399 ret i1 %2 400} 401 402define <2 x i1> @udiv_x_by_const_cmp_x_non_splat(<2 x i32> %x) { 403; CHECK-LABEL: @udiv_x_by_const_cmp_x_non_splat( 404; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], zeroinitializer 405; CHECK-NEXT: ret <2 x i1> [[TMP1]] 406; 407 %1 = udiv <2 x i32> %x, <i32 123, i32 -123> 408 %2 = icmp slt <2 x i32> %1, %x 409 ret <2 x i1> %2 410} 411 412 413define <2 x i1> @sdiv_x_by_const_cmp_x_non_splat(<2 x i32> %x) { 414; CHECK-LABEL: @sdiv_x_by_const_cmp_x_non_splat( 415; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer 416; CHECK-NEXT: ret <2 x i1> [[TMP1]] 417; 418 %1 = sdiv <2 x i32> %x, <i32 2, i32 3> 419 %2 = icmp eq <2 x i32> %1, %x 420 ret <2 x i1> %2 421} 422 423; Same as above but with right shift instead of division (C != 0) 424 425define i1 @lshr_x_by_const_cmp_x(i32 %x) { 426; CHECK-LABEL: @lshr_x_by_const_cmp_x( 427; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 0 428; CHECK-NEXT: ret i1 [[R]] 429; 430 %v = lshr i32 %x, 1 431 %r = icmp eq i32 %v, %x 432 ret i1 %r 433} 434 435define <4 x i1> @lshr_by_const_cmp_sle_value(<4 x i32> %x) { 436; CHECK-LABEL: @lshr_by_const_cmp_sle_value( 437; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[X:%.*]], splat (i32 -1) 438; CHECK-NEXT: ret <4 x i1> [[R]] 439; 440 %v = lshr <4 x i32> %x, <i32 3, i32 3, i32 3, i32 3> 441 %r = icmp sle <4 x i32> %v, %x 442 ret <4 x i1> %r 443} 444 445define <4 x i1> @lshr_by_const_cmp_sle_value_non_splat(<4 x i32> %x) { 446; CHECK-LABEL: @lshr_by_const_cmp_sle_value_non_splat( 447; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[X:%.*]], splat (i32 -1) 448; CHECK-NEXT: ret <4 x i1> [[R]] 449; 450 %v = lshr <4 x i32> %x, <i32 3, i32 3, i32 3, i32 5> 451 %r = icmp sle <4 x i32> %v, %x 452 ret <4 x i1> %r 453} 454 455 456define <4 x i1> @ashr_by_const_cmp_sge_value_non_splat(<4 x i32> %x) { 457; CHECK-LABEL: @ashr_by_const_cmp_sge_value_non_splat( 458; CHECK-NEXT: [[R:%.*]] = icmp slt <4 x i32> [[X:%.*]], splat (i32 1) 459; CHECK-NEXT: ret <4 x i1> [[R]] 460; 461 %v = ashr <4 x i32> %x, <i32 1, i32 2, i32 3, i32 4> 462 %r = icmp sge <4 x i32> %v, %x 463 ret <4 x i1> %r 464} 465 466 467define i1 @lshr_by_const_cmp_sge_value(i32 %x) { 468; CHECK-LABEL: @lshr_by_const_cmp_sge_value( 469; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[X:%.*]], 1 470; CHECK-NEXT: ret i1 [[R]] 471; 472 %v = lshr i32 %x, 3 473 %r = icmp sge i32 %v, %x 474 ret i1 %r 475} 476 477define i1 @ashr_x_by_const_cmp_sge_x(i32 %x) { 478; CHECK-LABEL: @ashr_x_by_const_cmp_sge_x( 479; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[X:%.*]], 1 480; CHECK-NEXT: ret i1 [[R]] 481; 482 %v = ashr i32 %x, 5 483 %r = icmp sge i32 %v, %x 484 ret i1 %r 485} 486 487; Negative test - constant is 1 488 489define <2 x i1> @udiv_x_by_const_cmp_eq_value_neg(<2 x i32> %x) { 490; CHECK-LABEL: @udiv_x_by_const_cmp_eq_value_neg( 491; CHECK-NEXT: [[V:%.*]] = udiv <2 x i32> [[X:%.*]], <i32 1, i32 3> 492; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i32> [[V]], [[X]] 493; CHECK-NEXT: ret <2 x i1> [[R]] 494; 495 %v = udiv <2 x i32> %x, <i32 1, i32 3> 496 %r = icmp eq <2 x i32> %v, %x 497 ret <2 x i1> %r 498} 499 500define <2 x i1> @sdiv_x_by_const_cmp_eq_value_neg(<2 x i32> %x) { 501; CHECK-LABEL: @sdiv_x_by_const_cmp_eq_value_neg( 502; CHECK-NEXT: [[V:%.*]] = sdiv <2 x i32> [[X:%.*]], <i32 1, i32 3> 503; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i32> [[V]], [[X]] 504; CHECK-NEXT: ret <2 x i1> [[R]] 505; 506 %v = sdiv <2 x i32> %x, <i32 1, i32 3> 507 %r = icmp eq <2 x i32> %v, %x 508 ret <2 x i1> %r 509} 510 511; Negative test - constant is 0 512 513define <2 x i1> @lshr_x_by_const_cmp_slt_value_neg(<2 x i32> %x) { 514; CHECK-LABEL: @lshr_x_by_const_cmp_slt_value_neg( 515; CHECK-NEXT: [[V:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 0, i32 2> 516; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i32> [[V]], [[X]] 517; CHECK-NEXT: ret <2 x i1> [[R]] 518; 519 %v = lshr <2 x i32> %x, <i32 0, i32 2> 520 %r = icmp slt <2 x i32> %v, %x 521 ret <2 x i1> %r 522} 523 524; Negative test - unsigned predicate with sdiv 525 526define i1 @sdiv_x_by_const_cmp_ult_value_neg(i32 %x) { 527; CHECK-LABEL: @sdiv_x_by_const_cmp_ult_value_neg( 528; CHECK-NEXT: [[V:%.*]] = sdiv i32 [[X:%.*]], 3 529; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[V]], [[X]] 530; CHECK-NEXT: ret i1 [[R]] 531; 532 %v = sdiv i32 %x, 3 533 %r = icmp ult i32 %v, %x 534 ret i1 %r 535} 536 537; Negative case - one of the components of a vector is 1 538 539define <4 x i1> @sdiv_x_by_const_cmp_sgt_value_neg(<4 x i32> %x) { 540; CHECK-LABEL: @sdiv_x_by_const_cmp_sgt_value_neg( 541; CHECK-NEXT: [[V:%.*]] = sdiv <4 x i32> [[X:%.*]], <i32 1, i32 2, i32 3, i32 4> 542; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[V]], [[X]] 543; CHECK-NEXT: ret <4 x i1> [[R]] 544; 545 %v = sdiv <4 x i32> %x, <i32 1, i32 2, i32 3, i32 4> 546 %r = icmp sgt <4 x i32> %v, %x 547 ret <4 x i1> %r 548} 549 550; Negative case - ashr only allows sge/slt predicates 551 552define i1 @ashr_x_by_const_cmp_sle_value_neg(i32 %x) { 553; CHECK-LABEL: @ashr_x_by_const_cmp_sle_value_neg( 554; CHECK-NEXT: [[V:%.*]] = ashr i32 [[X:%.*]], 3 555; CHECK-NEXT: [[R:%.*]] = icmp sle i32 [[V]], [[X]] 556; CHECK-NEXT: ret i1 [[R]] 557; 558 %v = ashr i32 %x, 3 559 %r = icmp sle i32 %v, %x 560 ret i1 %r 561} 562