]> granicus.if.org Git - clang/commitdiff
[PowerPC] Initial VSX intrinsic support, with min/max for vector double
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Fri, 31 Oct 2014 19:19:24 +0000 (19:19 +0000)
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>
Fri, 31 Oct 2014 19:19:24 +0000 (19:19 +0000)
Now that we have initial support for VSX, we can begin adding
intrinsics for programmer access to VSX instructions.  This patch
performs the necessary enablement in the front end, and tests it by
implementing intrinsics for minimum and maximum using the vector
double data type.

The main change in the front end is to no longer disallow "vector" and
"double" in the same declaration (lib/Sema/DeclSpec.cpp), but "vector"
and "long double" must still be disallowed.  The new intrinsics are
accessed via vec_max and vec_min with changes in
lib/Headers/altivec.h.  Note that for v4f32, we already access
corresponding VMX builtins, but with VSX enabled we should use the
forms that allow all 64 vector registers.

The new built-ins are defined in include/clang/Basic/BuiltinsPPC.def.

I've added a new test in test/CodeGen/builtins-ppc-vsx.c that is
similar to, but much smaller than, builtins-ppc-altivec.c.  This
allows us to test VSX IR generation without duplicating CHECK lines
for the existing bazillion Altivec tests.

Since vector double is now legal when VSX is available, I've modified
the error message, and changed where we test for it and for vector
long double, since the target machine isn't visible in the old place.
This serendipitously removed a not-pertinent warning about 'long'
being deprecated when used with 'vector', when "vector long double" is
encountered and we just want to issue an error.  The existing tests
test/Parser/altivec.c and test/Parser/cxx-altivec.cpp have been
updated accordingly, and I've added test/Parser/vsx.c to verify that
"vector double" is now legitimate with VSX enabled.

There is a companion patch for LLVM.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220989 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/BuiltinsPPC.def
include/clang/Basic/DiagnosticParseKinds.td
lib/Basic/Targets.cpp
lib/Headers/altivec.h
lib/Sema/DeclSpec.cpp
test/CodeGen/builtins-ppc-vsx.c [new file with mode: 0644]
test/Parser/altivec.c
test/Parser/cxx-altivec.cpp
test/Parser/vsx.c [new file with mode: 0644]

index 8a751e4ce8467df1585fd25428f129f01f175204..2d8427634950a80dcdb139e535aee7ae43755ca6 100644 (file)
@@ -132,6 +132,9 @@ BUILTIN(__builtin_altivec_vmaxuh, "V8UsV8UsV8Us", "")
 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_vminuh, "V8UsV8UsV8Us", "")
 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 7e6964a80ac6ec55d528439272135cf329f2e1ff..4510fdf157ec45304ca599fd5c55f4c640b6e359 100644 (file)
@@ -341,6 +341,10 @@ def err_invalid_vector_decl_spec : Error<
   "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<
index 4604b1cfa0fce59011e47838ecf069df98fed71c..587b13fe4126aff48b43ba86a91132aed00d55b7 100644 (file)
@@ -1136,7 +1136,9 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
 }
 
 bool PPCTargetInfo::hasFeature(StringRef Feature) const {
-  return Feature == "powerpc";
+  return (Feature == "powerpc" ||
+         (Feature == "vsx" && HasVSX) ||
+         (Feature == "power8-vector" && HasP8Vector));
 }
 
   
index 373eded482fcb0ec8b4b16cabbb04a1850b9e802..1ffefa8585136e467f3ce588f2d690b528479c5e 100644 (file)
@@ -2667,8 +2667,20 @@ vec_max(vector unsigned int __a, vector bool int __b)
 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 @@ vec_vmaxuw(vector unsigned int __a, vector bool int __b)
 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 @@ vec_min(vector unsigned int __a, vector bool int __b)
 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 @@ vec_vminuw(vector unsigned int __a, vector bool int __b)
 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 bed94127b28997336fac7f927eb42359b6aea270..6e77d2769fac406101cbf422b8c4a871e6f03c19 100644 (file)
@@ -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"
@@ -689,11 +690,6 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
   }
   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;
 }
 
@@ -987,6 +983,13 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
       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);
diff --git a/test/CodeGen/builtins-ppc-vsx.c b/test/CodeGen/builtins-ppc-vsx.c
new file mode 100644 (file)
index 0000000..bae9614
--- /dev/null
@@ -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 a9b41b9b7acaa130787885c4db49d74c30a31622..7adca6143bde4b1a7ee9490332316b6763bf6ae8 100644 (file)
@@ -61,15 +61,15 @@ vector unsigned long v_ul;          // expected-warning {{Use of 'long' with '__
 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'}}
index 23a6acd86beb2b75327bbc6453d83e5dabd9c99d..f2ba28b641a67389baeacd4931fd8cdaba02bc66 100644 (file)
@@ -61,14 +61,14 @@ vector unsigned long v_ul;          // expected-warning {{Use of 'long' with '__
 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'}}
diff --git a/test/Parser/vsx.c b/test/Parser/vsx.c
new file mode 100644 (file)
index 0000000..ead0981
--- /dev/null
@@ -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-error {{cannot use 'long double' with '__vector'}}
+vector long double  v_ld4;           // expected-error {{cannot use 'long double' with '__vector'}}