558 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 @ucmp_eq_0(i32 %x, i32 %y) {7; CHECK-LABEL: define i1 @ucmp_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.ucmp(i32 %x, i32 %y)13 %2 = icmp eq i8 %1, 014 ret i1 %215}16 17define i1 @ucmp_ne_0(i32 %x, i32 %y) {18; CHECK-LABEL: define i1 @ucmp_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.ucmp(i32 %x, i32 %y)24 %2 = icmp ne i8 %1, 025 ret i1 %226}27 28define i1 @ucmp_eq_1(i32 %x, i32 %y) {29; CHECK-LABEL: define i1 @ucmp_eq_1(30; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {31; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]32; CHECK-NEXT: ret i1 [[TMP2]]33;34 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)35 %2 = icmp eq i8 %1, 136 ret i1 %237}38 39define i1 @ucmp_ne_1(i32 %x, i32 %y) {40; CHECK-LABEL: define i1 @ucmp_ne_1(41; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {42; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]43; CHECK-NEXT: ret i1 [[TMP2]]44;45 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)46 %2 = icmp ne i8 %1, 147 ret i1 %248}49 50define i1 @ucmp_eq_negative_1(i32 %x, i32 %y) {51; CHECK-LABEL: define i1 @ucmp_eq_negative_1(52; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {53; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]54; CHECK-NEXT: ret i1 [[TMP2]]55;56 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)57 %2 = icmp eq i8 %1, -158 ret i1 %259}60 61define i1 @ucmp_ne_negative_1(i32 %x, i32 %y) {62; CHECK-LABEL: define i1 @ucmp_ne_negative_1(63; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {64; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]65; CHECK-NEXT: ret i1 [[TMP2]]66;67 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)68 %2 = icmp ne i8 %1, -169 ret i1 %270}71 72define i1 @ucmp_sgt_0(i32 %x, i32 %y) {73; CHECK-LABEL: define i1 @ucmp_sgt_0(74; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {75; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]76; CHECK-NEXT: ret i1 [[TMP2]]77;78 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)79 %2 = icmp sgt i8 %1, 080 ret i1 %281}82 83define i1 @ucmp_sgt_neg_1(i32 %x, i32 %y) {84; CHECK-LABEL: define i1 @ucmp_sgt_neg_1(85; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {86; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]87; CHECK-NEXT: ret i1 [[TMP2]]88;89 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)90 %2 = icmp sgt i8 %1, -191 ret i1 %292}93 94define i1 @ucmp_sge_0(i32 %x, i32 %y) {95; CHECK-LABEL: define i1 @ucmp_sge_0(96; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {97; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]98; CHECK-NEXT: ret i1 [[TMP2]]99;100 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)101 %2 = icmp sge i8 %1, 0102 ret i1 %2103}104 105define i1 @ucmp_sge_1(i32 %x, i32 %y) {106; CHECK-LABEL: define i1 @ucmp_sge_1(107; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {108; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]109; CHECK-NEXT: ret i1 [[TMP2]]110;111 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)112 %2 = icmp sge i8 %1, 1113 ret i1 %2114}115 116define i1 @ucmp_slt_0(i32 %x, i32 %y) {117; CHECK-LABEL: define i1 @ucmp_slt_0(118; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {119; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]120; CHECK-NEXT: ret i1 [[TMP2]]121;122 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)123 %2 = icmp slt i8 %1, 0124 ret i1 %2125}126 127define i1 @ucmp_slt_1(i32 %x, i32 %y) {128; CHECK-LABEL: define i1 @ucmp_slt_1(129; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {130; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]131; CHECK-NEXT: ret i1 [[TMP2]]132;133 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)134 %2 = icmp slt i8 %1, 1135 ret i1 %2136}137 138define i1 @ucmp_sle_0(i32 %x, i32 %y) {139; CHECK-LABEL: define i1 @ucmp_sle_0(140; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {141; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]142; CHECK-NEXT: ret i1 [[TMP2]]143;144 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)145 %2 = icmp sle i8 %1, 0146 ret i1 %2147}148 149define i1 @ucmp_sle_neg_1(i32 %x, i32 %y) {150; CHECK-LABEL: define i1 @ucmp_sle_neg_1(151; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {152; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]153; CHECK-NEXT: ret i1 [[TMP2]]154;155 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)156 %2 = icmp sle i8 %1, -1157 ret i1 %2158}159 160; ucmp(x, y) u< C => x u>= y when C u> 1 and C != -1161define i1 @ucmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) {162; CHECK-LABEL: define i1 @ucmp_ult_positive_const_gt_than_1_lt_than_umax(163; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {164; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[X]], [[Y]]165; CHECK-NEXT: ret i1 [[TMP1]]166;167 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)168 %2 = icmp ult i8 %1, 4169 ret i1 %2170}171 172; ucmp(x, y) u> C => x u< 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 ult i32 [[X]], [[Y]]177; CHECK-NEXT: ret i1 [[TMP2]]178;179 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)180 %2 = icmp ugt i8 %1, 12181 ret i1 %2182}183 184; ========== Fold -ucmp(x, y) => ucmp(y, x) ==========185define i8 @ucmp_negated(i32 %x, i32 %y) {186; CHECK-LABEL: define i8 @ucmp_negated(187; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {188; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[Y]], i32 [[X]])189; CHECK-NEXT: ret i8 [[TMP2]]190;191 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)192 %2 = sub i8 0, %1193 ret i8 %2194}195 196; Negative test: do not fold if the original ucmp result is already used197define i8 @ucmp_negated_multiuse(i32 %x, i32 %y) {198; CHECK-LABEL: define i8 @ucmp_negated_multiuse(199; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {200; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])201; CHECK-NEXT: call void @use(i8 [[TMP1]])202; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i8 0, [[TMP1]]203; CHECK-NEXT: ret i8 [[TMP2]]204;205 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)206 call void @use(i8 %1)207 %2 = sub i8 0, %1208 ret i8 %2209}210 211; Fold ((x u< y) ? -1 : (x != y)) into ucmp(x, y)212define i8 @ucmp_from_select_lt(i32 %x, i32 %y) {213; CHECK-LABEL: define i8 @ucmp_from_select_lt(214; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {215; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])216; CHECK-NEXT: ret i8 [[R]]217;218 %ne_bool = icmp ne i32 %x, %y219 %ne = zext i1 %ne_bool to i8220 %lt = icmp ult i32 %x, %y221 %r = select i1 %lt, i8 -1, i8 %ne222 ret i8 %r223}224 225; Fold (x u< y) ? -1 : zext(x u> y) into ucmp(x, y)226define i8 @ucmp_from_select_lt_and_gt(i32 %x, i32 %y) {227; CHECK-LABEL: define i8 @ucmp_from_select_lt_and_gt(228; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {229; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])230; CHECK-NEXT: ret i8 [[R]]231;232 %gt_bool = icmp ugt i32 %x, %y233 %gt = zext i1 %gt_bool to i8234 %lt = icmp ult i32 %x, %y235 %r = select i1 %lt, i8 -1, i8 %gt236 ret i8 %r237}238 239; Vector version240define <4 x i8> @ucmp_from_select_vec_lt(<4 x i32> %x, <4 x i32> %y) {241; CHECK-LABEL: define <4 x i8> @ucmp_from_select_vec_lt(242; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {243; CHECK-NEXT: [[R:%.*]] = call <4 x i8> @llvm.ucmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])244; CHECK-NEXT: ret <4 x i8> [[R]]245;246 %ne_bool = icmp ne <4 x i32> %x, %y247 %ne = zext <4 x i1> %ne_bool to <4 x i8>248 %lt = icmp ult <4 x i32> %x, %y249 %r = select <4 x i1> %lt, <4 x i8> splat(i8 -1), <4 x i8> %ne250 ret <4 x i8> %r251}252 253; Commuted operands254define i8 @ucmp_from_select_lt_commuted_ops1(i32 %x, i32 %y) {255; CHECK-LABEL: define i8 @ucmp_from_select_lt_commuted_ops1(256; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {257; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])258; CHECK-NEXT: ret i8 [[R]]259;260 %ne_bool = icmp ne i32 %y, %x261 %ne = zext i1 %ne_bool to i8262 %lt = icmp ult i32 %x, %y263 %r = select i1 %lt, i8 -1, i8 %ne264 ret i8 %r265}266 267define i8 @ucmp_from_select_lt_commuted_ops2(i32 %x, i32 %y) {268; CHECK-LABEL: define i8 @ucmp_from_select_lt_commuted_ops2(269; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {270; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])271; CHECK-NEXT: ret i8 [[R]]272;273 %ne_bool = icmp ne i32 %x, %y274 %ne = zext i1 %ne_bool to i8275 %lt = icmp ugt i32 %y, %x276 %r = select i1 %lt, i8 -1, i8 %ne277 ret i8 %r278}279 280; Negative test: false value of the select is not `icmp ne x, y`281define i8 @ucmp_from_select_lt_neg1(i32 %x, i32 %y) {282; CHECK-LABEL: define i8 @ucmp_from_select_lt_neg1(283; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {284; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp eq i32 [[X]], [[Y]]285; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8286; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X]], [[Y]]287; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]288; CHECK-NEXT: ret i8 [[R]]289;290 %ne_bool = icmp eq i32 %x, %y291 %ne = zext i1 %ne_bool to i8292 %lt = icmp ult i32 %x, %y293 %r = select i1 %lt, i8 -1, i8 %ne294 ret i8 %r295}296 297; Negative test: true value of select is not -1298define i8 @ucmp_from_select_lt_neg2(i32 %x, i32 %y) {299; CHECK-LABEL: define i8 @ucmp_from_select_lt_neg2(300; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {301; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]302; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8303; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X]], [[Y]]304; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 2, i8 [[NE]]305; CHECK-NEXT: ret i8 [[R]]306;307 %ne_bool = icmp ne i32 %x, %y308 %ne = zext i1 %ne_bool to i8309 %lt = icmp ult i32 %x, %y310 %r = select i1 %lt, i8 2, i8 %ne311 ret i8 %r312}313 314; Negative test: false value of select is sign-extended instead of zero-extended315define i8 @ucmp_from_select_lt_neg3(i32 %x, i32 %y) {316; CHECK-LABEL: define i8 @ucmp_from_select_lt_neg3(317; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {318; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]319; CHECK-NEXT: [[R:%.*]] = sext i1 [[NE_BOOL]] to i8320; CHECK-NEXT: ret i8 [[R]]321;322 %ne_bool = icmp ne i32 %x, %y323 %ne = sext i1 %ne_bool to i8324 %lt = icmp ult i32 %x, %y325 %r = select i1 %lt, i8 -1, i8 %ne326 ret i8 %r327}328 329; Negative test: condition of select is not (x u< y)330define i8 @ucmp_from_select_lt_neg4(i32 %x, i32 %y) {331; CHECK-LABEL: define i8 @ucmp_from_select_lt_neg4(332; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {333; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]334; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8335; CHECK-NEXT: [[LT_NOT:%.*]] = icmp ugt i32 [[X]], [[Y]]336; CHECK-NEXT: [[R:%.*]] = select i1 [[LT_NOT]], i8 [[NE]], i8 -1337; CHECK-NEXT: ret i8 [[R]]338;339 %ne_bool = icmp ne i32 %x, %y340 %ne = zext i1 %ne_bool to i8341 %lt = icmp ule i32 %x, %y342 %r = select i1 %lt, i8 -1, i8 %ne343 ret i8 %r344}345 346; Fold (x u<= y) ? sext(x != y) : 1 into ucmp(x, y)347define i8 @ucmp_from_select_le(i32 %x, i32 %y) {348; CHECK-LABEL: define i8 @ucmp_from_select_le(349; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {350; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])351; CHECK-NEXT: ret i8 [[R]]352;353 %ne_bool = icmp ne i32 %x, %y354 %ne = sext i1 %ne_bool to i8355 %le = icmp ule i32 %x, %y356 %r = select i1 %le, i8 %ne, i8 1357 ret i8 %r358}359 360; Negative test: condition of select is not (x u<= y)361define i8 @ucmp_from_select_le_neg1(i32 %x, i32 %y) {362; CHECK-LABEL: define i8 @ucmp_from_select_le_neg1(363; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {364; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ult i32 [[X]], [[Y]]365; CHECK-NEXT: [[NE:%.*]] = sext i1 [[NE_BOOL]] to i8366; CHECK-NEXT: [[LE_NOT:%.*]] = icmp ult i32 [[X]], [[Y]]367; CHECK-NEXT: [[R:%.*]] = select i1 [[LE_NOT]], i8 1, i8 [[NE]]368; CHECK-NEXT: ret i8 [[R]]369;370 %ne_bool = icmp ult i32 %x, %y371 %ne = sext i1 %ne_bool to i8372 %le = icmp uge i32 %x, %y373 %r = select i1 %le, i8 %ne, i8 1374 ret i8 %r375}376 377; Negative test: true value of select is zero-extended instead of sign-extended378define i8 @ucmp_from_select_le_neg2(i32 %x, i32 %y) {379; CHECK-LABEL: define i8 @ucmp_from_select_le_neg2(380; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {381; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]382; CHECK-NEXT: [[R:%.*]] = zext i1 [[NE_BOOL]] to i8383; CHECK-NEXT: ret i8 [[R]]384;385 %ne_bool = icmp ne i32 %x, %y386 %ne = zext i1 %ne_bool to i8387 %le = icmp ule i32 %x, %y388 %r = select i1 %le, i8 %ne, i8 1389 ret i8 %r390}391 392; Negative test: true value is not x != y393define i8 @ucmp_from_select_le_neg3(i32 %x, i32 %y) {394; CHECK-LABEL: define i8 @ucmp_from_select_le_neg3(395; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {396; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp sgt i32 [[X]], [[Y]]397; CHECK-NEXT: [[NE:%.*]] = sext i1 [[NE_BOOL]] to i8398; CHECK-NEXT: [[LE_NOT:%.*]] = icmp ugt i32 [[X]], [[Y]]399; CHECK-NEXT: [[R:%.*]] = select i1 [[LE_NOT]], i8 1, i8 [[NE]]400; CHECK-NEXT: ret i8 [[R]]401;402 %ne_bool = icmp sgt i32 %x, %y403 %ne = sext i1 %ne_bool to i8404 %le = icmp ule i32 %x, %y405 %r = select i1 %le, i8 %ne, i8 1406 ret i8 %r407}408 409; Negative test: false value is not 1410define i8 @ucmp_from_select_le_neg4(i32 %x, i32 %y) {411; CHECK-LABEL: define i8 @ucmp_from_select_le_neg4(412; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {413; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]414; CHECK-NEXT: [[R:%.*]] = sext i1 [[NE_BOOL]] to i8415; CHECK-NEXT: ret i8 [[R]]416;417 %ne_bool = icmp ne i32 %x, %y418 %ne = sext i1 %ne_bool to i8419 %le = icmp ule i32 %x, %y420 %r = select i1 %le, i8 %ne, i8 -1421 ret i8 %r422}423 424; Fold (x u>= y) ? zext(x != y) : -1 into ucmp(x, y)425define i8 @ucmp_from_select_ge(i32 %x, i32 %y) {426; CHECK-LABEL: define i8 @ucmp_from_select_ge(427; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {428; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])429; CHECK-NEXT: ret i8 [[R]]430;431 %ne_bool = icmp ne i32 %x, %y432 %ne = zext i1 %ne_bool to i8433 %ge = icmp uge i32 %x, %y434 %r = select i1 %ge, i8 %ne, i8 -1435 ret i8 %r436}437 438; Commuted operands439define i8 @ucmp_from_select_ge_commuted_ops1(i32 %x, i32 %y) {440; CHECK-LABEL: define i8 @ucmp_from_select_ge_commuted_ops1(441; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {442; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])443; CHECK-NEXT: ret i8 [[R]]444;445 %ne_bool = icmp ne i32 %y, %x446 %ne = zext i1 %ne_bool to i8447 %ge = icmp uge i32 %x, %y448 %r = select i1 %ge, i8 %ne, i8 -1449 ret i8 %r450}451 452define i8 @ucmp_from_select_ge_commuted_ops2(i32 %x, i32 %y) {453; CHECK-LABEL: define i8 @ucmp_from_select_ge_commuted_ops2(454; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {455; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])456; CHECK-NEXT: ret i8 [[R]]457;458 %ne_bool = icmp ne i32 %x, %y459 %ne = zext i1 %ne_bool to i8460 %ge = icmp ule i32 %y, %x461 %r = select i1 %ge, i8 %ne, i8 -1462 ret i8 %r463}464 465; Negative test: condition is not x u>= y466define i8 @ucmp_from_select_ge_neg1(i32 %x, i32 %y) {467; CHECK-LABEL: define i8 @ucmp_from_select_ge_neg1(468; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {469; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]470; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8471; CHECK-NEXT: [[GE:%.*]] = icmp ult i32 [[X]], [[Y]]472; CHECK-NEXT: [[R:%.*]] = select i1 [[GE]], i8 [[NE]], i8 -1473; CHECK-NEXT: ret i8 [[R]]474;475 %ne_bool = icmp ne i32 %x, %y476 %ne = zext i1 %ne_bool to i8477 %ge = icmp ult i32 %x, %y478 %r = select i1 %ge, i8 %ne, i8 -1479 ret i8 %r480}481 482; Negative test: true value is sign-extended instead of zero-extended483define i8 @ucmp_from_select_ge_neg2(i32 %x, i32 %y) {484; CHECK-LABEL: define i8 @ucmp_from_select_ge_neg2(485; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {486; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]487; CHECK-NEXT: [[R:%.*]] = sext i1 [[NE_BOOL]] to i8488; CHECK-NEXT: ret i8 [[R]]489;490 %ne_bool = icmp ne i32 %x, %y491 %ne = sext i1 %ne_bool to i8492 %ge = icmp uge i32 %x, %y493 %r = select i1 %ge, i8 %ne, i8 -1494 ret i8 %r495}496 497; Negative test: true value is not x != y498define i8 @ucmp_from_select_ge_neg3(i32 %x, i32 %y) {499; CHECK-LABEL: define i8 @ucmp_from_select_ge_neg3(500; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {501; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp sgt i32 [[X]], [[Y]]502; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8503; CHECK-NEXT: [[GE_NOT:%.*]] = icmp ult i32 [[X]], [[Y]]504; CHECK-NEXT: [[R:%.*]] = select i1 [[GE_NOT]], i8 -1, i8 [[NE]]505; CHECK-NEXT: ret i8 [[R]]506;507 %ne_bool = icmp sgt i32 %x, %y508 %ne = zext i1 %ne_bool to i8509 %ge = icmp uge i32 %x, %y510 %r = select i1 %ge, i8 %ne, i8 -1511 ret i8 %r512}513 514; Negative test: false value is not -1515define i8 @ucmp_from_select_ge_neg4(i32 %x, i32 %y) {516; CHECK-LABEL: define i8 @ucmp_from_select_ge_neg4(517; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {518; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]519; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8520; CHECK-NEXT: [[GE_NOT:%.*]] = icmp ult i32 [[X]], [[Y]]521; CHECK-NEXT: [[R:%.*]] = select i1 [[GE_NOT]], i8 3, i8 [[NE]]522; CHECK-NEXT: ret i8 [[R]]523;524 %ne_bool = icmp ne i32 %x, %y525 %ne = zext i1 %ne_bool to i8526 %ge = icmp uge i32 %x, %y527 %r = select i1 %ge, i8 %ne, i8 3528 ret i8 %r529}530 531; Fold (x > y) ? 1 : sext(x < y)532define i8 @ucmp_from_select_gt_and_lt(i32 %x, i32 %y) {533; CHECK-LABEL: define i8 @ucmp_from_select_gt_and_lt(534; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {535; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])536; CHECK-NEXT: ret i8 [[R]]537;538 %lt_bool = icmp ult i32 %x, %y539 %lt = sext i1 %lt_bool to i8540 %gt = icmp ugt i32 %x, %y541 %r = select i1 %gt, i8 1, i8 %lt542 ret i8 %r543}544 545; (x == y) ? 0 : (x u> y ? 1 : -1) into ucmp(x, y)546define i8 @scmp_from_select_eq_and_gt(i32 %x, i32 %y) {547; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(548; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {549; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])550; CHECK-NEXT: ret i8 [[R]]551;552 %eq = icmp eq i32 %x, %y553 %gt = icmp ugt i32 %x, %y554 %sel1 = select i1 %gt, i8 1, i8 -1555 %r = select i1 %eq, i8 0, i8 %sel1556 ret i8 %r557}558