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
4
5; PR35792 - https://bugs.llvm.org/show_bug.cgi?id=35792
6
7define 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]]
13;
14  %z = zext i8 %x to i16
15  %b = add i16 %z, 44
16  %r = and i16 %b, %z
17  ret i16 %r
18}
19
20define 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]]
26;
27  %z = zext i8 %x to i16
28  %b = sub i16 -5, %z
29  %r = and i16 %b, %z
30  ret i16 %r
31}
32
33define 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]]
39;
40  %z = zext i8 %x to i16
41  %b = mul i16 %z, 3
42  %r = and i16 %b, %z
43  ret i16 %r
44}
45
46define 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]]
52;
53  %z = zext i8 %x to i16
54  %b = lshr i16 %z, 4
55  %r = and i16 %b, %z
56  ret i16 %r
57}
58
59define 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]]
65;
66  %z = zext i8 %x to i16
67  %b = ashr i16 %z, 2
68  %r = and i16 %b, %z
69  ret i16 %r
70}
71
72define 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]]
78;
79  %z = zext i8 %x to i16
80  %b = shl i16 %z, 3
81  %r = and i16 %b, %z
82  ret i16 %r
83}
84
85define <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]]
91;
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
96}
97
98define <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]]
104;
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
109}
110
111define <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]]
117;
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
122}
123
124define <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]]
130;
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
135}
136
137define <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]]
143;
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
148}
149
150define <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]]
156;
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
161}
162
163; Don't create poison by narrowing a shift below the shift amount.
164
165define <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]]
171;
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
176}
177
178define <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> zeroinitializer
181;
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
186}
187
188; Don't create poison by narrowing a shift below the shift amount.
189
190define <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]]
196;
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
201}
202
203define <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> zeroinitializer
206;
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
211}
212
213