r211362 - The ability to use vector initializer lists is a GNU vector extension
James Molloy
james.molloy at arm.com
Fri Jun 20 07:35:14 PDT 2014
Author: jamesm
Date: Fri Jun 20 09:35:13 2014
New Revision: 211362
URL: http://llvm.org/viewvc/llvm-project?rev=211362&view=rev
Log:
The ability to use vector initializer lists is a GNU vector extension
and is unrelated to the NEON intrinsics in arm_neon.h. On little
endian machines it works fine, however on big endian machines it
exhibits surprising behaviour:
uint32x2_t x = {42, 64};
return vget_lane_u32(x, 0); // Will return 64.
Because of this, explicitly call out that it is unsupported on big
endian machines.
This patch will emit the following warning in big-endian mode:
test.c:3:15: warning: vector initializers are a GNU extension and are not compatible with NEON intrinsics [-Wgnu]
int32x4_t x = {0, 1, 2, 3};
^
test.c:3:15: note: consider using vld1q_s32() to initialize a vector from memory, or vcombine_s32(vcreate_s32(), vcreate_s32()) to initialize from integer constants
1 warning generated.
Added:
cfe/trunk/test/Sema/big-endian-neon-initializers.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaInit.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=211362&r1=211361&r2=211362&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 20 09:35:13 2014
@@ -6729,6 +6729,16 @@ def err_invalid_neon_type_code : Error<
"incompatible constant for this __builtin_neon function">;
def err_argument_invalid_range : Error<
"argument should be a value from %0 to %1">;
+def warn_neon_vector_initializer_non_portable : Warning<
+ "vector initializers are not compatible with NEON intrinsics in big endian "
+ "mode">, InGroup<DiagGroup<"nonportable-vector-initialization">>;
+def note_neon_vector_initializer_non_portable : Note<
+ "consider using vld1_%0%1() to initialize a vector from memory, or "
+ "vcreate_%0%1() to initialize from an integer constant">;
+def note_neon_vector_initializer_non_portable_q : Note<
+ "consider using vld1q_%0%1() to initialize a vector from memory, or "
+ "vcombine_%0%1(vcreate_%0%1(), vcreate_%0%1()) to initialize from integer "
+ "constants">;
def err_builtin_longjmp_invalid_val : Error<
"argument to __builtin_longjmp must be a constant 1">;
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=211362&r1=211361&r2=211362&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Jun 20 09:35:13 2014
@@ -17,6 +17,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/SemaInternal.h"
@@ -1204,6 +1205,46 @@ void InitListChecker::CheckVectorType(co
CheckSubElementType(ElementEntity, IList, elementType, Index,
StructuredList, StructuredIndex);
}
+
+ if (VerifyOnly)
+ return;
+
+ bool isBigEndian = SemaRef.Context.getTargetInfo().isBigEndian();
+ const VectorType *T = Entity.getType()->getAs<VectorType>();
+ if (isBigEndian && (T->getVectorKind() == VectorType::NeonVector ||
+ T->getVectorKind() == VectorType::NeonPolyVector)) {
+ // The ability to use vector initializer lists is a GNU vector extension
+ // and is unrelated to the NEON intrinsics in arm_neon.h. On little
+ // endian machines it works fine, however on big endian machines it
+ // exhibits surprising behaviour:
+ //
+ // uint32x2_t x = {42, 64};
+ // return vget_lane_u32(x, 0); // Will return 64.
+ //
+ // Because of this, explicitly call out that it is non-portable.
+ //
+ SemaRef.Diag(IList->getLocStart(),
+ diag::warn_neon_vector_initializer_non_portable);
+
+ const char *typeCode;
+ unsigned typeSize = SemaRef.Context.getTypeSize(elementType);
+
+ if (elementType->isFloatingType())
+ typeCode = "f";
+ else if (elementType->isSignedIntegerType())
+ typeCode = "s";
+ else if (elementType->isUnsignedIntegerType())
+ typeCode = "u";
+ else
+ llvm_unreachable("Invalid element type!");
+
+ SemaRef.Diag(IList->getLocStart(),
+ SemaRef.Context.getTypeSize(VT) > 64 ?
+ diag::note_neon_vector_initializer_non_portable_q :
+ diag::note_neon_vector_initializer_non_portable)
+ << typeCode << typeSize;
+ }
+
return;
}
Added: cfe/trunk/test/Sema/big-endian-neon-initializers.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/big-endian-neon-initializers.c?rev=211362&view=auto
==============================================================================
--- cfe/trunk/test/Sema/big-endian-neon-initializers.c (added)
+++ cfe/trunk/test/Sema/big-endian-neon-initializers.c Fri Jun 20 09:35:13 2014
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -triple arm64_be -target-feature +neon -verify -fsyntax-only -ffreestanding
+// RUN: %clang_cc1 %s -triple armebv7 -target-cpu cortex-a8 -verify -fsyntax-only -ffreestanding
+
+#include <arm_neon.h>
+
+int32x4_t x = {1, 2, 3, 4}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1q_s32() to initialize a vector from memory, or vcombine_s32(vcreate_s32(), vcreate_s32()) to initialize from integer constants}}
+int16x4_t y = {1, 2, 3, 4}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1_s16() to initialize a vector from memory, or vcreate_s16() to initialize from an integer constant}}
+int64x2_t z = {1, 2}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1q_s64() to initialize a vector from memory, or vcombine_s64(vcreate_s64(), vcreate_s64()) to initialize from integer constants}}
+float32x2_t b = {1, 2}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1_f32() to initialize a vector from memory, or vcreate_f32() to initialize from an integer constant}}
+
+// No warning expected here.
+typedef int v4si __attribute__ ((vector_size (16)));
+v4si c = {1, 2, 3, 4};
More information about the cfe-commits
mailing list