[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / and-narrow.ll
blob8a56f98aa691f5c01d283466b4dc523c8c55132e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -data-layout="n8:16:32" -S | FileCheck %s
3 ; RUN: opt < %s -instcombine -data-layout="n16"      -S | FileCheck %s
5 ; PR35792 - https://bugs.llvm.org/show_bug.cgi?id=35792
7 define i16 @zext_add(i8 %x) {
8 ; CHECK-LABEL: @zext_add(
9 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], 44
10 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
11 ; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
12 ; CHECK-NEXT:    ret i16 [[R]]
14   %z = zext i8 %x to i16
15   %b = add i16 %z, 44
16   %r = and i16 %b, %z
17   ret i16 %r
20 define i16 @zext_sub(i8 %x) {
21 ; CHECK-LABEL: @zext_sub(
22 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 -5, [[X:%.*]]
23 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
24 ; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
25 ; CHECK-NEXT:    ret i16 [[R]]
27   %z = zext i8 %x to i16
28   %b = sub i16 -5, %z
29   %r = and i16 %b, %z
30   ret i16 %r
33 define i16 @zext_mul(i8 %x) {
34 ; CHECK-LABEL: @zext_mul(
35 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[X:%.*]], 3
36 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
37 ; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
38 ; CHECK-NEXT:    ret i16 [[R]]
40   %z = zext i8 %x to i16
41   %b = mul i16 %z, 3
42   %r = and i16 %b, %z
43   ret i16 %r
46 define i16 @zext_lshr(i8 %x) {
47 ; CHECK-LABEL: @zext_lshr(
48 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i8 [[X:%.*]], 4
49 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
50 ; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
51 ; CHECK-NEXT:    ret i16 [[R]]
53   %z = zext i8 %x to i16
54   %b = lshr i16 %z, 4
55   %r = and i16 %b, %z
56   ret i16 %r
59 define i16 @zext_ashr(i8 %x) {
60 ; CHECK-LABEL: @zext_ashr(
61 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i8 [[X:%.*]], 2
62 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
63 ; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
64 ; CHECK-NEXT:    ret i16 [[R]]
66   %z = zext i8 %x to i16
67   %b = ashr i16 %z, 2
68   %r = and i16 %b, %z
69   ret i16 %r
72 define i16 @zext_shl(i8 %x) {
73 ; CHECK-LABEL: @zext_shl(
74 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 [[X:%.*]], 3
75 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
76 ; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
77 ; CHECK-NEXT:    ret i16 [[R]]
79   %z = zext i8 %x to i16
80   %b = shl i16 %z, 3
81   %r = and i16 %b, %z
82   ret i16 %r
85 define <2 x i16> @zext_add_vec(<2 x i8> %x) {
86 ; CHECK-LABEL: @zext_add_vec(
87 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 44, i8 42>
88 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
89 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
90 ; CHECK-NEXT:    ret <2 x i16> [[R]]
92   %z = zext <2 x i8> %x to <2 x i16>
93   %b = add <2 x i16> %z, <i16 44, i16 42>
94   %r = and <2 x i16> %b, %z
95   ret <2 x i16> %r
98 define <2 x i16> @zext_sub_vec(<2 x i8> %x) {
99 ; CHECK-LABEL: @zext_sub_vec(
100 ; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> <i8 -5, i8 -4>, [[X:%.*]]
101 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
102 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
103 ; CHECK-NEXT:    ret <2 x i16> [[R]]
105   %z = zext <2 x i8> %x to <2 x i16>
106   %b = sub <2 x i16> <i16 -5, i16 -4>, %z
107   %r = and <2 x i16> %b, %z
108   ret <2 x i16> %r
111 define <2 x i16> @zext_mul_vec(<2 x i8> %x) {
112 ; CHECK-LABEL: @zext_mul_vec(
113 ; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i8> [[X:%.*]], <i8 3, i8 -2>
114 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
115 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
116 ; CHECK-NEXT:    ret <2 x i16> [[R]]
118   %z = zext <2 x i8> %x to <2 x i16>
119   %b = mul <2 x i16> %z, <i16 3, i16 -2>
120   %r = and <2 x i16> %b, %z
121   ret <2 x i16> %r
124 define <2 x i16> @zext_lshr_vec(<2 x i8> %x) {
125 ; CHECK-LABEL: @zext_lshr_vec(
126 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 2>
127 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
128 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
129 ; CHECK-NEXT:    ret <2 x i16> [[R]]
131   %z = zext <2 x i8> %x to <2 x i16>
132   %b = lshr <2 x i16> %z, <i16 4, i16 2>
133   %r = and <2 x i16> %b, %z
134   ret <2 x i16> %r
137 define <2 x i16> @zext_ashr_vec(<2 x i8> %x) {
138 ; CHECK-LABEL: @zext_ashr_vec(
139 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 2, i8 3>
140 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
141 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
142 ; CHECK-NEXT:    ret <2 x i16> [[R]]
144   %z = zext <2 x i8> %x to <2 x i16>
145   %b = ashr <2 x i16> %z, <i16 2, i16 3>
146   %r = and <2 x i16> %b, %z
147   ret <2 x i16> %r
150 define <2 x i16> @zext_shl_vec(<2 x i8> %x) {
151 ; CHECK-LABEL: @zext_shl_vec(
152 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 3, i8 2>
153 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
154 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
155 ; CHECK-NEXT:    ret <2 x i16> [[R]]
157   %z = zext <2 x i8> %x to <2 x i16>
158   %b = shl <2 x i16> %z, <i16 3, i16 2>
159   %r = and <2 x i16> %b, %z
160   ret <2 x i16> %r
163 ; Don't create poison by narrowing a shift below the shift amount.
165 define <2 x i16> @zext_lshr_vec_overshift(<2 x i8> %x) {
166 ; CHECK-LABEL: @zext_lshr_vec_overshift(
167 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
168 ; CHECK-NEXT:    [[B:%.*]] = lshr <2 x i16> [[Z]], <i16 4, i16 8>
169 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
170 ; CHECK-NEXT:    ret <2 x i16> [[R]]
172   %z = zext <2 x i8> %x to <2 x i16>
173   %b = lshr <2 x i16> %z, <i16 4, i16 8>
174   %r = and <2 x i16> %b, %z
175   ret <2 x i16> %r
178 define <2 x i16> @zext_lshr_vec_undef(<2 x i8> %x) {
179 ; CHECK-LABEL: @zext_lshr_vec_undef(
180 ; CHECK-NEXT:    ret <2 x i16> poison
182   %z = zext <2 x i8> %x to <2 x i16>
183   %b = lshr <2 x i16> %z, undef
184   %r = and <2 x i16> %b, %z
185   ret <2 x i16> %r
188 ; Don't create poison by narrowing a shift below the shift amount.
190 define <2 x i16> @zext_shl_vec_overshift(<2 x i8> %x) {
191 ; CHECK-LABEL: @zext_shl_vec_overshift(
192 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
193 ; CHECK-NEXT:    [[B:%.*]] = shl <2 x i16> [[Z]], <i16 8, i16 2>
194 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
195 ; CHECK-NEXT:    ret <2 x i16> [[R]]
197   %z = zext <2 x i8> %x to <2 x i16>
198   %b = shl <2 x i16> %z, <i16 8, i16 2>
199   %r = and <2 x i16> %b, %z
200   ret <2 x i16> %r
203 define <2 x i16> @zext_shl_vec_undef(<2 x i8> %x) {
204 ; CHECK-LABEL: @zext_shl_vec_undef(
205 ; CHECK-NEXT:    ret <2 x i16> poison
207   %z = zext <2 x i8> %x to <2 x i16>
208   %b = shl <2 x i16> %z, undef
209   %r = and <2 x i16> %b, %z
210   ret <2 x i16> %r