235 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; https://bugs.llvm.org/show_bug.cgi?id=381495 6; Pattern:7; ((%x << MaskedBits) a>> MaskedBits) != %x8; Should be transformed into:9; (add %x, (1 << (KeptBits-1))) u>= (1 << KeptBits)10; Where KeptBits = bitwidth(%x) - MaskedBits11 12; ============================================================================ ;13; Basic positive tests14; ============================================================================ ;15 16define i1 @p0(i8 %x) {17; CHECK-LABEL: @p0(18; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -419; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], -820; CHECK-NEXT: ret i1 [[TMP2]]21;22 %tmp0 = shl i8 %x, 523 %tmp1 = ashr exact i8 %tmp0, 524 %tmp2 = icmp ne i8 %tmp1, %x25 ret i1 %tmp226}27 28; Big unusual bit width, https://bugs.llvm.org/show_bug.cgi?id=3820429define i1 @pb(i65 %x) {30; CHECK-LABEL: @pb(31; CHECK-NEXT: [[TMP1:%.*]] = add i65 [[X:%.*]], 922337203685477580832; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i65 [[TMP1]], 033; CHECK-NEXT: ret i1 [[TMP2]]34;35 %tmp0 = shl i65 %x, 136 %tmp1 = ashr exact i65 %tmp0, 137 %tmp2 = icmp ne i65 %x, %tmp138 ret i1 %tmp239}40 41; ============================================================================ ;42; Vector tests43; ============================================================================ ;44 45define <2 x i1> @p1_vec_splat(<2 x i8> %x) {46; CHECK-LABEL: @p1_vec_splat(47; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], splat (i8 -4)48; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i8> [[TMP1]], splat (i8 -8)49; CHECK-NEXT: ret <2 x i1> [[TMP2]]50;51 %tmp0 = shl <2 x i8> %x, <i8 5, i8 5>52 %tmp1 = ashr exact <2 x i8> %tmp0, <i8 5, i8 5>53 %tmp2 = icmp ne <2 x i8> %tmp1, %x54 ret <2 x i1> %tmp255}56 57define <2 x i1> @p2_vec_nonsplat(<2 x i8> %x) {58; CHECK-LABEL: @p2_vec_nonsplat(59; CHECK-NEXT: [[TMP0:%.*]] = shl <2 x i8> [[X:%.*]], <i8 5, i8 6>60; CHECK-NEXT: [[TMP1:%.*]] = ashr exact <2 x i8> [[TMP0]], <i8 5, i8 6>61; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i8> [[TMP1]], [[X]]62; CHECK-NEXT: ret <2 x i1> [[TMP2]]63;64 %tmp0 = shl <2 x i8> %x, <i8 5, i8 6>65 %tmp1 = ashr exact <2 x i8> %tmp0, <i8 5, i8 6>66 %tmp2 = icmp ne <2 x i8> %tmp1, %x67 ret <2 x i1> %tmp268}69 70define <3 x i1> @p3_vec_undef0(<3 x i8> %x) {71; CHECK-LABEL: @p3_vec_undef0(72; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i8> [[X:%.*]], <i8 5, i8 undef, i8 5>73; CHECK-NEXT: [[TMP1:%.*]] = ashr exact <3 x i8> [[TMP0]], splat (i8 5)74; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <3 x i8> [[TMP1]], [[X]]75; CHECK-NEXT: ret <3 x i1> [[TMP2]]76;77 %tmp0 = shl <3 x i8> %x, <i8 5, i8 undef, i8 5>78 %tmp1 = ashr exact <3 x i8> %tmp0, <i8 5, i8 5, i8 5>79 %tmp2 = icmp ne <3 x i8> %tmp1, %x80 ret <3 x i1> %tmp281}82 83define <3 x i1> @p4_vec_undef1(<3 x i8> %x) {84; CHECK-LABEL: @p4_vec_undef1(85; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i8> [[X:%.*]], splat (i8 5)86; CHECK-NEXT: [[TMP1:%.*]] = ashr exact <3 x i8> [[TMP0]], <i8 5, i8 undef, i8 5>87; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <3 x i8> [[TMP1]], [[X]]88; CHECK-NEXT: ret <3 x i1> [[TMP2]]89;90 %tmp0 = shl <3 x i8> %x, <i8 5, i8 5, i8 5>91 %tmp1 = ashr exact <3 x i8> %tmp0, <i8 5, i8 undef, i8 5>92 %tmp2 = icmp ne <3 x i8> %tmp1, %x93 ret <3 x i1> %tmp294}95 96define <3 x i1> @p5_vec_undef2(<3 x i8> %x) {97; CHECK-LABEL: @p5_vec_undef2(98; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i8> [[X:%.*]], <i8 5, i8 undef, i8 5>99; CHECK-NEXT: [[TMP1:%.*]] = ashr exact <3 x i8> [[TMP0]], <i8 5, i8 undef, i8 5>100; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <3 x i8> [[TMP1]], [[X]]101; CHECK-NEXT: ret <3 x i1> [[TMP2]]102;103 %tmp0 = shl <3 x i8> %x, <i8 5, i8 undef, i8 5>104 %tmp1 = ashr exact <3 x i8> %tmp0, <i8 5, i8 undef, i8 5>105 %tmp2 = icmp ne <3 x i8> %tmp1, %x106 ret <3 x i1> %tmp2107}108 109; ============================================================================ ;110; Commutativity tests.111; ============================================================================ ;112 113declare i8 @gen8()114 115define i1 @c0() {116; CHECK-LABEL: @c0(117; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()118; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -4119; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], -8120; CHECK-NEXT: ret i1 [[TMP2]]121;122 %x = call i8 @gen8()123 %tmp0 = shl i8 %x, 5124 %tmp1 = ashr exact i8 %tmp0, 5125 %tmp2 = icmp ne i8 %x, %tmp1 ; swapped order126 ret i1 %tmp2127}128 129; ============================================================================ ;130; One-use tests.131; ============================================================================ ;132 133declare void @use8(i8)134 135define i1 @n_oneuse0(i8 %x) {136; CHECK-LABEL: @n_oneuse0(137; CHECK-NEXT: [[TMP0:%.*]] = shl i8 [[X:%.*]], 5138; CHECK-NEXT: call void @use8(i8 [[TMP0]])139; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -4140; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], -8141; CHECK-NEXT: ret i1 [[TMP2]]142;143 %tmp0 = shl i8 %x, 5144 call void @use8(i8 %tmp0)145 %tmp1 = ashr exact i8 %tmp0, 5146 %tmp2 = icmp ne i8 %tmp1, %x147 ret i1 %tmp2148}149 150define i1 @n_oneuse1(i8 %x) {151; CHECK-LABEL: @n_oneuse1(152; CHECK-NEXT: [[TMP0:%.*]] = shl i8 [[X:%.*]], 5153; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i8 [[TMP0]], 5154; CHECK-NEXT: call void @use8(i8 [[TMP1]])155; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], [[X]]156; CHECK-NEXT: ret i1 [[TMP2]]157;158 %tmp0 = shl i8 %x, 5159 %tmp1 = ashr exact i8 %tmp0, 5160 call void @use8(i8 %tmp1)161 %tmp2 = icmp ne i8 %tmp1, %x162 ret i1 %tmp2163}164 165define i1 @n_oneuse2(i8 %x) {166; CHECK-LABEL: @n_oneuse2(167; CHECK-NEXT: [[TMP0:%.*]] = shl i8 [[X:%.*]], 5168; CHECK-NEXT: call void @use8(i8 [[TMP0]])169; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i8 [[TMP0]], 5170; CHECK-NEXT: call void @use8(i8 [[TMP1]])171; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], [[X]]172; CHECK-NEXT: ret i1 [[TMP2]]173;174 %tmp0 = shl i8 %x, 5175 call void @use8(i8 %tmp0)176 %tmp1 = ashr exact i8 %tmp0, 5177 call void @use8(i8 %tmp1)178 %tmp2 = icmp ne i8 %tmp1, %x179 ret i1 %tmp2180}181 182; ============================================================================ ;183; Negative tests184; ============================================================================ ;185 186define i1 @n0(i8 %x) {187; CHECK-LABEL: @n0(188; CHECK-NEXT: [[TMP0:%.*]] = shl i8 [[X:%.*]], 5189; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i8 [[TMP0]], 3190; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], [[X]]191; CHECK-NEXT: ret i1 [[TMP2]]192;193 %tmp0 = shl i8 %x, 5194 %tmp1 = ashr exact i8 %tmp0, 3 ; not 5195 %tmp2 = icmp ne i8 %tmp1, %x196 ret i1 %tmp2197}198 199define i1 @n1(i8 %x) {200; CHECK-LABEL: @n1(201; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i8 [[X:%.*]], 7202; CHECK-NEXT: ret i1 [[TMP2]]203;204 %tmp0 = shl i8 %x, 5205 %tmp1 = lshr exact i8 %tmp0, 5 ; not ashr206 %tmp2 = icmp ne i8 %tmp1, %x207 ret i1 %tmp2208}209 210define i1 @n2(i8 %x, i8 %y) {211; CHECK-LABEL: @n2(212; CHECK-NEXT: [[TMP0:%.*]] = shl i8 [[X:%.*]], 5213; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i8 [[TMP0]], 5214; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], [[Y:%.*]]215; CHECK-NEXT: ret i1 [[TMP2]]216;217 %tmp0 = shl i8 %x, 5218 %tmp1 = ashr exact i8 %tmp0, 5219 %tmp2 = icmp ne i8 %tmp1, %y ; not %x220 ret i1 %tmp2221}222 223define <2 x i1> @n3_vec_nonsplat(<2 x i8> %x) {224; CHECK-LABEL: @n3_vec_nonsplat(225; CHECK-NEXT: [[TMP0:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 5)226; CHECK-NEXT: [[TMP1:%.*]] = ashr exact <2 x i8> [[TMP0]], <i8 5, i8 3>227; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i8> [[TMP1]], [[X]]228; CHECK-NEXT: ret <2 x i1> [[TMP2]]229;230 %tmp0 = shl <2 x i8> %x, <i8 5, i8 5>231 %tmp1 = ashr exact <2 x i8> %tmp0, <i8 5, i8 3> ; 3 instead of 5232 %tmp2 = icmp ne <2 x i8> %tmp1, %x233 ret <2 x i1> %tmp2234}235