800 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i8 %value)5 6define i1 @scmp_eq_0(i32 %x, i32 %y) {7; CHECK-LABEL: define i1 @scmp_eq_0(8; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {9; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[X]], [[Y]]10; CHECK-NEXT: ret i1 [[TMP2]]11;12 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)13 %2 = icmp eq i8 %1, 014 ret i1 %215}16 17define i1 @scmp_ne_0(i32 %x, i32 %y) {18; CHECK-LABEL: define i1 @scmp_ne_0(19; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {20; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[X]], [[Y]]21; CHECK-NEXT: ret i1 [[TMP2]]22;23 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)24 %2 = icmp ne i8 %1, 025 ret i1 %226}27 28define i1 @scmp_eq_1(i32 %x, i32 %y) {29; CHECK-LABEL: define i1 @scmp_eq_1(30; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {31; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]32; CHECK-NEXT: ret i1 [[TMP2]]33;34 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)35 %2 = icmp eq i8 %1, 136 ret i1 %237}38 39define i1 @scmp_ne_1(i32 %x, i32 %y) {40; CHECK-LABEL: define i1 @scmp_ne_1(41; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {42; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]43; CHECK-NEXT: ret i1 [[TMP2]]44;45 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)46 %2 = icmp ne i8 %1, 147 ret i1 %248}49 50define i1 @scmp_eq_negative_1(i32 %x, i32 %y) {51; CHECK-LABEL: define i1 @scmp_eq_negative_1(52; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {53; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]54; CHECK-NEXT: ret i1 [[TMP2]]55;56 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)57 %2 = icmp eq i8 %1, -158 ret i1 %259}60 61define i1 @scmp_ne_negative_1(i32 %x, i32 %y) {62; CHECK-LABEL: define i1 @scmp_ne_negative_1(63; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {64; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]65; CHECK-NEXT: ret i1 [[TMP2]]66;67 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)68 %2 = icmp ne i8 %1, -169 ret i1 %270}71 72define i1 @scmp_sgt_0(i32 %x, i32 %y) {73; CHECK-LABEL: define i1 @scmp_sgt_0(74; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {75; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]76; CHECK-NEXT: ret i1 [[TMP2]]77;78 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)79 %2 = icmp sgt i8 %1, 080 ret i1 %281}82 83define i1 @scmp_sgt_neg_1(i32 %x, i32 %y) {84; CHECK-LABEL: define i1 @scmp_sgt_neg_1(85; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {86; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]87; CHECK-NEXT: ret i1 [[TMP2]]88;89 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)90 %2 = icmp sgt i8 %1, -191 ret i1 %292}93 94define i1 @scmp_sge_0(i32 %x, i32 %y) {95; CHECK-LABEL: define i1 @scmp_sge_0(96; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {97; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]98; CHECK-NEXT: ret i1 [[TMP2]]99;100 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)101 %2 = icmp sge i8 %1, 0102 ret i1 %2103}104 105define i1 @scmp_sge_1(i32 %x, i32 %y) {106; CHECK-LABEL: define i1 @scmp_sge_1(107; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {108; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]109; CHECK-NEXT: ret i1 [[TMP2]]110;111 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)112 %2 = icmp sge i8 %1, 1113 ret i1 %2114}115 116define i1 @scmp_slt_0(i32 %x, i32 %y) {117; CHECK-LABEL: define i1 @scmp_slt_0(118; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {119; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]120; CHECK-NEXT: ret i1 [[TMP2]]121;122 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)123 %2 = icmp slt i8 %1, 0124 ret i1 %2125}126 127define i1 @scmp_slt_1(i32 %x, i32 %y) {128; CHECK-LABEL: define i1 @scmp_slt_1(129; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {130; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]131; CHECK-NEXT: ret i1 [[TMP2]]132;133 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)134 %2 = icmp slt i8 %1, 1135 ret i1 %2136}137 138define i1 @scmp_sle_0(i32 %x, i32 %y) {139; CHECK-LABEL: define i1 @scmp_sle_0(140; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {141; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]142; CHECK-NEXT: ret i1 [[TMP2]]143;144 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)145 %2 = icmp sle i8 %1, 0146 ret i1 %2147}148 149define i1 @scmp_sle_neg_1(i32 %x, i32 %y) {150; CHECK-LABEL: define i1 @scmp_sle_neg_1(151; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {152; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]153; CHECK-NEXT: ret i1 [[TMP2]]154;155 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)156 %2 = icmp sle i8 %1, -1157 ret i1 %2158}159 160; scmp(x, y) u< C => x s>= y when C u> 1 and C != -1161define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) {162; CHECK-LABEL: define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(163; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {164; CHECK-NEXT: [[TMP1:%.*]] = icmp sge i32 [[X]], [[Y]]165; CHECK-NEXT: ret i1 [[TMP1]]166;167 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)168 %2 = icmp ult i8 %1, 4169 ret i1 %2170}171 172; scmp(x, y) s> C => x s< y when C != 0 and C != -1173define i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) {174; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1(175; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {176; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]177; CHECK-NEXT: ret i1 [[TMP2]]178;179 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)180 %2 = icmp ugt i8 %1, 12181 ret i1 %2182}183 184 185; ========== Fold -scmp(x, y) => scmp(y, x) ==========186define i8 @scmp_negated(i32 %x, i32 %y) {187; CHECK-LABEL: define i8 @scmp_negated(188; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {189; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])190; CHECK-NEXT: ret i8 [[TMP2]]191;192 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)193 %2 = sub i8 0, %1194 ret i8 %2195}196 197; Negative test: do not fold if the original scmp result is already used198define i8 @scmp_negated_multiuse(i32 %x, i32 %y) {199; CHECK-LABEL: define i8 @scmp_negated_multiuse(200; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {201; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])202; CHECK-NEXT: call void @use(i8 [[TMP1]])203; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i8 0, [[TMP1]]204; CHECK-NEXT: ret i8 [[TMP2]]205;206 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)207 call void @use(i8 %1)208 %2 = sub i8 0, %1209 ret i8 %2210}211 212; Fold ((x s< y) ? -1 : (x != y)) into scmp(x, y)213define i8 @scmp_from_select_lt(i32 %x, i32 %y) {214; CHECK-LABEL: define i8 @scmp_from_select_lt(215; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {216; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])217; CHECK-NEXT: ret i8 [[R]]218;219 %ne_bool = icmp ne i32 %x, %y220 %ne = zext i1 %ne_bool to i8221 %lt = icmp slt i32 %x, %y222 %r = select i1 %lt, i8 -1, i8 %ne223 ret i8 %r224}225 226; Fold (x s< y) ? -1 : zext(x s> y) into scmp(x, y)227define i8 @scmp_from_select_lt_and_gt(i32 %x, i32 %y) {228; CHECK-LABEL: define i8 @scmp_from_select_lt_and_gt(229; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {230; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])231; CHECK-NEXT: ret i8 [[R]]232;233 %gt_bool = icmp sgt i32 %x, %y234 %gt = zext i1 %gt_bool to i8235 %lt = icmp slt i32 %x, %y236 %r = select i1 %lt, i8 -1, i8 %gt237 ret i8 %r238}239 240; Vector version241define <4 x i8> @scmp_from_select_vec_lt(<4 x i32> %x, <4 x i32> %y) {242; CHECK-LABEL: define <4 x i8> @scmp_from_select_vec_lt(243; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {244; CHECK-NEXT: [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])245; CHECK-NEXT: ret <4 x i8> [[R]]246;247 %ne_bool = icmp ne <4 x i32> %x, %y248 %ne = zext <4 x i1> %ne_bool to <4 x i8>249 %lt = icmp slt <4 x i32> %x, %y250 %r = select <4 x i1> %lt, <4 x i8> splat(i8 -1), <4 x i8> %ne251 ret <4 x i8> %r252}253 254; Fold (x s<= y) ? sext(x != y) : 1 into scmp(x, y)255define i8 @scmp_from_select_le(i32 %x, i32 %y) {256; CHECK-LABEL: define i8 @scmp_from_select_le(257; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {258; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])259; CHECK-NEXT: ret i8 [[R]]260;261 %ne_bool = icmp ne i32 %x, %y262 %ne = sext i1 %ne_bool to i8263 %le = icmp sle i32 %x, %y264 %r = select i1 %le, i8 %ne, i8 1265 ret i8 %r266}267 268; Fold (x s>= y) ? zext(x != y) : -1 into scmp(x, y)269define i8 @scmp_from_select_ge(i32 %x, i32 %y) {270; CHECK-LABEL: define i8 @scmp_from_select_ge(271; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {272; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])273; CHECK-NEXT: ret i8 [[R]]274;275 %ne_bool = icmp ne i32 %x, %y276 %ne = zext i1 %ne_bool to i8277 %ge = icmp sge i32 %x, %y278 %r = select i1 %ge, i8 %ne, i8 -1279 ret i8 %r280}281 282; Fold scmp(x nsw- y, 0) to scmp(x, y)283define i8 @scmp_of_sub_and_zero(i32 %x, i32 %y) {284; CHECK-LABEL: define i8 @scmp_of_sub_and_zero(285; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {286; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])287; CHECK-NEXT: ret i8 [[R]]288;289 %diff = sub nsw i32 %x, %y290 %r = call i8 @llvm.scmp(i32 %diff, i32 0)291 ret i8 %r292}293 294; Negative test: no nsw295define i8 @scmp_of_sub_and_zero_neg_1(i32 %x, i32 %y) {296; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg_1(297; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {298; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[X]], [[Y]]299; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[DIFF]], i32 0)300; CHECK-NEXT: ret i8 [[R]]301;302 %diff = sub i32 %x, %y303 %r = call i8 @llvm.scmp(i32 %diff, i32 0)304 ret i8 %r305}306 307; Negative test: second argument of scmp is not 0308define i8 @scmp_of_sub_and_zero_neg2(i32 %x, i32 %y) {309; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg2(310; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {311; CHECK-NEXT: [[DIFF:%.*]] = sub nsw i32 [[X]], [[Y]]312; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[DIFF]], i32 15)313; CHECK-NEXT: ret i8 [[R]]314;315 %diff = sub nsw i32 %x, %y316 %r = call i8 @llvm.scmp(i32 %diff, i32 15)317 ret i8 %r318}319 320; Negative test: calling ucmp instead of scmp321define i8 @scmp_of_sub_and_zero_neg3(i32 %x, i32 %y) {322; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg3(323; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {324; CHECK-NEXT: [[DIFF:%.*]] = sub nsw i32 [[X]], [[Y]]325; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[DIFF]], i32 0)326; CHECK-NEXT: ret i8 [[R]]327;328 %diff = sub nsw i32 %x, %y329 %r = call i8 @llvm.ucmp(i32 %diff, i32 0)330 ret i8 %r331}332 333; Fold (x s> y) ? 1 : sext(x s< y)334define i8 @scmp_from_select_gt_and_lt(i32 %x, i32 %y) {335; CHECK-LABEL: define i8 @scmp_from_select_gt_and_lt(336; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {337; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])338; CHECK-NEXT: ret i8 [[R]]339;340 %lt_bool = icmp slt i32 %x, %y341 %lt = sext i1 %lt_bool to i8342 %gt = icmp sgt i32 %x, %y343 %r = select i1 %gt, i8 1, i8 %lt344 ret i8 %r345}346 347; (x == y) ? 0 : (x s> y ? 1 : -1) into scmp(x, y)348define i8 @scmp_from_select_eq_and_gt(i32 %x, i32 %y) {349; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(350; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {351; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])352; CHECK-NEXT: ret i8 [[R]]353;354 %eq = icmp eq i32 %x, %y355 %gt = icmp sgt i32 %x, %y356 %sel1 = select i1 %gt, i8 1, i8 -1357 %r = select i1 %eq, i8 0, i8 %sel1358 ret i8 %r359}360 361define i8 @scmp_from_select_eq_and_gt_inverse(i32 %x, i32 %y) {362; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_inverse(363; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {364; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])365; CHECK-NEXT: ret i8 [[R]]366;367 %ne = icmp ne i32 %x, %y368 %gt = icmp sgt i32 %x, %y369 %sel1 = select i1 %gt, i8 1, i8 -1370 %r = select i1 %ne, i8 %sel1, i8 0371 ret i8 %r372}373 374define <4 x i8> @scmp_from_select_eq_and_gt_vec(<4 x i32> %x, <4 x i32> %y) {375; CHECK-LABEL: define <4 x i8> @scmp_from_select_eq_and_gt_vec(376; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {377; CHECK-NEXT: [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])378; CHECK-NEXT: ret <4 x i8> [[R]]379;380 %eq = icmp eq <4 x i32> %x, %y381 %gt = icmp sgt <4 x i32> %x, %y382 %sel1 = select <4 x i1> %gt, <4 x i8> splat(i8 1), <4 x i8> splat(i8 -1)383 %r = select <4 x i1> %eq, <4 x i8> splat(i8 0), <4 x i8> %sel1384 ret <4 x i8> %r385}386 387define i8 @scmp_from_select_eq_and_gt_commuted1(i32 %x, i32 %y) {388; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted1(389; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {390; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])391; CHECK-NEXT: ret i8 [[R]]392;393 %eq = icmp eq i32 %x, %y394 %gt = icmp slt i32 %x, %y395 %sel1 = select i1 %gt, i8 1, i8 -1396 %r = select i1 %eq, i8 0, i8 %sel1397 ret i8 %r398}399 400define i8 @scmp_from_select_eq_and_gt_commuted2(i32 %x, i32 %y) {401; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted2(402; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {403; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])404; CHECK-NEXT: ret i8 [[R]]405;406 %eq = icmp eq i32 %x, %y407 %gt = icmp sgt i32 %x, %y408 %sel1 = select i1 %gt, i8 -1, i8 1409 %r = select i1 %eq, i8 0, i8 %sel1410 ret i8 %r411}412 413define i8 @scmp_from_select_eq_and_gt_commuted3(i32 %x, i32 %y) {414; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted3(415; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {416; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])417; CHECK-NEXT: ret i8 [[R]]418;419 %eq = icmp eq i32 %x, %y420 %gt = icmp slt i32 %x, %y421 %sel1 = select i1 %gt, i8 -1, i8 1422 %r = select i1 %eq, i8 0, i8 %sel1423 ret i8 %r424}425 426; Commutative tests for (x != y) ? (x > y ? 1 : -1) : 0427define i8 @scmp_from_select_ne_and_gt_commuted1(i32 %x, i32 %y) {428; CHECK-LABEL: define i8 @scmp_from_select_ne_and_gt_commuted1(429; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {430; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])431; CHECK-NEXT: ret i8 [[R]]432;433 %ne = icmp ne i32 %x, %y434 %gt = icmp slt i32 %x, %y435 %sel1 = select i1 %gt, i8 1, i8 -1436 %r = select i1 %ne, i8 %sel1, i8 0437 ret i8 %r438}439 440define i8 @scmp_from_select_ne_and_gt_commuted2(i32 %x, i32 %y) {441; CHECK-LABEL: define i8 @scmp_from_select_ne_and_gt_commuted2(442; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {443; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])444; CHECK-NEXT: ret i8 [[R]]445;446 %ne = icmp ne i32 %x, %y447 %gt = icmp sgt i32 %x, %y448 %sel1 = select i1 %gt, i8 -1, i8 1449 %r = select i1 %ne, i8 %sel1, i8 0450 ret i8 %r451}452 453define i8 @scmp_from_select_ne_and_gt_commuted3(i32 %x, i32 %y) {454; CHECK-LABEL: define i8 @scmp_from_select_ne_and_gt_commuted3(455; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {456; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])457; CHECK-NEXT: ret i8 [[R]]458;459 %ne = icmp ne i32 %x, %y460 %gt = icmp sgt i32 %x, %y461 %sel1 = select i1 %gt, i8 1, i8 -1462 %r = select i1 %ne, i8 %sel1, i8 0463 ret i8 %r464}465 466; Commutative tests for x != C ? (x > C - 1 ? 1 : -1) : 0467define i8 @scmp_from_select_ne_const_and_gt_commuted1(i32 %x) {468; CHECK-LABEL: define i8 @scmp_from_select_ne_const_and_gt_commuted1(469; CHECK-SAME: i32 [[X:%.*]]) {470; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 5)471; CHECK-NEXT: ret i8 [[R]]472;473 %ne = icmp ne i32 %x, 5474 %gt = icmp sgt i32 %x, 4475 %sel1 = select i1 %gt, i8 1, i8 -1476 %r = select i1 %ne, i8 %sel1, i8 0477 ret i8 %r478}479 480define i8 @scmp_from_select_ne_const_and_gt_commuted2(i32 %x) {481; CHECK-LABEL: define i8 @scmp_from_select_ne_const_and_gt_commuted2(482; CHECK-SAME: i32 [[X:%.*]]) {483; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 5)484; CHECK-NEXT: ret i8 [[R]]485;486 %ne = icmp ne i32 %x, 5487 %gt = icmp sgt i32 %x, 4488 %sel1 = select i1 %gt, i8 1, i8 -1489 %r = select i1 %ne, i8 %sel1, i8 0490 ret i8 %r491}492 493define i8 @scmp_from_select_ne_const_and_gt_commuted3(i32 %x) {494; CHECK-LABEL: define i8 @scmp_from_select_ne_const_and_gt_commuted3(495; CHECK-SAME: i32 [[X:%.*]]) {496; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 5)497; CHECK-NEXT: ret i8 [[R]]498;499 %ne = icmp ne i32 %x, 5500 %gt = icmp sgt i32 %x, 4501 %sel1 = select i1 %gt, i8 1, i8 -1502 %r = select i1 %ne, i8 %sel1, i8 0503 ret i8 %r504}505 506define <3 x i2> @scmp_unary_shuffle_ops(<3 x i8> %x, <3 x i8> %y) {507; CHECK-LABEL: define <3 x i2> @scmp_unary_shuffle_ops(508; CHECK-SAME: <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]) {509; CHECK-NEXT: [[TMP1:%.*]] = call <3 x i2> @llvm.scmp.v3i2.v3i8(<3 x i8> [[X]], <3 x i8> [[Y]])510; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x i2> [[TMP1]], <3 x i2> poison, <3 x i32> <i32 1, i32 0, i32 2>511; CHECK-NEXT: ret <3 x i2> [[R]]512;513 %sx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 1, i32 0, i32 2>514 %sy = shufflevector <3 x i8> %y, <3 x i8> poison, <3 x i32> <i32 1, i32 0, i32 2>515 %r = call <3 x i2> @llvm.scmp(<3 x i8> %sx, <3 x i8> %sy)516 ret <3 x i2> %r517}518 519define i32 @scmp_sgt_slt(i32 %a) {520; CHECK-LABEL: define i32 @scmp_sgt_slt(521; CHECK-SAME: i32 [[A:%.*]]) {522; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)523; CHECK-NEXT: ret i32 [[RETVAL_0]]524;525 %cmp = icmp sgt i32 %a, 0526 %cmp1 = icmp slt i32 %a, 0527 %. = select i1 %cmp1, i32 -1, i32 0528 %retval.0 = select i1 %cmp, i32 1, i32 %.529 ret i32 %retval.0530}531 532define i32 @scmp_zero_slt(i32 %a) {533; CHECK-LABEL: define i32 @scmp_zero_slt(534; CHECK-SAME: i32 [[A:%.*]]) {535; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)536; CHECK-NEXT: ret i32 [[RETVAL_0]]537;538 %cmp = icmp eq i32 %a, 0539 %cmp1.inv = icmp slt i32 %a, 1540 %. = select i1 %cmp1.inv, i32 -1, i32 1541 %retval.0 = select i1 %cmp, i32 0, i32 %.542 ret i32 %retval.0543}544 545define i32 @scmp_zero_sgt(i32 %a) {546; CHECK-LABEL: define i32 @scmp_zero_sgt(547; CHECK-SAME: i32 [[A:%.*]]) {548; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)549; CHECK-NEXT: ret i32 [[RETVAL_0]]550;551 %cmp = icmp eq i32 %a, 0552 %cmp1.inv = icmp sgt i32 %a, -1553 %. = select i1 %cmp1.inv, i32 1, i32 -1554 %retval.0 = select i1 %cmp, i32 0, i32 %.555 ret i32 %retval.0556}557 558 559define i32 @scmp_zero_sgt_1(i32 %a) {560; CHECK-LABEL: define i32 @scmp_zero_sgt_1(561; CHECK-SAME: i32 [[A:%.*]]) {562; CHECK-NEXT: [[COND2:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)563; CHECK-NEXT: ret i32 [[COND2]]564;565 %cmp = icmp eq i32 %a, 0566 %cmp1 = icmp sgt i32 %a, -1567 %cond = select i1 %cmp1, i32 1, i32 -1568 %cond2 = select i1 %cmp, i32 0, i32 %cond569 ret i32 %cond2570}571 572define i32 @scmp_zero_slt_1(i32 %a) {573; CHECK-LABEL: define i32 @scmp_zero_slt_1(574; CHECK-SAME: i32 [[A:%.*]]) {575; CHECK-NEXT: [[COND2:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)576; CHECK-NEXT: ret i32 [[COND2]]577;578 %cmp = icmp eq i32 %a, 0579 %cmp1 = icmp slt i32 %a, 1580 %cond = select i1 %cmp1, i32 -1, i32 1581 %cond2 = select i1 %cmp, i32 0, i32 %cond582 ret i32 %cond2583}584 585define i32 @scmp_zero_slt_neg(i32 %a) {586; CHECK-LABEL: define i32 @scmp_zero_slt_neg(587; CHECK-SAME: i32 [[A:%.*]]) {588; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0589; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -1590; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], i32 -1, i32 1591; CHECK-NEXT: [[COND2:%.*]] = select i1 [[CMP]], i32 0, i32 [[COND]]592; CHECK-NEXT: ret i32 [[COND2]]593;594 %cmp = icmp eq i32 %a, 0595 %cmp1 = icmp slt i32 %a, -1596 %cond = select i1 %cmp1, i32 -1, i32 1597 %cond2 = select i1 %cmp, i32 0, i32 %cond598 ret i32 %cond2599}600 601define i32 @scmp_zero_sgt_neg(i32 %a) {602; CHECK-LABEL: define i32 @scmp_zero_sgt_neg(603; CHECK-SAME: i32 [[A:%.*]]) {604; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0605; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], 1606; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], i32 1, i32 -1607; CHECK-NEXT: [[COND2:%.*]] = select i1 [[CMP]], i32 0, i32 [[COND]]608; CHECK-NEXT: ret i32 [[COND2]]609;610 %cmp = icmp eq i32 %a, 0611 %cmp1 = icmp sgt i32 %a, 1612 %cond = select i1 %cmp1, i32 1, i32 -1613 %cond2 = select i1 %cmp, i32 0, i32 %cond614 ret i32 %cond2615}616 617define i32 @ucmp_ugt_ult_neg(i32 %a) {618; CHECK-LABEL: define i32 @ucmp_ugt_ult_neg(619; CHECK-SAME: i32 [[A:%.*]]) {620; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ne i32 [[A]], 0621; CHECK-NEXT: [[RETVAL_0:%.*]] = zext i1 [[CMP_NOT]] to i32622; CHECK-NEXT: ret i32 [[RETVAL_0]]623;624 %cmp = icmp ugt i32 %a, 0625 %cmp1 = icmp ult i32 %a, 0626 %. = select i1 %cmp1, i32 -1, i32 0627 %retval.0 = select i1 %cmp, i32 1, i32 %.628 ret i32 %retval.0629}630 631define i32 @ucmp_zero_ult_neg(i32 %a) {632; CHECK-LABEL: define i32 @ucmp_zero_ult_neg(633; CHECK-SAME: i32 [[A:%.*]]) {634; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A]], 0635; CHECK-NEXT: [[RETVAL_0:%.*]] = zext i1 [[CMP]] to i32636; CHECK-NEXT: ret i32 [[RETVAL_0]]637;638 %cmp = icmp eq i32 %a, 0639 %cmp1.inv = icmp ult i32 %a, 1640 %. = select i1 %cmp1.inv, i32 -1, i32 1641 %retval.0 = select i1 %cmp, i32 0, i32 %.642 ret i32 %retval.0643}644 645define i32 @ucmp_zero_ugt_neg(i32 %a) {646; CHECK-LABEL: define i32 @ucmp_zero_ugt_neg(647; CHECK-SAME: i32 [[A:%.*]]) {648; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A]], 0649; CHECK-NEXT: [[RETVAL_0:%.*]] = sext i1 [[CMP]] to i32650; CHECK-NEXT: ret i32 [[RETVAL_0]]651;652 %cmp = icmp eq i32 %a, 0653 %cmp1.inv = icmp ugt i32 %a, -1654 %. = select i1 %cmp1.inv, i32 1, i32 -1655 %retval.0 = select i1 %cmp, i32 0, i32 %.656 ret i32 %retval.0657}658 659define i32 @scmp_sgt_slt_ab(i32 %a, i32 %b) {660; CHECK-LABEL: define i32 @scmp_sgt_slt_ab(661; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {662; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])663; CHECK-NEXT: ret i32 [[RETVAL_0]]664;665 %cmp = icmp sgt i32 %a, %b666 %cmp1 = icmp slt i32 %a, %b667 %. = select i1 %cmp1, i32 -1, i32 0668 %retval.0 = select i1 %cmp, i32 1, i32 %.669 ret i32 %retval.0670}671 672define i32 @scmp_zero_slt_ab(i32 %a, i32 %b) {673; CHECK-LABEL: define i32 @scmp_zero_slt_ab(674; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {675; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])676; CHECK-NEXT: ret i32 [[RETVAL_0]]677;678 %cmp = icmp eq i32 %a, %b679 %cmp1.inv = icmp slt i32 %a, %b680 %. = select i1 %cmp1.inv, i32 -1, i32 1681 %retval.0 = select i1 %cmp, i32 0, i32 %.682 ret i32 %retval.0683}684 685define i32 @scmp_zero_sgt_ab(i32 %a, i32 %b) {686; CHECK-LABEL: define i32 @scmp_zero_sgt_ab(687; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {688; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 [[B]])689; CHECK-NEXT: ret i32 [[RETVAL_0]]690;691 %cmp = icmp eq i32 %a, %b692 %cmp1.inv = icmp sgt i32 %a, %b693 %. = select i1 %cmp1.inv, i32 1, i32 -1694 %retval.0 = select i1 %cmp, i32 0, i32 %.695 ret i32 %retval.0696}697 698; Negative test: true value of outer select is not zero699define i8 @scmp_from_select_eq_and_gt_neg1(i32 %x, i32 %y) {700; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg1(701; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {702; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]703; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]704; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1705; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 5, i8 [[SEL1]]706; CHECK-NEXT: ret i8 [[R]]707;708 %eq = icmp eq i32 %x, %y709 %gt = icmp sgt i32 %x, %y710 %sel1 = select i1 %gt, i8 1, i8 -1711 %r = select i1 %eq, i8 5, i8 %sel1712 ret i8 %r713}714 715; Negative test: true value of inner select is not 1 or -1716define i8 @scmp_from_select_eq_and_gt_neg2(i32 %x, i32 %y) {717; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg2(718; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {719; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]720; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]721; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 2, i8 -1722; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]723; CHECK-NEXT: ret i8 [[R]]724;725 %eq = icmp eq i32 %x, %y726 %gt = icmp sgt i32 %x, %y727 %sel1 = select i1 %gt, i8 2, i8 -1728 %r = select i1 %eq, i8 0, i8 %sel1729 ret i8 %r730}731 732; Negative test: false value of inner select is not 1 or -1733define i8 @scmp_from_select_eq_and_gt_neg3(i32 %x, i32 %y) {734; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg3(735; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {736; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]737; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]738; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 22739; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]740; CHECK-NEXT: ret i8 [[R]]741;742 %eq = icmp eq i32 %x, %y743 %gt = icmp sgt i32 %x, %y744 %sel1 = select i1 %gt, i8 1, i8 22745 %r = select i1 %eq, i8 0, i8 %sel1746 ret i8 %r747}748 749define i32 @scmp_ashr(i32 %a) {750; CHECK-LABEL: define i32 @scmp_ashr(751; CHECK-SAME: i32 [[A:%.*]]) {752; CHECK-NEXT: [[RETVAL_0:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[A]], i32 0)753; CHECK-NEXT: ret i32 [[RETVAL_0]]754;755 %a.lobit = ashr i32 %a, 31756 %cmp.inv = icmp slt i32 %a, 1757 %retval.0 = select i1 %cmp.inv, i32 %a.lobit, i32 1758 ret i32 %retval.0759}760 761; select (icmp sgt X, 0), 1, ashr X, bitwidth-1 -> scmp(X, 0)762define i8 @scmp_ashr_sgt_pattern(i8 %a) {763; CHECK-LABEL: define i8 @scmp_ashr_sgt_pattern(764; CHECK-SAME: i8 [[A:%.*]]) {765; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i8(i8 [[A]], i8 0)766; CHECK-NEXT: ret i8 [[R]]767;768 %a.lobit = ashr i8 %a, 7769 %cmp = icmp sgt i8 %a, 0770 %retval = select i1 %cmp, i8 1, i8 %a.lobit771 ret i8 %retval772}773 774; select (icmp slt X, 1), ashr X, bitwidth-1, 1 -> scmp(X, 0)775define i8 @scmp_ashr_slt_pattern(i8 %a) {776; CHECK-LABEL: define i8 @scmp_ashr_slt_pattern(777; CHECK-SAME: i8 [[A:%.*]]) {778; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i8(i8 [[A]], i8 0)779; CHECK-NEXT: ret i8 [[R]]780;781 %a.lobit = ashr i8 %a, 7782 %cmp = icmp slt i8 %a, 1783 %retval = select i1 %cmp, i8 %a.lobit, i8 1784 ret i8 %retval785}786 787define i8 @scmp_ashr_slt_pattern_neg(i8 %a) {788; CHECK-LABEL: define i8 @scmp_ashr_slt_pattern_neg(789; CHECK-SAME: i8 [[A:%.*]]) {790; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr i8 [[A]], 4791; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], 1792; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[CMP]], i8 [[A_LOBIT]], i8 1793; CHECK-NEXT: ret i8 [[RETVAL]]794;795 %a.lobit = ashr i8 %a, 4796 %cmp = icmp slt i8 %a, 1797 %retval = select i1 %cmp, i8 %a.lobit, i8 1798 ret i8 %retval799}800