blob: 9dd0b373aa2e1c7f4a1f70e5cddca65a83c6763e [file] [log] [blame]
Eric Christophercee313d2019-04-17 04:52:47 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -mtriple=armv7-apple-darwin < %s -codegenprepare -S | FileCheck -check-prefix=NEON %s
3; RUN: opt -mtriple=armv6-unknown-linux < %s -codegenprepare -S | FileCheck -check-prefix=NONEON %s
4
5define <8 x i16> @sink_zext(<8 x i8> %a, <8 x i8> %b, i1 %c) {
6; NEON-LABEL: @sink_zext(
7; NEON-NEXT: entry:
8; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
9; NEON: if.then:
10; NEON-NEXT: [[ZB_1:%.*]] = zext <8 x i8> [[B:%.*]] to <8 x i16>
11; NEON-NEXT: [[TMP0:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
12; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
13; NEON-NEXT: ret <8 x i16> [[RES_1]]
14; NEON: if.else:
15; NEON-NEXT: [[ZB_2:%.*]] = zext <8 x i8> [[B]] to <8 x i16>
16; NEON-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[A]] to <8 x i16>
17; NEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[TMP1]], [[ZB_2]]
18; NEON-NEXT: ret <8 x i16> [[RES_2]]
19;
20; NONEON-LABEL: @sink_zext(
21; NONEON-NEXT: entry:
22; NONEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
23; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
24; NONEON: if.then:
25; NONEON-NEXT: [[ZB_1:%.*]] = zext <8 x i8> [[B:%.*]] to <8 x i16>
26; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[ZB_1]]
27; NONEON-NEXT: ret <8 x i16> [[RES_1]]
28; NONEON: if.else:
29; NONEON-NEXT: [[ZB_2:%.*]] = zext <8 x i8> [[B]] to <8 x i16>
30; NONEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[ZA]], [[ZB_2]]
31; NONEON-NEXT: ret <8 x i16> [[RES_2]]
32;
33entry:
34 %za = zext <8 x i8> %a to <8 x i16>
35 br i1 %c, label %if.then, label %if.else
36
37if.then:
38 %zb.1 = zext <8 x i8> %b to <8 x i16>
39 %res.1 = add <8 x i16> %za, %zb.1
40 ret <8 x i16> %res.1
41
42if.else:
43 %zb.2 = zext <8 x i8> %b to <8 x i16>
44 %res.2 = sub <8 x i16> %za, %zb.2
45 ret <8 x i16> %res.2
46}
47
48define <8 x i16> @sink_sext(<8 x i8> %a, <8 x i8> %b, i1 %c) {
49; NEON-LABEL: @sink_sext(
50; NEON-NEXT: entry:
51; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
52; NEON: if.then:
53; NEON-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
54; NEON-NEXT: [[TMP0:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
55; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
56; NEON-NEXT: ret <8 x i16> [[RES_1]]
57; NEON: if.else:
58; NEON-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
59; NEON-NEXT: [[TMP1:%.*]] = sext <8 x i8> [[A]] to <8 x i16>
60; NEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[TMP1]], [[ZB_2]]
61; NEON-NEXT: ret <8 x i16> [[RES_2]]
62;
63; NONEON-LABEL: @sink_sext(
64; NONEON-NEXT: entry:
65; NONEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
66; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
67; NONEON: if.then:
68; NONEON-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
69; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[ZB_1]]
70; NONEON-NEXT: ret <8 x i16> [[RES_1]]
71; NONEON: if.else:
72; NONEON-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
73; NONEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[ZA]], [[ZB_2]]
74; NONEON-NEXT: ret <8 x i16> [[RES_2]]
75;
76entry:
77 %za = sext <8 x i8> %a to <8 x i16>
78 br i1 %c, label %if.then, label %if.else
79
80if.then:
81 %zb.1 = sext <8 x i8> %b to <8 x i16>
82 %res.1 = add <8 x i16> %za, %zb.1
83 ret <8 x i16> %res.1
84
85if.else:
86 %zb.2 = sext <8 x i8> %b to <8 x i16>
87 %res.2 = sub <8 x i16> %za, %zb.2
88 ret <8 x i16> %res.2
89}
90
91define <8 x i16> @do_not_sink_nonfree_zext(<8 x i8> %a, <8 x i16> %b, i1 %c) {
92;
93; NEON-LABEL: @do_not_sink_nonfree_zext(
94; NEON-NEXT: entry:
95; NEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
96; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
97; NEON: if.then:
98; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
99; NEON-NEXT: ret <8 x i16> [[RES_1]]
100; NEON: if.else:
101; NEON-NEXT: ret <8 x i16> [[B]]
102;
103; NONEON-LABEL: @do_not_sink_nonfree_zext(
104; NONEON-NEXT: entry:
105; NONEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
106; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
107; NONEON: if.then:
108; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
109; NONEON-NEXT: ret <8 x i16> [[RES_1]]
110; NONEON: if.else:
111; NONEON-NEXT: ret <8 x i16> [[B]]
112;
113entry:
114 %za = zext <8 x i8> %a to <8 x i16>
115 br i1 %c, label %if.then, label %if.else
116
117if.then:
118 %res.1 = add <8 x i16> %za, %b
119 ret <8 x i16> %res.1
120
121if.else:
122 ret <8 x i16> %b
123}
124
125define <8 x i16> @do_not_sink_nonfree_sext(<8 x i8> %a, <8 x i16> %b, i1 %c) {
126; CHECK-LABEL: @do_not_sink_nonfree_sext(
127; CHECK-NEXT: entry:
128; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
129; CHECK: if.then:
130; CHECK-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
131; CHECK-NEXT: [[TMP0:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
132; CHECK-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
133; CHECK-NEXT: ret <8 x i16> [[RES_1]]
134; CHECK: if.else:
135; CHECK-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
136; CHECK-NEXT: ret <8 x i16> [[ZB_2]]
137;
138; NEON-LABEL: @do_not_sink_nonfree_sext(
139; NEON-NEXT: entry:
140; NEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
141; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
142; NEON: if.then:
143; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
144; NEON-NEXT: ret <8 x i16> [[RES_1]]
145; NEON: if.else:
146; NEON-NEXT: ret <8 x i16> [[B]]
147;
148; NONEON-LABEL: @do_not_sink_nonfree_sext(
149; NONEON-NEXT: entry:
150; NONEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
151; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
152; NONEON: if.then:
153; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
154; NONEON-NEXT: ret <8 x i16> [[RES_1]]
155; NONEON: if.else:
156; NONEON-NEXT: ret <8 x i16> [[B]]
157;
158entry:
159 %za = sext <8 x i8> %a to <8 x i16>
160 br i1 %c, label %if.then, label %if.else
161
162if.then:
163 %res.1 = add <8 x i16> %za, %b
164 ret <8 x i16> %res.1
165
166if.else:
167 ret <8 x i16> %b
168}
169
170declare void @user1(<8 x i16>)
171
172; Exts can be sunk.
173define <8 x i16> @sink_shufflevector_ext_subadd_multiuse(<16 x i8> %a, <16 x i8> %b) {
174; NEON-LABEL: @sink_shufflevector_ext_subadd_multiuse(
175; NEON-NEXT: entry:
176; NEON-NEXT: [[S1:%.*]] = shufflevector <16 x i8> [[A:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
177; NEON-NEXT: [[S3:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
178; NEON-NEXT: [[Z3:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
179; NEON-NEXT: call void @user1(<8 x i16> [[Z3]])
180; NEON-NEXT: br i1 undef, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
181; NEON: if.then:
182; NEON-NEXT: [[S2:%.*]] = shufflevector <16 x i8> [[B:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
183; NEON-NEXT: [[Z2:%.*]] = zext <8 x i8> [[S2]] to <8 x i16>
184; NEON-NEXT: [[TMP0:%.*]] = zext <8 x i8> [[S1]] to <8 x i16>
185; NEON-NEXT: [[RES1:%.*]] = add <8 x i16> [[TMP0]], [[Z2]]
186; NEON-NEXT: ret <8 x i16> [[RES1]]
187; NEON: if.else:
188; NEON-NEXT: [[S4:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
189; NEON-NEXT: [[Z4:%.*]] = sext <8 x i8> [[S4]] to <8 x i16>
190; NEON-NEXT: [[TMP1:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
191; NEON-NEXT: [[RES2:%.*]] = sub <8 x i16> [[TMP1]], [[Z4]]
192; NEON-NEXT: ret <8 x i16> [[RES2]]
193;
194; NONEON-LABEL: @sink_shufflevector_ext_subadd_multiuse(
195; NONEON-NEXT: entry:
196; NONEON-NEXT: [[S1:%.*]] = shufflevector <16 x i8> [[A:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
197; NONEON-NEXT: [[Z1:%.*]] = zext <8 x i8> [[S1]] to <8 x i16>
198; NONEON-NEXT: [[S3:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
199; NONEON-NEXT: [[Z3:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
200; NONEON-NEXT: call void @user1(<8 x i16> [[Z3]])
201; NONEON-NEXT: br i1 undef, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
202; NONEON: if.then:
203; NONEON-NEXT: [[S2:%.*]] = shufflevector <16 x i8> [[B:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
204; NONEON-NEXT: [[Z2:%.*]] = zext <8 x i8> [[S2]] to <8 x i16>
205; NONEON-NEXT: [[RES1:%.*]] = add <8 x i16> [[Z1]], [[Z2]]
206; NONEON-NEXT: ret <8 x i16> [[RES1]]
207; NONEON: if.else:
208; NONEON-NEXT: [[S4:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
209; NONEON-NEXT: [[Z4:%.*]] = sext <8 x i8> [[S4]] to <8 x i16>
210; NONEON-NEXT: [[RES2:%.*]] = sub <8 x i16> [[Z3]], [[Z4]]
211; NONEON-NEXT: ret <8 x i16> [[RES2]]
212;
213entry:
214 %s1 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
215 %z1 = zext <8 x i8> %s1 to <8 x i16>
216 %s3 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
217 %z3 = sext <8 x i8> %s3 to <8 x i16>
218 call void @user1(<8 x i16> %z3)
219 br i1 undef, label %if.then, label %if.else
220
221if.then:
222 %s2 = shufflevector <16 x i8> %b, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
223 %z2 = zext <8 x i8> %s2 to <8 x i16>
224 %res1 = add <8 x i16> %z1, %z2
225 ret <8 x i16> %res1
226
227if.else:
228 %s4 = shufflevector <16 x i8> %b, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
229 %z4 = sext <8 x i8> %s4 to <8 x i16>
230 %res2 = sub <8 x i16> %z3, %z4
231 ret <8 x i16> %res2
232}