aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/CodeGenPrepare/ARM/sink-free-instructions.ll
blob: 2a4323339a3421eeca1ac11a9df7564c0b424a41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -mtriple=armv7-apple-darwin < %s -codegenprepare -S | FileCheck -check-prefix=NEON %s
; RUN: opt -mtriple=armv6-unknown-linux < %s -codegenprepare -S | FileCheck -check-prefix=NONEON %s

define <8 x i16> @sink_zext(<8 x i8> %a, <8 x i8> %b, i1 %c) {
; NEON-LABEL: @sink_zext(
; NEON-NEXT:  entry:
; NEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NEON:       if.then:
; NEON-NEXT:    [[TMP0:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
; NEON-NEXT:    [[ZB_1:%.*]] = zext <8 x i8> [[B:%.*]] to <8 x i16>
; NEON-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
; NEON-NEXT:    ret <8 x i16> [[RES_1]]
; NEON:       if.else:
; NEON-NEXT:    [[TMP1:%.*]] = zext <8 x i8> [[A]] to <8 x i16>
; NEON-NEXT:    [[ZB_2:%.*]] = zext <8 x i8> [[B]] to <8 x i16>
; NEON-NEXT:    [[RES_2:%.*]] = sub <8 x i16> [[TMP1]], [[ZB_2]]
; NEON-NEXT:    ret <8 x i16> [[RES_2]]
;
; NONEON-LABEL: @sink_zext(
; NONEON-NEXT:  entry:
; NONEON-NEXT:    [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
; NONEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NONEON:       if.then:
; NONEON-NEXT:    [[ZB_1:%.*]] = zext <8 x i8> [[B:%.*]] to <8 x i16>
; NONEON-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[ZB_1]]
; NONEON-NEXT:    ret <8 x i16> [[RES_1]]
; NONEON:       if.else:
; NONEON-NEXT:    [[ZB_2:%.*]] = zext <8 x i8> [[B]] to <8 x i16>
; NONEON-NEXT:    [[RES_2:%.*]] = sub <8 x i16> [[ZA]], [[ZB_2]]
; NONEON-NEXT:    ret <8 x i16> [[RES_2]]
;
entry:
  %za = zext <8 x i8> %a to <8 x i16>
  br i1 %c, label %if.then, label %if.else

if.then:
  %zb.1 = zext <8 x i8> %b to <8 x i16>
  %res.1 = add <8 x i16> %za, %zb.1
  ret <8 x i16> %res.1

if.else:
  %zb.2 = zext <8 x i8> %b to <8 x i16>
  %res.2 = sub <8 x i16> %za, %zb.2
  ret <8 x i16> %res.2
}

define <8 x i16> @sink_sext(<8 x i8> %a, <8 x i8> %b, i1 %c) {
; NEON-LABEL: @sink_sext(
; NEON-NEXT:  entry:
; NEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NEON:       if.then:
; NEON-NEXT:    [[TMP0:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
; NEON-NEXT:    [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
; NEON-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
; NEON-NEXT:    ret <8 x i16> [[RES_1]]
; NEON:       if.else:
; NEON-NEXT:    [[TMP1:%.*]] = sext <8 x i8> [[A]] to <8 x i16>
; NEON-NEXT:    [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
; NEON-NEXT:    [[RES_2:%.*]] = sub <8 x i16> [[TMP1]], [[ZB_2]]
; NEON-NEXT:    ret <8 x i16> [[RES_2]]
;
; NONEON-LABEL: @sink_sext(
; NONEON-NEXT:  entry:
; NONEON-NEXT:    [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
; NONEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NONEON:       if.then:
; NONEON-NEXT:    [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
; NONEON-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[ZB_1]]
; NONEON-NEXT:    ret <8 x i16> [[RES_1]]
; NONEON:       if.else:
; NONEON-NEXT:    [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
; NONEON-NEXT:    [[RES_2:%.*]] = sub <8 x i16> [[ZA]], [[ZB_2]]
; NONEON-NEXT:    ret <8 x i16> [[RES_2]]
;
entry:
  %za = sext <8 x i8> %a to <8 x i16>
  br i1 %c, label %if.then, label %if.else

if.then:
  %zb.1 = sext <8 x i8> %b to <8 x i16>
  %res.1 = add <8 x i16> %za, %zb.1
  ret <8 x i16> %res.1

if.else:
  %zb.2 = sext <8 x i8> %b to <8 x i16>
  %res.2 = sub <8 x i16> %za, %zb.2
  ret <8 x i16> %res.2
}

define <8 x i16> @do_not_sink_nonfree_zext(<8 x i8> %a, <8 x i16> %b, i1 %c) {
;
; NEON-LABEL: @do_not_sink_nonfree_zext(
; NEON-NEXT:  entry:
; NEON-NEXT:    [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
; NEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NEON:       if.then:
; NEON-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
; NEON-NEXT:    ret <8 x i16> [[RES_1]]
; NEON:       if.else:
; NEON-NEXT:    ret <8 x i16> [[B]]
;
; NONEON-LABEL: @do_not_sink_nonfree_zext(
; NONEON-NEXT:  entry:
; NONEON-NEXT:    [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>
; NONEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NONEON:       if.then:
; NONEON-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
; NONEON-NEXT:    ret <8 x i16> [[RES_1]]
; NONEON:       if.else:
; NONEON-NEXT:    ret <8 x i16> [[B]]
;
entry:
  %za = zext <8 x i8> %a to <8 x i16>
  br i1 %c, label %if.then, label %if.else

if.then:
  %res.1 = add <8 x i16> %za, %b
  ret <8 x i16> %res.1

if.else:
  ret <8 x i16> %b
}

define <8 x i16> @do_not_sink_nonfree_sext(<8 x i8> %a, <8 x i16> %b, i1 %c) {
; CHECK-LABEL: @do_not_sink_nonfree_sext(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then:
; CHECK-NEXT:    [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>
; CHECK-NEXT:    [[TMP0:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
; CHECK-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]
; CHECK-NEXT:    ret <8 x i16> [[RES_1]]
; CHECK:       if.else:
; CHECK-NEXT:    [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>
; CHECK-NEXT:    ret <8 x i16> [[ZB_2]]
;
; NEON-LABEL: @do_not_sink_nonfree_sext(
; NEON-NEXT:  entry:
; NEON-NEXT:    [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
; NEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NEON:       if.then:
; NEON-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
; NEON-NEXT:    ret <8 x i16> [[RES_1]]
; NEON:       if.else:
; NEON-NEXT:    ret <8 x i16> [[B]]
;
; NONEON-LABEL: @do_not_sink_nonfree_sext(
; NONEON-NEXT:  entry:
; NONEON-NEXT:    [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>
; NONEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NONEON:       if.then:
; NONEON-NEXT:    [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]
; NONEON-NEXT:    ret <8 x i16> [[RES_1]]
; NONEON:       if.else:
; NONEON-NEXT:    ret <8 x i16> [[B]]
;
entry:
  %za = sext <8 x i8> %a to <8 x i16>
  br i1 %c, label %if.then, label %if.else

if.then:
  %res.1 = add <8 x i16> %za, %b
  ret <8 x i16> %res.1

if.else:
  ret <8 x i16> %b
}

declare void @user1(<8 x i16>)

; Exts can be sunk.
define <8 x i16> @sink_shufflevector_ext_subadd_multiuse(<16 x i8> %a, <16 x i8> %b, i1 %c) {
; NEON-LABEL: @sink_shufflevector_ext_subadd_multiuse(
; NEON-NEXT:  entry:
; 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>
; 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>
; NEON-NEXT:    [[Z3:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
; NEON-NEXT:    call void @user1(<8 x i16> [[Z3]])
; NEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NEON:       if.then:
; 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>
; NEON-NEXT:    [[TMP0:%.*]] = zext <8 x i8> [[S1]] to <8 x i16>
; NEON-NEXT:    [[Z2:%.*]] = zext <8 x i8> [[S2]] to <8 x i16>
; NEON-NEXT:    [[RES1:%.*]] = add <8 x i16> [[TMP0]], [[Z2]]
; NEON-NEXT:    ret <8 x i16> [[RES1]]
; NEON:       if.else:
; 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>
; NEON-NEXT:    [[TMP1:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
; NEON-NEXT:    [[Z4:%.*]] = sext <8 x i8> [[S4]] to <8 x i16>
; NEON-NEXT:    [[RES2:%.*]] = sub <8 x i16> [[TMP1]], [[Z4]]
; NEON-NEXT:    ret <8 x i16> [[RES2]]
;
; NONEON-LABEL: @sink_shufflevector_ext_subadd_multiuse(
; NONEON-NEXT:  entry:
; 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>
; NONEON-NEXT:    [[Z1:%.*]] = zext <8 x i8> [[S1]] to <8 x i16>
; 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>
; NONEON-NEXT:    [[Z3:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>
; NONEON-NEXT:    call void @user1(<8 x i16> [[Z3]])
; NONEON-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; NONEON:       if.then:
; 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>
; NONEON-NEXT:    [[Z2:%.*]] = zext <8 x i8> [[S2]] to <8 x i16>
; NONEON-NEXT:    [[RES1:%.*]] = add <8 x i16> [[Z1]], [[Z2]]
; NONEON-NEXT:    ret <8 x i16> [[RES1]]
; NONEON:       if.else:
; 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>
; NONEON-NEXT:    [[Z4:%.*]] = sext <8 x i8> [[S4]] to <8 x i16>
; NONEON-NEXT:    [[RES2:%.*]] = sub <8 x i16> [[Z3]], [[Z4]]
; NONEON-NEXT:    ret <8 x i16> [[RES2]]
;
entry:
  %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>
  %z1 = zext <8 x i8> %s1 to <8 x i16>
  %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>
  %z3 = sext <8 x i8> %s3 to <8 x i16>
  call void @user1(<8 x i16> %z3)
  br i1 %c, label %if.then, label %if.else

if.then:
  %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>
  %z2 = zext <8 x i8> %s2 to <8 x i16>
  %res1 = add <8 x i16> %z1, %z2
  ret <8 x i16> %res1

if.else:
  %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>
  %z4 = sext <8 x i8> %s4 to <8 x i16>
  %res2 = sub <8 x i16> %z3, %z4
  ret <8 x i16> %res2
}