xref: /aosp_15_r20/external/llvm/test/CodeGen/ARM/vector-promotion.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon -S | FileCheck --check-prefix=IR-BOTH --check-prefix=IR-NORMAL %s
2*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon -S -stress-cgp-store-extract | FileCheck --check-prefix=IR-BOTH --check-prefix=IR-STRESS %s
3*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon | FileCheck --check-prefix=ASM %s
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotion
6*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
7*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 undef, i32 1>
8*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[VECTOR_OR]], i32 1
9*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[EXTRACT]], i32* %dest
10*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
11*9880d681SAndroid Build Coastguard Worker;
12*9880d681SAndroid Build Coastguard Worker; Make sure we got rid of any expensive vmov.32 instructions.
13*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: simpleOneInstructionPromotion:
14*9880d681SAndroid Build Coastguard Worker; ASM: vldr [[LOAD:d[0-9]+]], [r0]
15*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: vorr.i32 [[LOAD]], #0x1
16*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: vst1.32 {[[LOAD]][1]}, [r1:32]
17*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: bx
18*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotion(<2 x i32>* %addr1, i32* %dest) {
19*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
20*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 1
21*9880d681SAndroid Build Coastguard Worker  %out = or i32 %extract, 1
22*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
23*9880d681SAndroid Build Coastguard Worker  ret void
24*9880d681SAndroid Build Coastguard Worker}
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @unsupportedInstructionForPromotion
27*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
28*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 0
29*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[CMP:%[a-zA-Z_0-9-]+]] = icmp eq i32 [[EXTRACT]], %in2
30*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i1 [[CMP]], i1* %dest
31*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
32*9880d681SAndroid Build Coastguard Worker;
33*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: unsupportedInstructionForPromotion:
34*9880d681SAndroid Build Coastguard Worker; ASM: vldr [[LOAD:d[0-9]+]], [r0]
35*9880d681SAndroid Build Coastguard Worker; ASM: vmov.32 {{r[0-9]+}}, [[LOAD]]
36*9880d681SAndroid Build Coastguard Worker; ASM: bx
37*9880d681SAndroid Build Coastguard Workerdefine void @unsupportedInstructionForPromotion(<2 x i32>* %addr1, i32 %in2, i1* %dest) {
38*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
39*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 0
40*9880d681SAndroid Build Coastguard Worker  %out = icmp eq i32 %extract, %in2
41*9880d681SAndroid Build Coastguard Worker  store i1 %out, i1* %dest, align 4
42*9880d681SAndroid Build Coastguard Worker  ret void
43*9880d681SAndroid Build Coastguard Worker}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @unsupportedChainInDifferentBBs
47*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
48*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 0
49*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: br i1 %bool, label %bb2, label %end
50*9880d681SAndroid Build Coastguard Worker; BB2
51*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[OR:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1
52*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[OR]], i32* %dest, align 4
53*9880d681SAndroid Build Coastguard Worker; IR-BOTH: ret
54*9880d681SAndroid Build Coastguard Worker;
55*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: unsupportedChainInDifferentBBs:
56*9880d681SAndroid Build Coastguard Worker; ASM: vldrne [[LOAD:d[0-9]+]], [r0]
57*9880d681SAndroid Build Coastguard Worker; ASM: vmovne.32 {{r[0-9]+}}, [[LOAD]]
58*9880d681SAndroid Build Coastguard Worker; ASM: bx
59*9880d681SAndroid Build Coastguard Workerdefine void @unsupportedChainInDifferentBBs(<2 x i32>* %addr1, i32* %dest, i1 %bool) {
60*9880d681SAndroid Build Coastguard Workerbb1:
61*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
62*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 0
63*9880d681SAndroid Build Coastguard Worker  br i1 %bool, label %bb2, label %end
64*9880d681SAndroid Build Coastguard Workerbb2:
65*9880d681SAndroid Build Coastguard Worker  %out = or i32 %extract, 1
66*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
67*9880d681SAndroid Build Coastguard Worker  br label %end
68*9880d681SAndroid Build Coastguard Workerend:
69*9880d681SAndroid Build Coastguard Worker  ret void
70*9880d681SAndroid Build Coastguard Worker}
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker; IR-LABEL: @chainOfInstructionsToPromote
73*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
74*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR1:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 1, i32 undef>
75*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR2:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR1]], <i32 1, i32 undef>
76*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR3:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR2]], <i32 1, i32 undef>
77*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR4:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR3]], <i32 1, i32 undef>
78*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR5:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR4]], <i32 1, i32 undef>
79*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR6:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR5]], <i32 1, i32 undef>
80*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR7:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR6]], <i32 1, i32 undef>
81*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[VECTOR_OR7]], i32 0
82*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[EXTRACT]], i32* %dest
83*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
84*9880d681SAndroid Build Coastguard Worker;
85*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: chainOfInstructionsToPromote:
86*9880d681SAndroid Build Coastguard Worker; ASM: vldr [[LOAD:d[0-9]+]], [r0]
87*9880d681SAndroid Build Coastguard Worker; ASM-NOT: vmov.32 {{r[0-9]+}}, [[LOAD]]
88*9880d681SAndroid Build Coastguard Worker; ASM: bx
89*9880d681SAndroid Build Coastguard Workerdefine void @chainOfInstructionsToPromote(<2 x i32>* %addr1, i32* %dest) {
90*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
91*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 0
92*9880d681SAndroid Build Coastguard Worker  %out1 = or i32 %extract, 1
93*9880d681SAndroid Build Coastguard Worker  %out2 = or i32 %out1, 1
94*9880d681SAndroid Build Coastguard Worker  %out3 = or i32 %out2, 1
95*9880d681SAndroid Build Coastguard Worker  %out4 = or i32 %out3, 1
96*9880d681SAndroid Build Coastguard Worker  %out5 = or i32 %out4, 1
97*9880d681SAndroid Build Coastguard Worker  %out6 = or i32 %out5, 1
98*9880d681SAndroid Build Coastguard Worker  %out7 = or i32 %out6, 1
99*9880d681SAndroid Build Coastguard Worker  store i32 %out7, i32* %dest, align 4
100*9880d681SAndroid Build Coastguard Worker  ret void
101*9880d681SAndroid Build Coastguard Worker}
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @unsupportedMultiUses
104*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
105*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1
106*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1
107*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[OR]], i32* %dest
108*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret i32 [[OR]]
109*9880d681SAndroid Build Coastguard Worker;
110*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: unsupportedMultiUses:
111*9880d681SAndroid Build Coastguard Worker; ASM: vldr [[LOAD:d[0-9]+]], [r0]
112*9880d681SAndroid Build Coastguard Worker; ASM: vmov.32 {{r[0-9]+}}, [[LOAD]]
113*9880d681SAndroid Build Coastguard Worker; ASM: bx
114*9880d681SAndroid Build Coastguard Workerdefine i32 @unsupportedMultiUses(<2 x i32>* %addr1, i32* %dest) {
115*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
116*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 1
117*9880d681SAndroid Build Coastguard Worker  %out = or i32 %extract, 1
118*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
119*9880d681SAndroid Build Coastguard Worker  ret i32 %out
120*9880d681SAndroid Build Coastguard Worker}
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker; Check that we promote we a splat constant when this is a division.
123*9880d681SAndroid Build Coastguard Worker; The NORMAL mode does not promote anything as divisions are not legal.
124*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @udivCase
125*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
126*9880d681SAndroid Build Coastguard Worker; Scalar version:
127*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1
128*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv i32 [[EXTRACT]], 7
129*9880d681SAndroid Build Coastguard Worker; Vector version:
130*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = udiv <2 x i32> [[LOAD]], <i32 7, i32 7>
131*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1
132*9880d681SAndroid Build Coastguard Worker;
133*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest
134*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
135*9880d681SAndroid Build Coastguard Workerdefine void @udivCase(<2 x i32>* %addr1, i32* %dest) {
136*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
137*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 1
138*9880d681SAndroid Build Coastguard Worker  %out = udiv i32 %extract, 7
139*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
140*9880d681SAndroid Build Coastguard Worker  ret void
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @uremCase
144*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
145*9880d681SAndroid Build Coastguard Worker; Scalar version:
146*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1
147*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = urem i32 [[EXTRACT]], 7
148*9880d681SAndroid Build Coastguard Worker; Vector version:
149*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = urem <2 x i32> [[LOAD]], <i32 7, i32 7>
150*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1
151*9880d681SAndroid Build Coastguard Worker;
152*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest
153*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
154*9880d681SAndroid Build Coastguard Workerdefine void @uremCase(<2 x i32>* %addr1, i32* %dest) {
155*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
156*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 1
157*9880d681SAndroid Build Coastguard Worker  %out = urem i32 %extract, 7
158*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
159*9880d681SAndroid Build Coastguard Worker  ret void
160*9880d681SAndroid Build Coastguard Worker}
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @sdivCase
163*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
164*9880d681SAndroid Build Coastguard Worker; Scalar version:
165*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1
166*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = sdiv i32 [[EXTRACT]], 7
167*9880d681SAndroid Build Coastguard Worker; Vector version:
168*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = sdiv <2 x i32> [[LOAD]], <i32 7, i32 7>
169*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1
170*9880d681SAndroid Build Coastguard Worker;
171*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest
172*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
173*9880d681SAndroid Build Coastguard Workerdefine void @sdivCase(<2 x i32>* %addr1, i32* %dest) {
174*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
175*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 1
176*9880d681SAndroid Build Coastguard Worker  %out = sdiv i32 %extract, 7
177*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
178*9880d681SAndroid Build Coastguard Worker  ret void
179*9880d681SAndroid Build Coastguard Worker}
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @sremCase
182*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
183*9880d681SAndroid Build Coastguard Worker; Scalar version:
184*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1
185*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = srem i32 [[EXTRACT]], 7
186*9880d681SAndroid Build Coastguard Worker; Vector version:
187*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = srem <2 x i32> [[LOAD]], <i32 7, i32 7>
188*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1
189*9880d681SAndroid Build Coastguard Worker;
190*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest
191*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
192*9880d681SAndroid Build Coastguard Workerdefine void @sremCase(<2 x i32>* %addr1, i32* %dest) {
193*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
194*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 1
195*9880d681SAndroid Build Coastguard Worker  %out = srem i32 %extract, 7
196*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
197*9880d681SAndroid Build Coastguard Worker  ret void
198*9880d681SAndroid Build Coastguard Worker}
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @fdivCase
201*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1
202*9880d681SAndroid Build Coastguard Worker; Scalar version:
203*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1
204*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = fdiv float [[EXTRACT]], 7.0
205*9880d681SAndroid Build Coastguard Worker; Vector version:
206*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = fdiv <2 x float> [[LOAD]], <float 7.000000e+00, float 7.000000e+00>
207*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1
208*9880d681SAndroid Build Coastguard Worker;
209*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest
210*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
211*9880d681SAndroid Build Coastguard Workerdefine void @fdivCase(<2 x float>* %addr1, float* %dest) {
212*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x float>, <2 x float>* %addr1, align 8
213*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x float> %in1, i32 1
214*9880d681SAndroid Build Coastguard Worker  %out = fdiv float %extract, 7.0
215*9880d681SAndroid Build Coastguard Worker  store float %out, float* %dest, align 4
216*9880d681SAndroid Build Coastguard Worker  ret void
217*9880d681SAndroid Build Coastguard Worker}
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @fremCase
220*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1
221*9880d681SAndroid Build Coastguard Worker; Scalar version:
222*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1
223*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem float [[EXTRACT]], 7.0
224*9880d681SAndroid Build Coastguard Worker; Vector version:
225*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem <2 x float> [[LOAD]], <float 7.000000e+00, float 7.000000e+00>
226*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1
227*9880d681SAndroid Build Coastguard Worker;
228*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest
229*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
230*9880d681SAndroid Build Coastguard Workerdefine void @fremCase(<2 x float>* %addr1, float* %dest) {
231*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x float>, <2 x float>* %addr1, align 8
232*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x float> %in1, i32 1
233*9880d681SAndroid Build Coastguard Worker  %out = frem float %extract, 7.0
234*9880d681SAndroid Build Coastguard Worker  store float %out, float* %dest, align 4
235*9880d681SAndroid Build Coastguard Worker  ret void
236*9880d681SAndroid Build Coastguard Worker}
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker; Check that we do not promote when we may introduce undefined behavior
239*9880d681SAndroid Build Coastguard Worker; like division by zero.
240*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @undefDivCase
241*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
242*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1
243*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv i32 7, [[EXTRACT]]
244*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest
245*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
246*9880d681SAndroid Build Coastguard Workerdefine void @undefDivCase(<2 x i32>* %addr1, i32* %dest) {
247*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
248*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 1
249*9880d681SAndroid Build Coastguard Worker  %out = udiv i32 7, %extract
250*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
251*9880d681SAndroid Build Coastguard Worker  ret void
252*9880d681SAndroid Build Coastguard Worker}
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker; Check that we do not promote when we may introduce undefined behavior
256*9880d681SAndroid Build Coastguard Worker; like division by zero.
257*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @undefRemCase
258*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
259*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1
260*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = srem i32 7, [[EXTRACT]]
261*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest
262*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
263*9880d681SAndroid Build Coastguard Workerdefine void @undefRemCase(<2 x i32>* %addr1, i32* %dest) {
264*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
265*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 1
266*9880d681SAndroid Build Coastguard Worker  %out = srem i32 7, %extract
267*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
268*9880d681SAndroid Build Coastguard Worker  ret void
269*9880d681SAndroid Build Coastguard Worker}
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker; Check that we use an undef mask for undefined behavior if the fast-math
272*9880d681SAndroid Build Coastguard Worker; flag is set.
273*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @undefConstantFRemCaseWithFastMath
274*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1
275*9880d681SAndroid Build Coastguard Worker; Scalar version:
276*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1
277*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem nnan float [[EXTRACT]], 7.0
278*9880d681SAndroid Build Coastguard Worker; Vector version:
279*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem nnan <2 x float> [[LOAD]], <float undef, float 7.000000e+00>
280*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1
281*9880d681SAndroid Build Coastguard Worker;
282*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest
283*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
284*9880d681SAndroid Build Coastguard Workerdefine void @undefConstantFRemCaseWithFastMath(<2 x float>* %addr1, float* %dest) {
285*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x float>, <2 x float>* %addr1, align 8
286*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x float> %in1, i32 1
287*9880d681SAndroid Build Coastguard Worker  %out = frem nnan float %extract, 7.0
288*9880d681SAndroid Build Coastguard Worker  store float %out, float* %dest, align 4
289*9880d681SAndroid Build Coastguard Worker  ret void
290*9880d681SAndroid Build Coastguard Worker}
291*9880d681SAndroid Build Coastguard Worker
292*9880d681SAndroid Build Coastguard Worker; Check that we use an undef mask for undefined behavior if the fast-math
293*9880d681SAndroid Build Coastguard Worker; flag is set.
294*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @undefVectorFRemCaseWithFastMath
295*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1
296*9880d681SAndroid Build Coastguard Worker; Scalar version:
297*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1
298*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem nnan float 7.000000e+00, [[EXTRACT]]
299*9880d681SAndroid Build Coastguard Worker; Vector version:
300*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem nnan <2 x float> <float undef, float 7.000000e+00>, [[LOAD]]
301*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1
302*9880d681SAndroid Build Coastguard Worker;
303*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest
304*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
305*9880d681SAndroid Build Coastguard Workerdefine void @undefVectorFRemCaseWithFastMath(<2 x float>* %addr1, float* %dest) {
306*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x float>, <2 x float>* %addr1, align 8
307*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x float> %in1, i32 1
308*9880d681SAndroid Build Coastguard Worker  %out = frem nnan float 7.0, %extract
309*9880d681SAndroid Build Coastguard Worker  store float %out, float* %dest, align 4
310*9880d681SAndroid Build Coastguard Worker  ret void
311*9880d681SAndroid Build Coastguard Worker}
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker; Check that we are able to promote floating point value.
314*9880d681SAndroid Build Coastguard Worker; This requires the STRESS mode, as floating point value are
315*9880d681SAndroid Build Coastguard Worker; not promote on armv7.
316*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotionFloat
317*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1
318*9880d681SAndroid Build Coastguard Worker; Scalar version:
319*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1
320*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = fadd float [[EXTRACT]], 1.0
321*9880d681SAndroid Build Coastguard Worker; Vector version:
322*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = fadd <2 x float> [[LOAD]], <float undef, float 1.000000e+00>
323*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1
324*9880d681SAndroid Build Coastguard Worker;
325*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest
326*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
327*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotionFloat(<2 x float>* %addr1, float* %dest) {
328*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x float>, <2 x float>* %addr1, align 8
329*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x float> %in1, i32 1
330*9880d681SAndroid Build Coastguard Worker  %out = fadd float %extract, 1.0
331*9880d681SAndroid Build Coastguard Worker  store float %out, float* %dest, align 4
332*9880d681SAndroid Build Coastguard Worker  ret void
333*9880d681SAndroid Build Coastguard Worker}
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker; Check that we correctly use a splat constant when we cannot
336*9880d681SAndroid Build Coastguard Worker; determine at compile time the index of the extract.
337*9880d681SAndroid Build Coastguard Worker; This requires the STRESS modes, as variable index are expensive
338*9880d681SAndroid Build Coastguard Worker; to lower.
339*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotionVariableIdx
340*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1
341*9880d681SAndroid Build Coastguard Worker; Scalar version:
342*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 %idx
343*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1
344*9880d681SAndroid Build Coastguard Worker; Vector version:
345*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 1, i32 1>
346*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[OR]], i32 %idx
347*9880d681SAndroid Build Coastguard Worker;
348*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest
349*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
350*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotionVariableIdx(<2 x i32>* %addr1, i32* %dest, i32 %idx) {
351*9880d681SAndroid Build Coastguard Worker  %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8
352*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <2 x i32> %in1, i32 %idx
353*9880d681SAndroid Build Coastguard Worker  %out = or i32 %extract, 1
354*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 4
355*9880d681SAndroid Build Coastguard Worker  ret void
356*9880d681SAndroid Build Coastguard Worker}
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker; Check a vector with more than 2 elements.
359*9880d681SAndroid Build Coastguard Worker; This requires the STRESS mode because currently 'or v8i8' is not marked
360*9880d681SAndroid Build Coastguard Worker; as legal or custom, althought the actual assembly is better if we were
361*9880d681SAndroid Build Coastguard Worker; promoting it.
362*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotion8x8
363*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <8 x i8>, <8 x i8>* %addr1
364*9880d681SAndroid Build Coastguard Worker; Scalar version:
365*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <8 x i8> [[LOAD]], i32 1
366*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = or i8 [[EXTRACT]], 1
367*9880d681SAndroid Build Coastguard Worker; Vector version:
368*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or <8 x i8> [[LOAD]], <i8 undef, i8 1, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>
369*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <8 x i8> [[OR]], i32 1
370*9880d681SAndroid Build Coastguard Worker;
371*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i8 [[RES]], i8* %dest
372*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
373*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotion8x8(<8 x i8>* %addr1, i8* %dest) {
374*9880d681SAndroid Build Coastguard Worker  %in1 = load <8 x i8>, <8 x i8>* %addr1, align 8
375*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <8 x i8> %in1, i32 1
376*9880d681SAndroid Build Coastguard Worker  %out = or i8 %extract, 1
377*9880d681SAndroid Build Coastguard Worker  store i8 %out, i8* %dest, align 4
378*9880d681SAndroid Build Coastguard Worker  ret void
379*9880d681SAndroid Build Coastguard Worker}
380*9880d681SAndroid Build Coastguard Worker
381*9880d681SAndroid Build Coastguard Worker; Check that we optimized the sequence correctly when it can be
382*9880d681SAndroid Build Coastguard Worker; lowered on a Q register.
383*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotion
384*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <4 x i32>, <4 x i32>* %addr1
385*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <4 x i32> [[LOAD]], <i32 undef, i32 1, i32 undef, i32 undef>
386*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <4 x i32> [[VECTOR_OR]], i32 1
387*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[EXTRACT]], i32* %dest
388*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret
389*9880d681SAndroid Build Coastguard Worker;
390*9880d681SAndroid Build Coastguard Worker; Make sure we got rid of any expensive vmov.32 instructions.
391*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: simpleOneInstructionPromotion4x32:
392*9880d681SAndroid Build Coastguard Worker; ASM: vld1.64 {[[LOAD:d[0-9]+]], d{{[0-9]+}}}, [r0]
393*9880d681SAndroid Build Coastguard Worker; The Q register used here must be [[LOAD]] / 2, but we cannot express that.
394*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: vorr.i32 q{{[[0-9]+}}, #0x1
395*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: vst1.32 {[[LOAD]][1]}, [r1]
396*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: bx
397*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotion4x32(<4 x i32>* %addr1, i32* %dest) {
398*9880d681SAndroid Build Coastguard Worker  %in1 = load <4 x i32>, <4 x i32>* %addr1, align 8
399*9880d681SAndroid Build Coastguard Worker  %extract = extractelement <4 x i32> %in1, i32 1
400*9880d681SAndroid Build Coastguard Worker  %out = or i32 %extract, 1
401*9880d681SAndroid Build Coastguard Worker  store i32 %out, i32* %dest, align 1
402*9880d681SAndroid Build Coastguard Worker  ret void
403*9880d681SAndroid Build Coastguard Worker}
404