294 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4; Tests for select to scmp5 6define i32 @scmp_x_0_inverted(i32 %x) {7; CHECK-LABEL: define i32 @scmp_x_0_inverted(8; CHECK-SAME: i32 [[X:%.*]]) {9; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 0)10; CHECK-NEXT: ret i32 [[TMP1]]11;12 %2 = icmp ne i32 %x, 013 %3 = zext i1 %2 to i3214 %4 = icmp sgt i32 %x, -115 %5 = select i1 %4, i32 %3, i32 -116 ret i32 %517}18 19; y = -1020define i32 @scmp_x_0_inverted_const_neg10(i32 %x) {21; CHECK-LABEL: define i32 @scmp_x_0_inverted_const_neg10(22; CHECK-SAME: i32 [[X:%.*]]) {23; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 -10)24; CHECK-NEXT: ret i32 [[TMP1]]25;26 %1 = icmp ne i32 %x, -1027 %2 = zext i1 %1 to i3228 %3 = icmp sgt i32 %x, -1129 %4 = select i1 %3, i32 %2, i32 -130 ret i32 %431}32 33; y = 7 (i8)34define i8 @scmp_x_0_inverted_i8(i8 %x) {35; CHECK-LABEL: define i8 @scmp_x_0_inverted_i8(36; CHECK-SAME: i8 [[X:%.*]]) {37; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i8(i8 [[X]], i8 7)38; CHECK-NEXT: ret i8 [[TMP1]]39;40 %1 = icmp ne i8 %x, 741 %2 = zext i1 %1 to i842 %3 = icmp sgt i8 %x, 643 %4 = select i1 %3, i8 %2, i8 -144 ret i8 %445}46 47; scmp using ints of two kinds- i32 and i6448define i32 @scmp_x_0_inverted_i64_neq(i32 %x) {49; CHECK-LABEL: define i32 @scmp_x_0_inverted_i64_neq(50; CHECK-SAME: i32 [[X:%.*]]) {51; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.scmp.i64.i32(i32 [[X]], i32 0)52; CHECK-NEXT: [[RET:%.*]] = trunc i64 [[SEL]] to i3253; CHECK-NEXT: ret i32 [[RET]]54;55 %x64 = sext i32 %x to i6456 %cmp1 = icmp ne i64 %x64, 057 %zext = zext i1 %cmp1 to i6458 %cmp2 = icmp sgt i64 %x64, -159 %sel = select i1 %cmp2, i64 %zext, i64 -160 %ret = trunc i64 %sel to i3261 ret i32 %ret62}63 64; Same example as previous but with inequality65define i32 @scmp_x_0_inverted_i64_sgt(i32 %x) {66; CHECK-LABEL: define i32 @scmp_x_0_inverted_i64_sgt(67; CHECK-SAME: i32 [[X:%.*]]) {68; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.scmp.i64.i32(i32 [[X]], i32 0)69; CHECK-NEXT: [[RET:%.*]] = trunc i64 [[SEL]] to i3270; CHECK-NEXT: ret i32 [[RET]]71;72 %x64 = sext i32 %x to i6473 %cmp1 = icmp sgt i64 %x64, 074 %zext = zext i1 %cmp1 to i6475 %cmp2 = icmp sgt i64 %x64, -176 %sel = select i1 %cmp2, i64 %zext, i64 -177 %ret = trunc i64 %sel to i3278 ret i32 %ret79}80 81; y = -100082define i32 @scmp_x_0_inverted_const_neg1000(i32 %x) {83; CHECK-LABEL: define i32 @scmp_x_0_inverted_const_neg1000(84; CHECK-SAME: i32 [[X:%.*]]) {85; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 -1000)86; CHECK-NEXT: ret i32 [[TMP1]]87;88 %1 = icmp sgt i32 %x, -100089 %2 = zext i1 %1 to i3290 %3 = icmp sgt i32 %x, -100191 %4 = select i1 %3, i32 %2, i32 -192 ret i32 %493}94 95; y = 172996define i32 @scmp_x_0_inverted_const_1729_sgt(i32 %x) {97; CHECK-LABEL: define i32 @scmp_x_0_inverted_const_1729_sgt(98; CHECK-SAME: i32 [[X:%.*]]) {99; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 1729)100; CHECK-NEXT: ret i32 [[TMP1]]101;102 %1 = icmp sgt i32 %x, 1729103 %2 = zext i1 %1 to i32104 %3 = icmp sgt i32 %x, 1728105 %4 = select i1 %3, i32 %2, i32 -1106 ret i32 %4107}108 109; ucmp with 10110define i32 @ucmp_x_10_inverted(i32 %x) {111; CHECK-LABEL: define i32 @ucmp_x_10_inverted(112; CHECK-SAME: i32 [[X:%.*]]) {113; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ucmp.i32.i32(i32 [[X]], i32 10)114; CHECK-NEXT: ret i32 [[TMP1]]115;116 %1 = icmp ne i32 %x, 10117 %2 = zext i1 %1 to i32118 %3 = icmp ugt i32 %x, 9119 %4 = select i1 %3, i32 %2, i32 -1120 ret i32 %4121}122 123; ucmp with -3, wraps around124define i32 @ucmp_x_neg1_inverted(i32 %x) {125; CHECK-LABEL: define i32 @ucmp_x_neg1_inverted(126; CHECK-SAME: i32 [[X:%.*]]) {127; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ucmp.i32.i32(i32 [[X]], i32 -3)128; CHECK-NEXT: ret i32 [[TMP1]]129;130 %1 = icmp ne i32 %x, -3131 %2 = zext i1 %1 to i32132 %3 = icmp ugt i32 %x, -4133 %4 = select i1 %3, i32 %2, i32 -1134 ret i32 %4135}136 137; ucmp with -4, wraps around138define i8 @ucmp_x_neg4_i8_ugt(i8 %x) {139; CHECK-LABEL: define i8 @ucmp_x_neg4_i8_ugt(140; CHECK-SAME: i8 [[X:%.*]]) {141; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i8(i8 [[X]], i8 -4)142; CHECK-NEXT: ret i8 [[TMP1]]143;144 %1 = icmp ugt i8 %x, -4145 %2 = zext i1 %1 to i8146 %3 = icmp ugt i8 %x, -5147 %4 = select i1 %3, i8 %2, i8 -1148 ret i8 %4149}150 151; Vector tests152 153; Test with splat vec154define <4 x i32> @scmp_x_0_inverted_splat_vec(<4 x i32> %x) {155; CHECK-LABEL: define <4 x i32> @scmp_x_0_inverted_splat_vec(156; CHECK-SAME: <4 x i32> [[X:%.*]]) {157; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.scmp.v4i32.v4i32(<4 x i32> [[X]], <4 x i32> zeroinitializer)158; CHECK-NEXT: ret <4 x i32> [[TMP1]]159;160 %2 = icmp ne <4 x i32> %x, zeroinitializer161 %3 = zext <4 x i1> %2 to <4 x i32>162 %4 = icmp sgt <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>163 %5 = select <4 x i1> %4, <4 x i32> %3, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>164 ret <4 x i32> %5165}166 167; Test with non-splat vector and different bitwidth168define <4 x i32> @non_splat_vec_scmp_diff_bitwidth(<4 x i32> %x) {169; CHECK-LABEL: define <4 x i32> @non_splat_vec_scmp_diff_bitwidth(170; CHECK-SAME: <4 x i32> [[X:%.*]]) {171; CHECK-NEXT: [[SEL:%.*]] = call <4 x i64> @llvm.scmp.v4i64.v4i32(<4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 -1, i32 5>)172; CHECK-NEXT: [[RET:%.*]] = trunc <4 x i64> [[SEL]] to <4 x i32>173; CHECK-NEXT: ret <4 x i32> [[RET]]174;175 %x64 = sext <4 x i32> %x to <4 x i64>176 %cmp1 = icmp slt <4 x i64> %x64, <i64 0, i64 1, i64 -1, i64 5>177 %sext = sext <4 x i1> %cmp1 to <4 x i64>178 %cmp2 = icmp slt <4 x i64> %x64, <i64 1, i64 2, i64 0, i64 6>179 %sel = select <4 x i1> %cmp2, <4 x i64> %sext, <4 x i64> <i64 1, i64 1, i64 1, i64 1>180 %ret = trunc <4 x i64> %sel to <4 x i32>181 ret <4 x i32> %ret182}183 184; Negative examples185 186; Not scmp due to wrong RHS of the predicate187define i32 @scmp_ne_0(i32 %0) {188; CHECK-LABEL: define i32 @scmp_ne_0(189; CHECK-SAME: i32 [[TMP0:%.*]]) {190; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0]], 0191; CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32192; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP0]], 1193; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP4]], i32 [[TMP3]], i32 -1194; CHECK-NEXT: ret i32 [[TMP5]]195;196 %2 = icmp ne i32 %0, 0197 %3 = zext i1 %2 to i32198 %4 = icmp sgt i32 %0, 1199 %5 = select i1 %4, i32 %3, i32 -1200 ret i32 %5201}202 203; y = 0 with unsigned compare but RHS wraps204define i32 @ucmp_x_0_inverted(i32 %x) {205; CHECK-LABEL: define i32 @ucmp_x_0_inverted(206; CHECK-SAME: i32 [[X:%.*]]) {207; CHECK-NEXT: ret i32 -1208;209 %1 = icmp ne i32 %x, 0210 %2 = zext i1 %1 to i32211 %3 = icmp ugt i32 %x, -1212 %4 = select i1 %3, i32 %2, i32 -1213 ret i32 %4214}215 216; Don't fold with INT32_MIN217define i32 @scmp_x_0_inverted_const_min(i32 %x) {218; CHECK-LABEL: define i32 @scmp_x_0_inverted_const_min(219; CHECK-SAME: i32 [[X:%.*]]) {220; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648221; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i32222; CHECK-NEXT: ret i32 [[TMP2]]223;224 %1 = icmp ne i32 %x, -2147483648225 %2 = zext i1 %1 to i32226 %3 = icmp sge i32 %x, -2147483648227 %4 = select i1 %3, i32 %2, i32 -1228 ret i32 %4229}230 231; Unsigned cmp of zext of i32 with i64 -1 should always be -1232define i32 @ucmp_x_0_inverted_i64_ugt(i32 %x) {233; CHECK-LABEL: define i32 @ucmp_x_0_inverted_i64_ugt(234; CHECK-SAME: i32 [[X:%.*]]) {235; CHECK-NEXT: ret i32 -1236;237 %x64 = zext i32 %x to i64238 %cmp1 = icmp ugt i64 %x64, 0239 %zext = zext i1 %cmp1 to i64240 %cmp2 = icmp ugt i64 %x64, -1241 %sel = select i1 %cmp2, i64 %zext, i64 -1242 %ret = trunc i64 %sel to i32243 ret i32 %ret244}245 246; y = 4294967295 (UINT32_MAX), simply sign extend neq247define i32 @ucmp_x_const_u32max(i32 %x) {248; CHECK-LABEL: define i32 @ucmp_x_const_u32max(249; CHECK-SAME: i32 [[X:%.*]]) {250; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -1251; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[TMP1]] to i32252; CHECK-NEXT: ret i32 [[TMP2]]253;254 %1 = icmp ugt i32 %x, 4294967295255 %2 = zext i1 %1 to i32256 %3 = icmp ugt i32 %x, 4294967294257 %4 = select i1 %3, i32 %2, i32 -1258 ret i32 %4259}260 261; Don't fold with different signedness262define i32 @different_signedness_neg(i32 %x) {263; CHECK-LABEL: define i32 @different_signedness_neg(264; CHECK-SAME: i32 [[X:%.*]]) {265; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X]], -10266; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i32267; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[X]], -11268; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 -1269; CHECK-NEXT: ret i32 [[TMP4]]270;271 %1 = icmp ugt i32 %x, -10272 %2 = zext i1 %1 to i32273 %3 = icmp sgt i32 %x, -11274 %4 = select i1 %3, i32 %2, i32 -1275 ret i32 %4276}277 278; Test with wrong false value279define <4 x i32> @scmp_x_0_inverted_vec(<4 x i32> %x) {280; CHECK-LABEL: define <4 x i32> @scmp_x_0_inverted_vec(281; CHECK-SAME: <4 x i32> [[X:%.*]]) {282; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[X]], zeroinitializer283; CHECK-NEXT: [[TMP2:%.*]] = zext <4 x i1> [[TMP1]] to <4 x i32>284; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt <4 x i32> [[X]], splat (i32 -1)285; CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[TMP2]], <4 x i32> <i32 -1, i32 -2, i32 -1, i32 -1>286; CHECK-NEXT: ret <4 x i32> [[TMP4]]287;288 %2 = icmp ne <4 x i32> %x, zeroinitializer289 %3 = zext <4 x i1> %2 to <4 x i32>290 %4 = icmp sgt <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>291 %5 = select <4 x i1> %4, <4 x i32> %3, <4 x i32> <i32 -1, i32 -2, i32 -1, i32 -1>292 ret <4 x i32> %5293}294