Skip to content

Commit 5ea6117

Browse files
committed
[PowerPC] Emit error for Altivec vector initializations when -faltivec-src-compat=gcc is specified
Under the -faltivec-src-compat=gcc option, AltiVec vector initialization should be treated as if they were compiled with gcc - which is, to emit an error when the vectors are initialized in the parenthesized or non-parenthesized manner. This patch implements this behaviour. Differential Revision: https://reviews.llvm.org/D106410
1 parent 14c1450 commit 5ea6117

File tree

5 files changed

+72
-1
lines changed

5 files changed

+72
-1
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6100,6 +6100,13 @@ class Sema final {
61006100
// AltiVecPixel and AltiVecBool when -faltivec-src-compat=xl is specified.
61016101
bool ShouldSplatAltivecScalarInCast(const VectorType *VecTy);
61026102

6103+
// Checks if the -faltivec-src-compat=gcc option is specified.
6104+
// If so, AltiVecVector, AltiVecBool and AltiVecPixel types are
6105+
// treated the same way as they are when trying to initialize
6106+
// these vectors on gcc (an error is emitted).
6107+
bool CheckAltivecInitFromScalar(SourceRange R, QualType VecTy,
6108+
QualType SrcTy);
6109+
61036110
/// ActOnCXXNamedCast - Parse
61046111
/// {dynamic,static,reinterpret,const,addrspace}_cast's.
61056112
ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,

clang/lib/Sema/SemaCast.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2637,6 +2637,19 @@ bool Sema::ShouldSplatAltivecScalarInCast(const VectorType *VecTy) {
26372637
return false;
26382638
}
26392639

2640+
bool Sema::CheckAltivecInitFromScalar(SourceRange R, QualType VecTy,
2641+
QualType SrcTy) {
2642+
bool SrcCompatGCC = this->getLangOpts().getAltivecSrcCompat() ==
2643+
LangOptions::AltivecSrcCompatKind::GCC;
2644+
if (this->getLangOpts().AltiVec && SrcCompatGCC) {
2645+
this->Diag(R.getBegin(),
2646+
diag::err_invalid_conversion_between_vector_and_integer)
2647+
<< VecTy << SrcTy << R;
2648+
return true;
2649+
}
2650+
return false;
2651+
}
2652+
26402653
void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
26412654
bool ListInitialization) {
26422655
assert(Self.getLangOpts().CPlusPlus);
@@ -2690,14 +2703,20 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
26902703
}
26912704

26922705
// AltiVec vector initialization with a single literal.
2693-
if (const VectorType *vecTy = DestType->getAs<VectorType>())
2706+
if (const VectorType *vecTy = DestType->getAs<VectorType>()) {
2707+
if (Self.CheckAltivecInitFromScalar(OpRange, DestType,
2708+
SrcExpr.get()->getType())) {
2709+
SrcExpr = ExprError();
2710+
return;
2711+
}
26942712
if (Self.ShouldSplatAltivecScalarInCast(vecTy) &&
26952713
(SrcExpr.get()->getType()->isIntegerType() ||
26962714
SrcExpr.get()->getType()->isFloatingType())) {
26972715
Kind = CK_VectorSplat;
26982716
SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
26992717
return;
27002718
}
2719+
}
27012720

27022721
// C++ [expr.cast]p5: The conversions performed by
27032722
// - a const_cast,
@@ -2976,6 +2995,10 @@ void CastOperation::CheckCStyleCast() {
29762995
}
29772996

29782997
if (const VectorType *DestVecTy = DestType->getAs<VectorType>()) {
2998+
if (Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {
2999+
SrcExpr = ExprError();
3000+
return;
3001+
}
29793002
if (Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&
29803003
(SrcType->isIntegerType() || SrcType->isFloatingType())) {
29813004
Kind = CK_VectorSplat;

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7735,6 +7735,9 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,
77357735
// initializers must be one or must match the size of the vector.
77367736
// If a single value is specified in the initializer then it will be
77377737
// replicated to all the components of the vector
7738+
if (CheckAltivecInitFromScalar(E->getSourceRange(), Ty,
7739+
VTy->getElementType()))
7740+
return ExprError();
77387741
if (ShouldSplatAltivecScalarInCast(VTy)) {
77397742
// The number of initializers must be one or must match the size of the
77407743
// vector. If a single value is specified in the initializer then it will

clang/test/CodeGen/vector-bool-pixel-altivec-init-no-parentheses.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
55
// RUN: -faltivec-src-compat=mixed -triple powerpc64le-unknown-unknown -S \
66
// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=MIXED-ERR
7+
// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
8+
// RUN: -faltivec-src-compat=gcc -triple powerpc-unknown-unknown -S \
9+
// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=GCC-ERR
10+
// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
11+
// RUN: -faltivec-src-compat=gcc -triple powerpc64le-unknown-unknown -S \
12+
// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=GCC-ERR
713
// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
814
// RUN: -faltivec-src-compat=xl -triple powerpc-unknown-unknown -S \
915
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
@@ -14,6 +20,10 @@
1420
// RUN: -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=MIXED-ERR
1521
// RUN: not %clang -mcpu=pwr9 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
1622
// RUN: -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=MIXED-ERR
23+
// RUN: not %clang -mcpu=pwr8 -faltivec-src-compat=gcc --target=powerpc-unknown-unknown \
24+
// RUN: -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=GCC-ERR
25+
// RUN: not %clang -mcpu=pwr9 -faltivec-src-compat=gcc --target=powerpc-unknown-unknown \
26+
// RUN: -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=GCC-ERR
1727
// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
1828
// RUN: -S -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
1929
// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
@@ -40,49 +50,58 @@ void test_vector_bool_pixel_init_no_parentheses() {
4050
// vector bool char initialization
4151
vbi8_1 = (vector bool char)'a';
4252
// MIXED-ERR: error: invalid conversion between vector type '__vector __bool unsigned char'
53+
// GCC-ERR: error: invalid conversion between vector type '__vector __bool unsigned char' (vector of 16 'unsigned char' values) and integer type 'int' of different size
4354
// XL: <i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97>
4455
char c = 'c';
4556
vbi8_2 = (vector bool char)c;
4657
// MIXED-ERR: error: invalid conversion between vector type '__vector __bool unsigned char'
58+
// GCC-ERR: error: invalid conversion between vector type '__vector __bool unsigned char' (vector of 16 'unsigned char' values) and integer type 'char' of different size
4759
// XL: [[INS_ELT:%.*]] = insertelement <16 x i8>
4860
// XL: [[SHUFF:%.*]] = shufflevector <16 x i8> [[INS_ELT]], <16 x i8> poison, <16 x i32> zeroinitializer
4961
// XL: store <16 x i8> [[SHUFF]]
5062

5163
// vector bool short initialization
5264
vbi16_1 = (vector bool short)5;
5365
// MIXED-ERR: error: invalid conversion between vector type '__vector __bool unsigned short'
66+
// GCC-ERR: error: invalid conversion between vector type '__vector __bool unsigned short' (vector of 8 'unsigned short' values) and integer type 'int' of different size
5467
// XL: <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
5568
short si16 = 55;
5669
vbi16_2 = (vector bool short)si16;
5770
// MIXED-ERR: error: invalid conversion between vector type '__vector __bool unsigned short'
71+
// GCC-ERR: error: invalid conversion between vector type '__vector __bool unsigned short' (vector of 8 'unsigned short' values) and integer type 'short' of different size
5872
// XL: [[INS_ELT:%.*]] = insertelement <8 x i16>
5973
// XL: [[SHUFF:%.*]] = shufflevector <8 x i16> [[INS_ELT]], <8 x i16> poison, <8 x i32> zeroinitializer
6074
// XL: store <8 x i16> [[SHUFF]]
6175

6276
// vector bool int initialization
6377
vbi32_1 = (vector bool int)9;
6478
// MIXED-ERR: error: invalid conversion between vector type '__vector __bool unsigned int'
79+
// GCC-ERR: error: invalid conversion between vector type '__vector __bool unsigned int' (vector of 4 'unsigned int' values) and integer type 'int' of different size
6580
// XL: <i32 9, i32 9, i32 9, i32 9>
6681
int si32 = 99;
6782
vbi32_2 = (vector bool int)si32;
6883
// MIXED-ERR: error: invalid conversion between vector type '__vector __bool unsigned int'
84+
// GCC-ERR: error: invalid conversion between vector type '__vector __bool unsigned int' (vector of 4 'unsigned int' values) and integer type 'int' of different size
6985
// XL: [[INS_ELT:%.*]] = insertelement <4 x i32>
7086
// XL: [[SHUFF:%.*]] = shufflevector <4 x i32> [[INS_ELT]], <4 x i32> poison, <4 x i32> zeroinitializer
7187
// XL: store <4 x i32> [[SHUFF]]
7288

7389
// vector bool long long initialization
7490
vbi64_1 = (vector bool long long)13;
7591
// MIXED-ERR: error: invalid conversion between vector type '__vector __bool unsigned long long'
92+
// GCC-ERR: error: invalid conversion between vector type '__vector __bool unsigned long long' (vector of 2 'unsigned long long' values) and integer type 'int' of different size
7693
// XL: <i64 13, i64 13>
7794
long long si64 = 1313;
7895
vbi64_2 = (vector bool long long)si64;
7996
// MIXED-ERR: error: invalid conversion between vector type '__vector __bool unsigned long long'
97+
// GCC-ERR: error: invalid conversion between vector type '__vector __bool unsigned long long' (vector of 2 'unsigned long long' values) and integer type 'long long' of different size
8098
// XL: [[INS_ELT:%.*]] = insertelement <2 x i64>
8199
// XL: [[SHUFF:%.*]] = shufflevector <2 x i64> [[INS_ELT]], <2 x i64> poison, <2 x i32> zeroinitializer
82100
// XL: store <2 x i64> [[SHUFF]]
83101

84102
// vector pixel initialization
85103
p1 = (vector pixel)1;
86104
// MIXED-ERR: error: invalid conversion between vector type '__vector __pixel '
105+
// GCC-ERR: error: invalid conversion between vector type '__vector __pixel ' (vector of 8 'unsigned short' values) and integer type 'int' of different size
87106
// XL: <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
88107
}

clang/test/CodeGen/vector-bool-pixel-altivec-init.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
1111
// RUN: -faltivec-src-compat=xl -triple powerpc64le-unknown-unknown -S \
1212
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
13+
// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
14+
// RUN: -faltivec-src-compat=gcc -triple powerpc-unknown-unknown -S \
15+
// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=GCC
16+
// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
17+
// RUN: -faltivec-src-compat=gcc -triple powerpc64le-unknown-unknown -S \
18+
// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=GCC
1319
// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
1420
// RUN: -S -emit-llvm %s -o - | FileCheck %s --check-prefix=MIXED
1521
// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
@@ -18,6 +24,10 @@
1824
// RUN: -S -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
1925
// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
2026
// RUN: -S -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
27+
// RUN: not %clang -mcpu=pwr8 -faltivec-src-compat=gcc --target=powerpc-unknown-unknown \
28+
// RUN: -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=GCC
29+
// RUN: not %clang -mcpu=pwr9 -faltivec-src-compat=gcc --target=powerpc-unknown-unknown \
30+
// RUN: -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=GCC
2131

2232
// Vector bool type
2333
vector bool char vbi8_1;
@@ -41,52 +51,61 @@ void test_vector_bool_pixel_init() {
4151
vbi8_1 = (vector bool char)('a');
4252
// MIXED: <i8 97, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>
4353
// XL: <i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97>
54+
// GCC: error: invalid conversion between vector type '__vector __bool unsigned char' (vector of 16 'unsigned char' values) and integer type 'unsigned char' of different size
4455
char c = 'c';
4556
vbi8_2 = (vector bool char)(c);
4657
// MIXED: [[INS:%.*]] = insertelement <16 x i8>
4758
// MIXED: store <16 x i8> [[INS:%.*]]
4859
// XL: [[INS_ELT:%.*]] = insertelement <16 x i8>
4960
// XL: [[SHUFF:%.*]] = shufflevector <16 x i8> [[INS_ELT]], <16 x i8> poison, <16 x i32> zeroinitializer
5061
// XL: store <16 x i8> [[SHUFF]]
62+
// GCC: error: invalid conversion between vector type '__vector __bool unsigned char' (vector of 16 'unsigned char' values) and integer type 'unsigned char' of different size
5163

5264
// vector bool short initialization
5365
vbi16_1 = (vector bool short)(5);
5466
// MIXED: <i16 5, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>
5567
// XL: <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
68+
// GCC: error: invalid conversion between vector type '__vector __bool unsigned short' (vector of 8 'unsigned short' values) and integer type 'unsigned short' of different size
5669
short si16 = 55;
5770
vbi16_2 = (vector bool short)(si16);
5871
// MIXED: [[INS:%.*]] = insertelement <8 x i16>
5972
// MIXED: store <8 x i16> [[INS:%.*]]
6073
// XL: [[INS_ELT:%.*]] = insertelement <8 x i16>
6174
// XL: [[SHUFF:%.*]] = shufflevector <8 x i16> [[INS_ELT]], <8 x i16> poison, <8 x i32> zeroinitializer
6275
// XL: store <8 x i16> [[SHUFF]]
76+
// GCC: error: invalid conversion between vector type '__vector __bool unsigned short' (vector of 8 'unsigned short' values) and integer type 'unsigned short' of different size
6377

6478
// vector bool int initialization
6579
vbi32_1 = (vector bool int)(9);
6680
// MIXED: <i32 9, i32 0, i32 0, i32 0>
6781
// XL: <i32 9, i32 9, i32 9, i32 9>
82+
// GCC: error: invalid conversion between vector type '__vector __bool unsigned int' (vector of 4 'unsigned int' values) and integer type 'unsigned int' of different size
6883
int si32 = 99;
6984
vbi32_2 = (vector bool int)(si32);
7085
// MIXED: [[INS:%.*]] = insertelement <4 x i32>
7186
// MIXED: store <4 x i32> [[INS:%.*]]
7287
// XL: [[INS_ELT:%.*]] = insertelement <4 x i32>
7388
// XL: [[SHUFF:%.*]] = shufflevector <4 x i32> [[INS_ELT]], <4 x i32> poison, <4 x i32> zeroinitializer
7489
// XL: store <4 x i32> [[SHUFF]]
90+
// GCC: error: invalid conversion between vector type '__vector __bool unsigned int' (vector of 4 'unsigned int' values) and integer type 'unsigned int' of different size
7591

7692
// vector bool long long initialization
7793
vbi64_1 = (vector bool long long)(13);
7894
// MIXED: <i64 13, i64 0>
7995
// XL: <i64 13, i64 13>
96+
// GCC: error: invalid conversion between vector type '__vector __bool unsigned long long' (vector of 2 'unsigned long long' values) and integer type 'unsigned long long' of different size
8097
long long si64 = 1313;
8198
vbi64_2 = (vector bool long long)(si64);
8299
// MIXED: [[INS:%.*]] = insertelement <2 x i64>
83100
// MIXED: store <2 x i64> [[INS:%.*]]
84101
// XL: [[INS_ELT:%.*]] = insertelement <2 x i64>
85102
// XL: [[SHUFF:%.*]] = shufflevector <2 x i64> [[INS_ELT]], <2 x i64> poison, <2 x i32> zeroinitializer
86103
// XL: store <2 x i64> [[SHUFF]]
104+
// GCC: error: invalid conversion between vector type '__vector __bool unsigned long long' (vector of 2 'unsigned long long' values) and integer type 'unsigned long long' of different size
87105

88106
// vector pixel initialization
89107
p1 = (vector pixel)(1);
90108
// MIXED: <i16 1, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>
91109
// XL: <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
110+
// GCC: error: invalid conversion between vector type '__vector __pixel ' (vector of 8 'unsigned short' values) and integer type 'unsigned short' of different size
92111
}

0 commit comments

Comments
 (0)