Add support for System z vector language extensions

The z13 vector facility has an associated language extension,
closely modeled on AltiVec/VSX.  The main differences are:

- vector long, vector float and vector pixel are not supported

- vector long long and vector double are supported (like VSX)

- comparison operators return a vector rather than a scalar integer

- shift operators behave like the OpenCL shift operators

- vector bool is only supported as argument to certain operators;
  some operators allow mixing a bool with a non-bool vector 

This patch adds clang support for the extension.  It is closely modelled
on the AltiVec support.  Similarly to the -faltivec option, there's a
new -fzvector option to enable the extensions (as well as an -mzvector
alias for compatibility with GCC).  There's also a separate LangOpt.

The extension as implemented here is intended to be compatible with
the -mzvector extension recently implemented by GCC.

Based on a patch by Richard Sandiford.

Differential Revision: http://reviews.llvm.org/D11001

llvm-svn: 243642
This commit is contained in:
Ulrich Weigand 2015-07-30 14:08:36 +00:00
parent 40631133b4
commit 3c5038a535
19 changed files with 3983 additions and 46 deletions

View File

@ -358,6 +358,10 @@ def err_invalid_pixel_decl_spec_combination : Error<
"'%0' declaration specifier not allowed here">;
def err_invalid_vector_bool_decl_spec : Error<
"cannot use '%0' with '__vector bool'">;
def err_invalid_vector_long_decl_spec : Error<
"cannot use 'long' with '__vector'">;
def err_invalid_vector_float_decl_spec : Error<
"cannot use 'float' with '__vector'">;
def err_invalid_vector_double_decl_spec : Error <
"use of 'double' with '__vector' requires VSX support to be enabled "
"(available on POWER7 or later)">;

View File

@ -104,6 +104,7 @@ LANGOPT(WritableStrings , 1, 0, "writable string support")
LANGOPT(ConstStrings , 1, 0, "const-qualified string support")
LANGOPT(LaxVectorConversions , 1, 1, "lax vector conversions")
LANGOPT(AltiVec , 1, 0, "AltiVec-style vector initializers")
LANGOPT(ZVector , 1, 0, "System z vector extensions")
LANGOPT(Exceptions , 1, 0, "exception handling")
LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions")
LANGOPT(CXXExceptions , 1, 0, "C++ exceptions")

View File

@ -239,6 +239,8 @@ PUNCTUATOR(greatergreatergreater, ">>>")
// KEYOPENCL - This is a keyword in OpenCL
// KEYNOOPENCL - This is a keyword that is not supported in OpenCL
// KEYALTIVEC - This is a keyword in AltiVec
// KEYZVECTOR - This is a keyword for the System z vector extensions,
// which are heavily based on AltiVec
// KEYBORLAND - This is a keyword if Borland extensions are enabled
// BOOLSUPPORT - This is a keyword if 'bool' is a built-in type
// HALFSUPPORT - This is a keyword if 'half' is a built-in type
@ -501,7 +503,7 @@ ALIAS("write_only", __write_only , KEYOPENCL)
ALIAS("read_write", __read_write , KEYOPENCL)
// OpenCL builtins
KEYWORD(__builtin_astype , KEYOPENCL)
KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC)
KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC|KEYZVECTOR)
// OpenMP Type Traits
KEYWORD(__builtin_omp_required_simd_align, KEYALL)
@ -510,9 +512,9 @@ KEYWORD(__builtin_omp_required_simd_align, KEYALL)
KEYWORD(__pascal , KEYALL)
// Altivec Extension.
KEYWORD(__vector , KEYALTIVEC)
KEYWORD(__vector , KEYALTIVEC|KEYZVECTOR)
KEYWORD(__pixel , KEYALTIVEC)
KEYWORD(__bool , KEYALTIVEC)
KEYWORD(__bool , KEYALTIVEC|KEYZVECTOR)
// ARM NEON extensions.
ALIAS("__fp16", half , KEYALL)

View File

@ -1354,6 +1354,13 @@ def mno_altivec : Flag<["-"], "mno-altivec">, Alias<fno_altivec>;
def mvx : Flag<["-"], "mvx">, Group<m_Group>;
def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
def fzvector : Flag<["-"], "fzvector">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable System z vector language extension">;
def fno_zvector : Flag<["-"], "fno-zvector">, Group<f_Group>,
Flags<[CC1Option]>;
def mzvector : Flag<["-"], "mzvector">, Alias<fzvector>;
def mno_zvector : Flag<["-"], "mno-zvector">, Alias<fno_zvector>;
def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>;
def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>;
def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>,

View File

@ -108,12 +108,13 @@ class Parser : public CodeCompletionHandler {
/// Ident_super - IdentifierInfo for "super", to support fast
/// comparison.
IdentifierInfo *Ident_super;
/// Ident_vector, Ident_pixel, Ident_bool - cached IdentifierInfo's
/// for "vector", "pixel", and "bool" fast comparison. Only present
/// if AltiVec enabled.
/// Ident_vector, Ident_bool - cached IdentifierInfos for "vector" and
/// "bool" fast comparison. Only present if AltiVec or ZVector are enabled.
IdentifierInfo *Ident_vector;
IdentifierInfo *Ident_pixel;
IdentifierInfo *Ident_bool;
/// Ident_pixel - cached IdentifierInfos for "pixel" fast comparison.
/// Only present if AltiVec enabled.
IdentifierInfo *Ident_pixel;
/// Objective-C contextual keywords.
mutable IdentifierInfo *Ident_instancetype;
@ -605,10 +606,12 @@ private:
bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
bool &isInvalid) {
if (!getLangOpts().AltiVec ||
(Tok.getIdentifierInfo() != Ident_vector &&
Tok.getIdentifierInfo() != Ident_pixel &&
Tok.getIdentifierInfo() != Ident_bool))
if (!getLangOpts().AltiVec && !getLangOpts().ZVector)
return false;
if (Tok.getIdentifierInfo() != Ident_vector &&
Tok.getIdentifierInfo() != Ident_bool &&
(!getLangOpts().AltiVec || Tok.getIdentifierInfo() != Ident_pixel))
return false;
return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid);
@ -618,7 +621,7 @@ private:
/// identifier token, replacing it with the non-context-sensitive __vector.
/// This returns true if the token was replaced.
bool TryAltiVecVectorToken() {
if (!getLangOpts().AltiVec ||
if ((!getLangOpts().AltiVec && !getLangOpts().ZVector) ||
Tok.getIdentifierInfo() != Ident_vector) return false;
return TryAltiVecVectorTokenOutOfLine();
}

View File

@ -8370,7 +8370,8 @@ public:
/// type checking for vector binary operators.
QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign);
SourceLocation Loc, bool IsCompAssign,
bool AllowBothBool, bool AllowBoolConversion);
QualType GetSignedVectorType(QualType V);
QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool isRelational);

View File

@ -110,7 +110,8 @@ namespace {
HALFSUPPORT = 0x08000,
KEYCONCEPTS = 0x10000,
KEYOBJC2 = 0x20000,
KEYALL = (0x3ffff & ~KEYNOMS18 &
KEYZVECTOR = 0x40000,
KEYALL = (0x7ffff & ~KEYNOMS18 &
~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude.
};

View File

@ -67,6 +67,7 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
.Case("objc_arc", LangOpts.ObjCAutoRefCount)
.Case("opencl", LangOpts.OpenCL)
.Case("tls", Target.isTLSSupported())
.Case("zvector", LangOpts.ZVector)
.Default(Target.hasFeature(Feature));
if (!HasFeature)
HasFeature = std::find(LangOpts.ModuleFeatures.begin(),

View File

@ -5829,6 +5829,8 @@ public:
Builder.defineMacro("__LONG_DOUBLE_128__");
if (HasTransactionalExecution)
Builder.defineMacro("__HTM__");
if (Opts.ZVector)
Builder.defineMacro("__VEC__", "10301");
}
void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const override {

View File

@ -4053,9 +4053,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
EmulatedTLSDefault))
CmdArgs.push_back("-femulated-tls");
// AltiVec language extensions aren't relevant for assembling.
if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm)
// AltiVec-like language extensions aren't relevant for assembling.
if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm) {
Args.AddLastArg(CmdArgs, options::OPT_faltivec);
Args.AddLastArg(CmdArgs, options::OPT_fzvector);
}
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
@ -4100,6 +4102,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
<< "ppc/ppc64/ppc64le";
}
// -fzvector is incompatible with -faltivec.
if (Arg *A = Args.getLastArg(options::OPT_fzvector))
if (Args.hasArg(options::OPT_faltivec))
D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
<< "-faltivec";
if (getToolChain().SupportsProfiling())
Args.AddLastArg(CmdArgs, options::OPT_pg);

View File

@ -1264,6 +1264,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
// OpenCL has some additional defaults.
if (Opts.OpenCL) {
Opts.AltiVec = 0;
Opts.ZVector = 0;
Opts.CXXOperatorNames = 1;
Opts.LaxVectorConversions = 0;
Opts.DefaultFPContract = 1;
@ -1452,6 +1453,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
if (Args.hasArg(OPT_faltivec))
Opts.AltiVec = 1;
if (Args.hasArg(OPT_fzvector))
Opts.ZVector = 1;
if (Args.hasArg(OPT_pthread))
Opts.POSIXThreads = 1;

View File

@ -476,11 +476,12 @@ void Parser::Initialize() {
Ident_super = &PP.getIdentifierTable().get("super");
if (getLangOpts().AltiVec) {
if (getLangOpts().AltiVec || getLangOpts().ZVector) {
Ident_vector = &PP.getIdentifierTable().get("vector");
Ident_pixel = &PP.getIdentifierTable().get("pixel");
Ident_bool = &PP.getIdentifierTable().get("bool");
}
if (getLangOpts().AltiVec)
Ident_pixel = &PP.getIdentifierTable().get("pixel");
Ident_introduced = nullptr;
Ident_deprecated = nullptr;

View File

@ -987,10 +987,11 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
<< getSpecifierName((TSW)TypeSpecWidth);
// vector bool long long requires VSX support.
// vector bool long long requires VSX support or ZVector.
if ((TypeSpecWidth == TSW_longlong) &&
(!PP.getTargetInfo().hasFeature("vsx")) &&
(!PP.getTargetInfo().hasFeature("power8-vector")))
(!PP.getTargetInfo().hasFeature("power8-vector")) &&
!PP.getLangOpts().ZVector)
Diag(D, TSTLoc, diag::err_invalid_vector_long_long_decl_spec);
// Elements of vector bool are interpreted as unsigned. (PIM 2.1)
@ -999,14 +1000,23 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
TypeSpecSign = TSS_unsigned;
} else if (TypeSpecType == TST_double) {
// vector long double and vector long long double are never allowed.
// vector double is OK for Power7 and later.
// vector double is OK for Power7 and later, and ZVector.
if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong)
Diag(D, TSWLoc, diag::err_invalid_vector_long_double_decl_spec);
else if (!PP.getTargetInfo().hasFeature("vsx"))
else if (!PP.getTargetInfo().hasFeature("vsx") &&
!PP.getLangOpts().ZVector)
Diag(D, TSTLoc, diag::err_invalid_vector_double_decl_spec);
} else if (TypeSpecType == TST_float) {
// vector float is unsupported for ZVector.
if (PP.getLangOpts().ZVector)
Diag(D, TSTLoc, diag::err_invalid_vector_float_decl_spec);
} else if (TypeSpecWidth == TSW_long) {
Diag(D, TSWLoc, diag::warn_vector_long_decl_spec_combination)
<< getSpecifierName((TST)TypeSpecType, Policy);
// vector long is unsupported for ZVector and deprecated for AltiVec.
if (PP.getLangOpts().ZVector)
Diag(D, TSWLoc, diag::err_invalid_vector_long_decl_spec);
else
Diag(D, TSWLoc, diag::warn_vector_long_decl_spec_combination)
<< getSpecifierName((TST)TypeSpecType, Policy);
}
if (TypeAltiVecPixel) {

View File

@ -5516,7 +5516,7 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
// i.e. all the elements are integer constants.
ParenExpr *PE = dyn_cast<ParenExpr>(CastExpr);
ParenListExpr *PLE = dyn_cast<ParenListExpr>(CastExpr);
if ((getLangOpts().AltiVec || getLangOpts().OpenCL)
if ((getLangOpts().AltiVec || getLangOpts().ZVector || getLangOpts().OpenCL)
&& castType->isVectorType() && (PE || PLE)) {
if (PLE && PLE->getNumExprs() == 0) {
Diag(PLE->getExprLoc(), diag::err_altivec_empty_initializer);
@ -6073,7 +6073,9 @@ OpenCLCheckVectorConditional(Sema &S, ExprResult &Cond,
if (LHS.get()->getType()->isVectorType() ||
RHS.get()->getType()->isVectorType()) {
QualType VecResTy = S.CheckVectorOperands(LHS, RHS, QuestionLoc,
/*isCompAssign*/false);
/*isCompAssign*/false,
/*AllowBothBool*/true,
/*AllowBoolConversions*/false);
if (VecResTy.isNull()) return QualType();
// The result type must match the condition type as specified in
// OpenCL v1.1 s6.11.6.
@ -6124,7 +6126,9 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// Now check the two expressions.
if (LHS.get()->getType()->isVectorType() ||
RHS.get()->getType()->isVectorType())
return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false);
return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false,
/*AllowBothBool*/true,
/*AllowBoolConversions*/false);
QualType ResTy = UsualArithmeticConversions(LHS, RHS);
if (LHS.isInvalid() || RHS.isInvalid())
@ -7265,7 +7269,9 @@ static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
}
QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign) {
SourceLocation Loc, bool IsCompAssign,
bool AllowBothBool,
bool AllowBoolConversions) {
if (!IsCompAssign) {
LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
if (LHS.isInvalid())
@ -7280,14 +7286,21 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
QualType LHSType = LHS.get()->getType().getUnqualifiedType();
QualType RHSType = RHS.get()->getType().getUnqualifiedType();
// If the vector types are identical, return.
if (Context.hasSameType(LHSType, RHSType))
return LHSType;
const VectorType *LHSVecType = LHSType->getAs<VectorType>();
const VectorType *RHSVecType = RHSType->getAs<VectorType>();
assert(LHSVecType || RHSVecType);
// AltiVec-style "vector bool op vector bool" combinations are allowed
// for some operators but not others.
if (!AllowBothBool &&
LHSVecType && LHSVecType->getVectorKind() == VectorType::AltiVecBool &&
RHSVecType && RHSVecType->getVectorKind() == VectorType::AltiVecBool)
return InvalidOperands(Loc, LHS, RHS);
// If the vector types are identical, return.
if (Context.hasSameType(LHSType, RHSType))
return LHSType;
// If we have compatible AltiVec and GCC vector types, use the AltiVec type.
if (LHSVecType && RHSVecType &&
Context.areCompatibleVectorTypes(LHSType, RHSType)) {
@ -7301,6 +7314,28 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
return RHSType;
}
// AllowBoolConversions says that bool and non-bool AltiVec vectors
// can be mixed, with the result being the non-bool type. The non-bool
// operand must have integer element type.
if (AllowBoolConversions && LHSVecType && RHSVecType &&
LHSVecType->getNumElements() == RHSVecType->getNumElements() &&
(Context.getTypeSize(LHSVecType->getElementType()) ==
Context.getTypeSize(RHSVecType->getElementType()))) {
if (LHSVecType->getVectorKind() == VectorType::AltiVecVector &&
LHSVecType->getElementType()->isIntegerType() &&
RHSVecType->getVectorKind() == VectorType::AltiVecBool) {
RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
return LHSType;
}
if (!IsCompAssign &&
LHSVecType->getVectorKind() == VectorType::AltiVecBool &&
RHSVecType->getVectorKind() == VectorType::AltiVecVector &&
RHSVecType->getElementType()->isIntegerType()) {
LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast);
return RHSType;
}
}
// If there's an ext-vector type and a scalar, try to convert the scalar to
// the vector element type and splat.
if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
@ -7389,7 +7424,9 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS,
if (LHS.get()->getType()->isVectorType() ||
RHS.get()->getType()->isVectorType())
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign);
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign,
/*AllowBothBool*/getLangOpts().AltiVec,
/*AllowBoolConversions*/false);
QualType compType = UsualArithmeticConversions(LHS, RHS, IsCompAssign);
if (LHS.isInvalid() || RHS.isInvalid())
@ -7418,7 +7455,9 @@ QualType Sema::CheckRemainderOperands(
RHS.get()->getType()->isVectorType()) {
if (LHS.get()->getType()->hasIntegerRepresentation() &&
RHS.get()->getType()->hasIntegerRepresentation())
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign);
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign,
/*AllowBothBool*/getLangOpts().AltiVec,
/*AllowBoolConversions*/false);
return InvalidOperands(Loc, LHS, RHS);
}
@ -7704,7 +7743,10 @@ QualType Sema::CheckAdditionOperands( // C99 6.5.6
if (LHS.get()->getType()->isVectorType() ||
RHS.get()->getType()->isVectorType()) {
QualType compType = CheckVectorOperands(LHS, RHS, Loc, CompLHSTy);
QualType compType = CheckVectorOperands(
LHS, RHS, Loc, CompLHSTy,
/*AllowBothBool*/getLangOpts().AltiVec,
/*AllowBoolConversions*/getLangOpts().ZVector);
if (CompLHSTy) *CompLHSTy = compType;
return compType;
}
@ -7779,7 +7821,10 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
if (LHS.get()->getType()->isVectorType() ||
RHS.get()->getType()->isVectorType()) {
QualType compType = CheckVectorOperands(LHS, RHS, Loc, CompLHSTy);
QualType compType = CheckVectorOperands(
LHS, RHS, Loc, CompLHSTy,
/*AllowBothBool*/getLangOpts().AltiVec,
/*AllowBoolConversions*/getLangOpts().ZVector);
if (CompLHSTy) *CompLHSTy = compType;
return compType;
}
@ -8021,7 +8066,21 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
RHS.get()->getType()->isVectorType()) {
if (LangOpts.OpenCL)
return checkOpenCLVectorShift(*this, LHS, RHS, Loc, IsCompAssign);
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign);
if (LangOpts.ZVector) {
// The shift operators for the z vector extensions work basically
// like OpenCL shifts, except that neither the LHS nor the RHS is
// allowed to be a "vector bool".
if (auto LHSVecType = LHS.get()->getType()->getAs<VectorType>())
if (LHSVecType->getVectorKind() == VectorType::AltiVecBool)
return InvalidOperands(Loc, LHS, RHS);
if (auto RHSVecType = RHS.get()->getType()->getAs<VectorType>())
if (RHSVecType->getVectorKind() == VectorType::AltiVecBool)
return InvalidOperands(Loc, LHS, RHS);
return checkOpenCLVectorShift(*this, LHS, RHS, Loc, IsCompAssign);
}
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign,
/*AllowBothBool*/true,
/*AllowBoolConversions*/false);
}
// Shifts don't perform usual arithmetic conversions, they just do integer
@ -8795,7 +8854,9 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
bool IsRelational) {
// Check to make sure we're operating on vectors of the same type and width,
// Allowing one side to be a scalar of element type.
QualType vType = CheckVectorOperands(LHS, RHS, Loc, /*isCompAssign*/false);
QualType vType = CheckVectorOperands(LHS, RHS, Loc, /*isCompAssign*/false,
/*AllowBothBool*/true,
/*AllowBoolConversions*/getLangOpts().ZVector);
if (vType.isNull())
return vType;
@ -8803,7 +8864,8 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
// If AltiVec, the comparison results in a numeric type, i.e.
// bool for C++, int for C
if (vType->getAs<VectorType>()->getVectorKind() == VectorType::AltiVecVector)
if (getLangOpts().AltiVec &&
vType->getAs<VectorType>()->getVectorKind() == VectorType::AltiVecVector)
return Context.getLogicalOperationType();
// For non-floating point types, check for self-comparisons of the form
@ -8837,7 +8899,9 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc) {
// Ensure that either both operands are of the same vector type, or
// one operand is of a vector type and the other is of its element type.
QualType vType = CheckVectorOperands(LHS, RHS, Loc, false);
QualType vType = CheckVectorOperands(LHS, RHS, Loc, false,
/*AllowBothBool*/true,
/*AllowBoolConversions*/false);
if (vType.isNull())
return InvalidOperands(Loc, LHS, RHS);
if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 &&
@ -8855,8 +8919,9 @@ inline QualType Sema::CheckBitwiseOperands(
RHS.get()->getType()->isVectorType()) {
if (LHS.get()->getType()->hasIntegerRepresentation() &&
RHS.get()->getType()->hasIntegerRepresentation())
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign);
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign,
/*AllowBothBool*/true,
/*AllowBoolConversions*/getLangOpts().ZVector);
return InvalidOperands(Loc, LHS, RHS);
}
@ -9470,6 +9535,10 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
IsInc, IsPrefix);
} else if (S.getLangOpts().AltiVec && ResType->isVectorType()) {
// OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 )
} else if (S.getLangOpts().ZVector && ResType->isVectorType() &&
(ResType->getAs<VectorType>()->getVectorKind() !=
VectorType::AltiVecBool)) {
// The z vector extensions allow ++ and -- for non-bool vectors.
} else if(S.getLangOpts().OpenCL && ResType->isVectorType() &&
ResType->getAs<VectorType>()->getElementType()->isIntegerType()) {
// OpenCL V1.2 6.3 says dec/inc ops operate on integer vector types.
@ -10550,8 +10619,13 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
resultType = Input.get()->getType();
if (resultType->isDependentType())
break;
if (resultType->isArithmeticType() || // C99 6.5.3.3p1
resultType->isVectorType())
if (resultType->isArithmeticType()) // C99 6.5.3.3p1
break;
else if (resultType->isVectorType() &&
// The z vector extensions don't allow + or - with bool vectors.
(!Context.getLangOpts().ZVector ||
resultType->getAs<VectorType>()->getVectorKind() !=
VectorType::AltiVecBool))
break;
else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6
Opc == UO_Plus &&

View File

@ -4946,7 +4946,9 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// Extension: conditional operator involving vector types.
if (LTy->isVectorType() || RTy->isVectorType())
return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false);
return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false,
/*AllowBothBool*/true,
/*AllowBoolConversions*/false);
// -- The second and third operands have arithmetic or enumeration type;
// the usual arithmetic conversions are performed to bring them to a

View File

@ -4292,7 +4292,7 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
// Don't try to correct the identifier "vector" when in AltiVec mode.
// TODO: Figure out why typo correction misbehaves in this case, fix it, and
// remove this workaround.
if (getLangOpts().AltiVec && Typo->isStr("vector"))
if ((getLangOpts().AltiVec || getLangOpts().ZVector) && Typo->isStr("vector"))
return nullptr;
// Provide a stop gap for files that are just seriously broken. Trying

2798
clang/test/CodeGen/zvector.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1748,3 +1748,12 @@
// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_HTM
//
// CHECK_SYSTEMZ_HTM: #define __HTM__ 1
//
// RUN: %clang -fzvector -E -dM %s -o - 2>&1 \
// RUN: -target s390x-unknown-linux \
// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_ZVECTOR
// RUN: %clang -mzvector -E -dM %s -o - 2>&1 \
// RUN: -target s390x-unknown-linux \
// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_ZVECTOR
//
// CHECK_SYSTEMZ_ZVECTOR: #define __VEC__ 10301

1009
clang/test/Sema/zvector.c Normal file

File diff suppressed because it is too large Load Diff