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", "")
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", "")
"cannot use '%0' with '__vector'">;
def err_invalid_vector_bool_decl_spec : Error<
"cannot use '%0' with '__vector bool'">;
+def err_invalid_vector_double_decl_spec : Error <
+ "use of 'double' with '__vector' requires VSX support to be enabled (available on the POWER7 or later)">;
+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<Deprecated>;
def err_friend_invalid_in_context : Error<
}
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
- return Feature == "powerpc";
+ return (Feature == "powerpc" ||
+ (Feature == "vsx" && HasVSX) ||
+ (Feature == "power8-vector" && HasP8Vector));
}
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 */
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 */
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 */
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 */
#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"
}
TypeSpecType = T;
TypeSpecOwned = false;
- if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
- PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
- DiagID = diag::err_invalid_vector_decl_spec;
- return true;
- }
return false;
}
if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
(TypeSpecWidth != TSW_unspecified))
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.
+ if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong)
+ Diag(D, TSWLoc, diag::err_invalid_vector_long_double_decl_spec);
+ else if (!PP.getTargetInfo().hasFeature("vsx"))
+ Diag(D, TSTLoc, diag::err_invalid_vector_double_decl_spec);
} else if (TypeSpecWidth == TSW_long) {
Diag(D, TSWLoc, diag::warn_vector_long_decl_spec_combination)
<< getSpecifierName((TST)TypeSpecType, Policy);
--- /dev/null
+// 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
+}
vector long int v_li; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
vector signed long int v_sli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
vector unsigned long int v_uli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
-__vector long double vv_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
-vector long double v_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+__vector long double vv_ld; // expected-error {{cannot use 'long double' with '__vector'}}
+vector long double v_ld; // expected-error {{cannot use 'long double' with '__vector'}}
vector bool v_b; // expected-warning {{type specifier missing, defaults to 'int'}}
// These should have errors.
-__vector double vv_d1; // expected-error {{cannot use 'double' with '__vector'}}
-vector double v_d2; // expected-error {{cannot use 'double' with '__vector'}}
-__vector long double vv_ld3; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
-vector long double v_ld4; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+__vector double vv_d1; // expected-error {{use of 'double' with '__vector' requires VSX support to be enabled (available on the POWER7 or later)}}
+vector double v_d2; // expected-error {{use of 'double' with '__vector' requires VSX support to be enabled (available on the POWER7 or later)}}
+__vector long double vv_ld3; // expected-error {{cannot use 'long double' with '__vector'}}
+vector long double v_ld4; // expected-error {{cannot use 'long double' with '__vector'}}
vector bool float v_bf; // expected-error {{cannot use 'float' with '__vector bool'}}
vector bool double v_bd; // expected-error {{cannot use 'double' with '__vector bool'}}
vector bool pixel v_bp; // expected-error {{cannot use '__pixel' with '__vector bool'}}
vector long int v_li; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
vector signed long int v_sli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
vector unsigned long int v_uli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
-__vector long double vv_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
-vector long double v_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+__vector long double vv_ld; // expected-error {{cannot use 'long double' with '__vector'}}
+vector long double v_ld; // expected-error {{cannot use 'long double' with '__vector'}}
// These should have errors.
-__vector double vv_d1; // expected-error {{cannot use 'double' with '__vector'}}
-vector double v_d2; // expected-error {{cannot use 'double' with '__vector'}}
-__vector long double vv_ld3; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
-vector long double v_ld4; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+__vector double vv_d1; // expected-error {{use of 'double' with '__vector' requires VSX support to be enabled (available on the POWER7 or later)}}
+vector double v_d2; // expected-error {{use of 'double' with '__vector' requires VSX support to be enabled (available on the POWER7 or later)}}
+__vector long double vv_ld3; // expected-error {{cannot use 'long double' with '__vector'}}
+vector long double v_ld4; // expected-error {{cannot use 'long double' with '__vector'}}
vector bool v_b; // expected-error {{C++ requires a type specifier for all declarations}}
vector bool float v_bf; // expected-error {{cannot use 'float' with '__vector bool'}}
vector bool double v_bd; // expected-error {{cannot use 'double' with '__vector bool'}}
--- /dev/null
+// 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-error {{cannot use 'long double' with '__vector'}}
+vector long double v_ld4; // expected-error {{cannot use 'long double' with '__vector'}}