brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.3 KiB · 2ae062c Raw
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