Skip to content

Commit 8267e7d

Browse files
committedDec 4, 2015
LLDB JIT needs android vector passing rules.
Summary: Looking into some recent issues with LLDBs expression parser highlighted that upstream clang passes vectors types differently to Android Open Source Project's clang for Arm Android targets. This patch reflects the changes present in the AOSP and allows LLDB's JIT expression evaluation to work correctly for Arm Android targets when passing vectors. This is submitted with consent of the original author Stephen Hines. Reviewers: asl, rsmith, ADodds, rnk Subscribers: rnk, aemerson, tberghammer, danalbert, srhines, cfe-commits, pirama Differential Revision: http://reviews.llvm.org/D14639 llvm-svn: 254682
1 parent c07cbc8 commit 8267e7d

File tree

2 files changed

+94
-9
lines changed

2 files changed

+94
-9
lines changed
 

Diff for: ‎clang/lib/CodeGen/TargetInfo.cpp

+26-9
Original file line numberDiff line numberDiff line change
@@ -4730,6 +4730,11 @@ class ARMABIInfo : public ABIInfo {
47304730
}
47314731
}
47324732

4733+
bool isAndroid() const {
4734+
return (getTarget().getTriple().getEnvironment() ==
4735+
llvm::Triple::Android);
4736+
}
4737+
47334738
ABIKind getABIKind() const { return Kind; }
47344739

47354740
private:
@@ -5233,15 +5238,27 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
52335238

52345239
/// isIllegalVector - check whether Ty is an illegal vector type.
52355240
bool ARMABIInfo::isIllegalVectorType(QualType Ty) const {
5236-
if (const VectorType *VT = Ty->getAs<VectorType>()) {
5237-
// Check whether VT is legal.
5238-
unsigned NumElements = VT->getNumElements();
5239-
uint64_t Size = getContext().getTypeSize(VT);
5240-
// NumElements should be power of 2.
5241-
if ((NumElements & (NumElements - 1)) != 0)
5242-
return true;
5243-
// Size should be greater than 32 bits.
5244-
return Size <= 32;
5241+
if (const VectorType *VT = Ty->getAs<VectorType> ()) {
5242+
if (isAndroid()) {
5243+
// Android shipped using Clang 3.1, which supported a slightly different
5244+
// vector ABI. The primary differences were that 3-element vector types
5245+
// were legal, and so were sub 32-bit vectors (i.e. <2 x i8>). This path
5246+
// accepts that legacy behavior for Android only.
5247+
// Check whether VT is legal.
5248+
unsigned NumElements = VT->getNumElements();
5249+
// NumElements should be power of 2 or equal to 3.
5250+
if (!llvm::isPowerOf2_32(NumElements) && NumElements != 3)
5251+
return true;
5252+
} else {
5253+
// Check whether VT is legal.
5254+
unsigned NumElements = VT->getNumElements();
5255+
uint64_t Size = getContext().getTypeSize(VT);
5256+
// NumElements should be power of 2.
5257+
if (!llvm::isPowerOf2_32(NumElements))
5258+
return true;
5259+
// Size should be greater than 32 bits.
5260+
return Size <= 32;
5261+
}
52455262
}
52465263
return false;
52475264
}

Diff for: ‎clang/test/CodeGen/arm-abi-vector.c

+68
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi aapcs -emit-llvm -o - %s | FileCheck %s
22
// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi apcs-gnu -emit-llvm -o - %s | FileCheck -check-prefix=APCS-GNU %s
3+
// RUN: %clang_cc1 -triple arm-linux-androideabi -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s
34

45
#include <stdarg.h>
56

@@ -28,6 +29,14 @@ double varargs_vec_2i(int fixed, ...) {
2829
// APCS-GNU: [[AP_CAST:%.*]] = bitcast i8* [[AP]] to <2 x i32>*
2930
// APCS-GNU: [[VEC:%.*]] = load <2 x i32>, <2 x i32>* [[AP_CAST]], align 4
3031
// APCS-GNU: store <2 x i32> [[VEC]], <2 x i32>* [[VAR]], align 8
32+
// ANDROID: varargs_vec_2i
33+
// ANDROID: [[VAR:%.*]] = alloca <2 x i32>, align 8
34+
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
35+
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
36+
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i32 8
37+
// ANDROID: [[AP_CAST:%.*]] = bitcast i8* [[AP_ALIGN]] to <2 x i32>*
38+
// ANDROID: [[VEC:%.*]] = load <2 x i32>, <2 x i32>* [[AP_CAST]], align 8
39+
// ANDROID: store <2 x i32> [[VEC]], <2 x i32>* [[VAR]], align 8
3140
va_list ap;
3241
double sum = fixed;
3342
va_start(ap, fixed);
@@ -42,6 +51,8 @@ double test_2i(__int2 *in) {
4251
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_2i(i32 3, <2 x i32> {{%.*}})
4352
// APCS-GNU: test_2i
4453
// APCS-GNU: call double (i32, ...) @varargs_vec_2i(i32 3, <2 x i32> {{%.*}})
54+
// ANDROID: test_2i
55+
// ANDROID: call double (i32, ...) @varargs_vec_2i(i32 3, <2 x i32> {{%.*}})
4556
return varargs_vec_2i(3, *in);
4657
}
4758

@@ -54,6 +65,10 @@ double varargs_vec_3c(int fixed, ...) {
5465
// APCS-GNU: alloca <3 x i8>, align 4
5566
// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP:%.*]], i32 4
5667
// APCS-GNU: bitcast i8* [[AP]] to <3 x i8>*
68+
// ANDROID: varargs_vec_3c
69+
// ANDROID: alloca <3 x i8>, align 4
70+
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP:%.*]], i32 4
71+
// ANDROID: bitcast i8* [[AP]] to <3 x i8>*
5772
va_list ap;
5873
double sum = fixed;
5974
va_start(ap, fixed);
@@ -68,6 +83,8 @@ double test_3c(__char3 *in) {
6883
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_3c(i32 3, i32 {{%.*}})
6984
// APCS-GNU: test_3c
7085
// APCS-GNU: call double (i32, ...) @varargs_vec_3c(i32 3, i32 {{%.*}})
86+
// ANDROID: test_3c
87+
// ANDROID: call double (i32, ...) @varargs_vec_3c(i32 3, <3 x i8> {{%.*}})
7188
return varargs_vec_3c(3, *in);
7289
}
7390

@@ -87,6 +104,14 @@ double varargs_vec_5c(int fixed, ...) {
87104
// APCS-GNU: [[AP_CAST:%.*]] = bitcast i8* [[AP]] to <5 x i8>*
88105
// APCS-GNU: [[VEC:%.*]] = load <5 x i8>, <5 x i8>* [[AP_CAST]], align 4
89106
// APCS-GNU: store <5 x i8> [[VEC]], <5 x i8>* [[VAR]], align 8
107+
// ANDROID: varargs_vec_5c
108+
// ANDROID: [[VAR:%.*]] = alloca <5 x i8>, align 8
109+
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
110+
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
111+
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i32 8
112+
// ANDROID: [[AP_CAST:%.*]] = bitcast i8* [[AP_ALIGN]] to <5 x i8>*
113+
// ANDROID: [[VEC:%.*]] = load <5 x i8>, <5 x i8>* [[AP_CAST]], align 8
114+
// ANDROID: store <5 x i8> [[VEC]], <5 x i8>* [[VAR]], align 8
90115
va_list ap;
91116
double sum = fixed;
92117
va_start(ap, fixed);
@@ -101,6 +126,8 @@ double test_5c(__char5 *in) {
101126
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_5c(i32 5, <2 x i32> {{%.*}})
102127
// APCS-GNU: test_5c
103128
// APCS-GNU: call double (i32, ...) @varargs_vec_5c(i32 5, <2 x i32> {{%.*}})
129+
// ANDROID: test_5c
130+
// ANDROID: call double (i32, ...) @varargs_vec_5c(i32 5, <2 x i32> {{%.*}})
104131
return varargs_vec_5c(5, *in);
105132
}
106133

@@ -120,6 +147,14 @@ double varargs_vec_9c(int fixed, ...) {
120147
// APCS-GNU: [[AP_CAST:%.*]] = bitcast i8* [[AP]] to <9 x i8>*
121148
// APCS-GNU: [[VEC:%.*]] = load <9 x i8>, <9 x i8>* [[AP_CAST]], align 4
122149
// APCS-GNU: store <9 x i8> [[VEC]], <9 x i8>* [[VAR]], align 16
150+
// ANDROID: varargs_vec_9c
151+
// ANDROID: [[VAR:%.*]] = alloca <9 x i8>, align 16
152+
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
153+
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
154+
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i32 16
155+
// ANDROID: [[AP_CAST:%.*]] = bitcast i8* [[AP_ALIGN]] to <9 x i8>*
156+
// ANDROID: [[T0:%.*]] = load <9 x i8>, <9 x i8>* [[AP_CAST]], align 8
157+
// ANDROID: store <9 x i8> [[T0]], <9 x i8>* [[VAR]], align 16
123158
va_list ap;
124159
double sum = fixed;
125160
va_start(ap, fixed);
@@ -134,6 +169,8 @@ double test_9c(__char9 *in) {
134169
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_9c(i32 9, <4 x i32> {{%.*}})
135170
// APCS-GNU: test_9c
136171
// APCS-GNU: call double (i32, ...) @varargs_vec_9c(i32 9, <4 x i32> {{%.*}})
172+
// ANDROID: test_9c
173+
// ANDROID: call double (i32, ...) @varargs_vec_9c(i32 9, <4 x i32> {{%.*}})
137174
return varargs_vec_9c(9, *in);
138175
}
139176

@@ -146,6 +183,10 @@ double varargs_vec_19c(int fixed, ...) {
146183
// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP:%.*]], i32 4
147184
// APCS-GNU: [[VAR:%.*]] = bitcast i8* [[AP]] to <19 x i8>**
148185
// APCS-GNU: [[VAR2:%.*]] = load <19 x i8>*, <19 x i8>** [[VAR]]
186+
// ANDROID: varargs_vec_19c
187+
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP:%.*]], i32 4
188+
// ANDROID: [[VAR:%.*]] = bitcast i8* [[AP]] to <19 x i8>**
189+
// ANDROID: [[VAR2:%.*]] = load <19 x i8>*, <19 x i8>** [[VAR]]
149190
va_list ap;
150191
double sum = fixed;
151192
va_start(ap, fixed);
@@ -160,6 +201,8 @@ double test_19c(__char19 *in) {
160201
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}})
161202
// APCS-GNU: test_19c
162203
// APCS-GNU: call double (i32, ...) @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}})
204+
// ANDROID: test_19c
205+
// ANDROID: call double (i32, ...) @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}})
163206
return varargs_vec_19c(19, *in);
164207
}
165208

@@ -176,6 +219,12 @@ double varargs_vec_3s(int fixed, ...) {
176219
// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP]], i32 8
177220
// APCS-GNU: [[AP_CAST:%.*]] = bitcast i8* [[AP]] to <3 x i16>*
178221
// APCS-GNU: [[VEC:%.*]] = load <3 x i16>, <3 x i16>* [[AP_CAST]], align 4
222+
// ANDROID: varargs_vec_3s
223+
// ANDROID: alloca <3 x i16>, align 8
224+
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
225+
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
226+
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i32 8
227+
// ANDROID: bitcast i8* [[AP_ALIGN]] to <3 x i16>*
179228
va_list ap;
180229
double sum = fixed;
181230
va_start(ap, fixed);
@@ -190,6 +239,8 @@ double test_3s(__short3 *in) {
190239
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_3s(i32 3, <2 x i32> {{%.*}})
191240
// APCS-GNU: test_3s
192241
// APCS-GNU: call double (i32, ...) @varargs_vec_3s(i32 3, <2 x i32> {{%.*}})
242+
// ANDROID: test_3s
243+
// ANDROID: call double (i32, ...) @varargs_vec_3s(i32 3, <3 x i16> {{%.*}})
193244
return varargs_vec_3s(3, *in);
194245
}
195246

@@ -208,6 +259,14 @@ double varargs_vec_5s(int fixed, ...) {
208259
// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP]], i32 16
209260
// APCS-GNU: [[AP_CAST:%.*]] = bitcast i8* [[AP]] to <5 x i16>*
210261
// APCS-GNU: [[VEC:%.*]] = load <5 x i16>, <5 x i16>* [[AP_CAST]], align 4
262+
// ANDROID: varargs_vec_5s
263+
// ANDROID: [[VAR_ALIGN:%.*]] = alloca <5 x i16>, align 16
264+
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
265+
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
266+
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i32 16
267+
// ANDROID: [[AP_CAST:%.*]] = bitcast i8* [[AP_ALIGN]] to <5 x i16>*
268+
// ANDROID: [[VEC:%.*]] = load <5 x i16>, <5 x i16>* [[AP_CAST]], align 8
269+
// ANDROID: store <5 x i16> [[VEC]], <5 x i16>* [[VAR_ALIGN]], align 16
211270
va_list ap;
212271
double sum = fixed;
213272
va_start(ap, fixed);
@@ -222,6 +281,8 @@ double test_5s(__short5 *in) {
222281
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_5s(i32 5, <4 x i32> {{%.*}})
223282
// APCS-GNU: test_5s
224283
// APCS-GNU: call double (i32, ...) @varargs_vec_5s(i32 5, <4 x i32> {{%.*}})
284+
// ANDROID: test_5s
285+
// ANDROID: call double (i32, ...) @varargs_vec_5s(i32 5, <4 x i32> {{%.*}})
225286
return varargs_vec_5s(5, *in);
226287
}
227288

@@ -243,6 +304,11 @@ double varargs_struct(int fixed, ...) {
243304
// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* {{%.*}}, i32 16
244305
// APCS-GNU: bitcast %struct.StructWithVec* [[VAR_ALIGN]] to i8*
245306
// APCS-GNU: call void @llvm.memcpy
307+
// ANDROID: varargs_struct
308+
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
309+
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
310+
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i32 16
311+
// ANDROID: bitcast i8* [[AP_ALIGN]] to %struct.StructWithVec*
246312
va_list ap;
247313
double sum = fixed;
248314
va_start(ap, fixed);
@@ -257,5 +323,7 @@ double test_struct(StructWithVec* d) {
257323
// CHECK: call arm_aapcscc double (i32, ...) @varargs_struct(i32 3, [2 x i64] {{%.*}})
258324
// APCS-GNU: test_struct
259325
// APCS-GNU: call double (i32, ...) @varargs_struct(i32 3, [2 x i64] {{%.*}})
326+
// ANDROID: test_struct
327+
// ANDROID: call double (i32, ...) @varargs_struct(i32 3, [2 x i64] {{%.*}})
260328
return varargs_struct(3, *d);
261329
}

0 commit comments

Comments
 (0)
Please sign in to comment.