Index: include/clang/Basic/BuiltinsPPC.def =================================================================== --- include/clang/Basic/BuiltinsPPC.def +++ include/clang/Basic/BuiltinsPPC.def @@ -132,6 +132,9 @@ BUILTIN(__builtin_altivec_vmaxsw, "V4SiV4SiV4Si", "") BUILTIN(__builtin_altivec_vmaxuw, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_altivec_vmaxfp, "V4fV4fV4f", "") +BUILTIN(__builtin_vsx_xvmaxdp, "V2dV2dV2d", "") +BUILTIN(__builtin_vsx_xvmaxsp, "V4fV4fV4f", "") +BUILTIN(__builtin_vsx_xsmaxdp, "ddd", "") BUILTIN(__builtin_altivec_mfvscr, "V8Us", "") @@ -142,6 +145,9 @@ BUILTIN(__builtin_altivec_vminsw, "V4SiV4SiV4Si", "") BUILTIN(__builtin_altivec_vminuw, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "") +BUILTIN(__builtin_vsx_xvmindp, "V2dV2dV2d", "") +BUILTIN(__builtin_vsx_xvminsp, "V4fV4fV4f", "") +BUILTIN(__builtin_vsx_xsmindp, "ddd", "") BUILTIN(__builtin_altivec_mtvscr, "vV4i", "") Index: include/clang/Basic/DiagnosticParseKinds.td =================================================================== --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -341,6 +341,8 @@ "cannot use '%0' with '__vector'">; def err_invalid_vector_bool_decl_spec : Error< "cannot use '%0' with '__vector bool'">; +def err_invalid_vector_long_double_decl_spec : Error< + "cannot use 'long double' with '__vector'">; def warn_vector_long_decl_spec_combination : Warning< "Use of 'long' with '__vector' is deprecated">, InGroup; def err_friend_invalid_in_context : Error< Index: include/clang/Sema/DeclSpec.h =================================================================== --- include/clang/Sema/DeclSpec.h +++ include/clang/Sema/DeclSpec.h @@ -28,6 +28,7 @@ #include "clang/Basic/Lambda.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Lex/Token.h" #include "clang/Sema/AttributeList.h" #include "clang/Sema/Ownership.h" @@ -627,6 +628,9 @@ bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy); bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID, const PrintingPolicy &Policy, + const TargetInfo& TI); + bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ParsedType Rep, const PrintingPolicy &Policy); bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -1136,7 +1136,9 @@ } bool PPCTargetInfo::hasFeature(StringRef Feature) const { - return Feature == "powerpc"; + return (Feature == "powerpc" || + (Feature == "vsx" && HasVSX) || + (Feature == "power8-vector" && HasP8Vector)); } Index: lib/Headers/altivec.h =================================================================== --- lib/Headers/altivec.h +++ lib/Headers/altivec.h @@ -2667,8 +2667,20 @@ static vector float __ATTRS_o_ai vec_max(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvmaxsp(__a, __b); +#else return __builtin_altivec_vmaxfp(__a, __b); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai +vec_max(vector double __a, vector double __b) +{ + return __builtin_vsx_xvmaxdp(__a, __b); } +#endif /* vec_vmaxsb */ @@ -2795,7 +2807,11 @@ static vector float __attribute__((__always_inline__)) vec_vmaxfp(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvmaxsp(__a, __b); +#else return __builtin_altivec_vmaxfp(__a, __b); +#endif } /* vec_mergeh */ @@ -3299,8 +3315,20 @@ static vector float __ATTRS_o_ai vec_min(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvminsp(__a, __b); +#else return __builtin_altivec_vminfp(__a, __b); +#endif +} + +#ifdef __VSX__ +static vector double __ATTRS_o_ai +vec_min(vector double __a, vector double __b) +{ + return __builtin_vsx_xvmindp(__a, __b); } +#endif /* vec_vminsb */ @@ -3427,7 +3455,11 @@ static vector float __attribute__((__always_inline__)) vec_vminfp(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvminsp(__a, __b); +#else return __builtin_altivec_vminfp(__a, __b); +#endif } /* vec_mladd */ Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -3051,7 +3051,7 @@ break; case tok::kw_double: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, - DiagID, Policy); + DiagID, Policy, getTargetInfo()); break; case tok::kw_wchar_t: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, Index: lib/Sema/DeclSpec.cpp =================================================================== --- lib/Sema/DeclSpec.cpp +++ lib/Sema/DeclSpec.cpp @@ -18,6 +18,7 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency! #include "clang/Sema/LocInfoType.h" @@ -697,6 +698,43 @@ return false; } +bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, + const char *&PrevSpec, + unsigned &DiagID, + const PrintingPolicy &Policy, + const TargetInfo& TI) { + assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && + "rep required for these type-spec kinds!"); + if (TypeSpecType != TST_unspecified) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); + DiagID = diag::err_invalid_decl_spec_combination; + return true; + } + TSTLoc = Loc; + TSTNameLoc = Loc; + if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { + TypeAltiVecBool = true; + return false; + } + TypeSpecType = T; + TypeSpecOwned = false; + bool HasVSX = TI.hasFeature("vsx"); + if (TypeAltiVecVector && !TypeAltiVecBool && !HasVSX && + (TypeSpecType == TST_double)) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); + DiagID = diag::err_invalid_vector_decl_spec; + return true; + } + if (TypeAltiVecVector && !TypeAltiVecBool && HasVSX && + (TypeSpecType == TST_double) && + (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong)) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); + DiagID = diag::err_invalid_vector_long_double_decl_spec; + return true; + } + return false; +} + bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy) { Index: test/CodeGen/builtins-ppc-vsx.c =================================================================== --- test/CodeGen/builtins-ppc-vsx.c +++ test/CodeGen/builtins-ppc-vsx.c @@ -0,0 +1,40 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -faltivec -target-feature +vsx -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +vector float vf = { -1.5, 2.5, -3.5, 4.5 }; +vector double vd = { 3.5, -7.5 }; +double d = 23.4; + +vector float res_vf; +vector double res_vd; +double res_d; + +void test1() { +// CHECK-LABEL: define void @test1 + + /* vec_max */ + res_vf = vec_max(vf, vf); +// CHECK: @llvm.ppc.vsx.xvmaxsp + + res_vd = vec_max(vd, vd); +// CHECK: @llvm.ppc.vsx.xvmaxdp + + res_vf = vec_vmaxfp(vf, vf); +// CHECK: @llvm.ppc.vsx.xvmaxsp + + /* vec_min */ + res_vf = vec_min(vf, vf); +// CHECK: @llvm.ppc.vsx.xvminsp + + res_vd = vec_min(vd, vd); +// CHECK: @llvm.ppc.vsx.xvmindp + + res_vf = vec_vminfp(vf, vf); +// CHECK: @llvm.ppc.vsx.xvminsp + + res_d = __builtin_vsx_xsmaxdp(d, d); +// CHECK: @llvm.ppc.vsx.xsmaxdp + + res_d = __builtin_vsx_xsmindp(d, d); +// CHECK: @llvm.ppc.vsx.xsmindp +} Index: test/Parser/vsx.c =================================================================== --- test/Parser/vsx.c +++ test/Parser/vsx.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -faltivec -target-feature +vsx -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -faltivec -target-feature +vsx -fsyntax-only -verify %s + +// Legitimate for VSX. +__vector double vv_d1; +vector double v_d2; + +// These should have errors. +__vector long double vv_ld3; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'long double' with '__vector'}} +vector long double v_ld4; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'long double' with '__vector'}}