This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, rs6000] Add additional support for vec_subc, vec_sube, vec_subec builtins.
- From: Carl Love <cel at us dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org, David Edelsohn <dje dot gcc at gmail dot com>, Segher Boessenkool <segher at kernel dot crashing dot org>
- Cc: Bill Schmidt <wschmidt at linux dot vnet dot ibm dot com>, cel at us dot ibm dot com
- Date: Fri, 30 Jun 2017 13:32:01 -0700
- Subject: [PATCH, rs6000] Add additional support for vec_subc, vec_sube, vec_subec builtins.
- Authentication-results: sourceware.org; auth=none
GCC Maintainers:
The following patch adds support for additional the vec_subc, vec_sube,
vec_subec builtins. It also adds a few missing tests for currently
supported builtins. The patch has been tested on
powerpc64le-unknown-linux-gnu (Power 8 LE) and
powerpc64-unknown-linux-gnu(Power 8 BE).
Please let me know if the following patch is acceptable. Thanks.
Carl Love
---------------------------------------------------------
gcc/ChangeLog:
2017-06-29 Carl Love <cel@us.ibm.com>
* config/rs6000/rs6000-c.c: Add support for built-in functions.
vector signed int vec_subc (vector signed int, vector signed int);
vector signed __int128 vec_subc (vector signed __int128, vector signed __int128);
vector unsigned __int128 vec_subc (vector unsigned __int128, vector unsigned __int128);
vector signed int vec_sube (vector signed int, vector signed int, vector signed int);
vector unsigned int vec_sube (vector unsigned int, vector unsigned int, vector unsigned int);
vector signed __int128 vec_sube (vector signed __int128, vector signed __int128, vector signed__int128);
vector unsigned __int128 vec_sube (vector unsigned __int128, vector unsigned __int128, vector unsigned __int128);
vector signed int vec_subec (vector signed int, vector signed int, vector signed int);
vector unsigned int vec_subec (vector unsigned int, vector unsigned int, vector unsigned int);
vector signed __int128 vec_subec (vector signed __int128, vector signed __int128, vector signed__int128);
vector unsigned __int128 vec_subec (vector unsigned __int128, vector unsigned __int128, vector unsigned __int128);
* config/rs6000/rs6000.c (ALTIVEC_BUILTIN_VEC_SUBE, ALTIVEC_BUILTIN_VEC_SUBEC): Add
def_builtins.
* config/rs6000/rs6000-builtin.def (SUBE, SUBEC): Add
BU_ALTIVEC_OVERLOAD_X definitions.
* config/rs6000/altivec.h (vec_sube, vec_subec): Add builtin defines.
* doc/extend.texi: Update the built-in documentation file for the new
built-in functions.
gcc/testsuite/ChangeLog:
2017-06-29 Carl Love <cel@us.ibm.com>
* gcc.target/powerpc/p8vector-builtin-8.c (foo): Add test cases for
the new vec_subc, vec_sube, vec_subec built-ins. Add the missing test
cases for vec_addc, adde and addec builtins.
---
gcc/config/rs6000/altivec.h | 2 +
gcc/config/rs6000/rs6000-builtin.def | 2 +
gcc/config/rs6000/rs6000-c.c | 106 +++++++++++++++++----
gcc/config/rs6000/rs6000.c | 4 +
gcc/doc/extend.texi | 27 ++++++
.../gcc.target/powerpc/p8vector-builtin-8.c | 29 +++++-
6 files changed, 148 insertions(+), 22 deletions(-)
diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index 417e143..45bf615 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -191,6 +191,8 @@
#define vec_unsignedo __builtin_vec_vunsignedo
#define vec_vsubfp __builtin_vec_vsubfp
#define vec_subc __builtin_vec_subc
+#define vec_sube __builtin_vec_sube
+#define vec_subec __builtin_vec_subec
#define vec_vsubsws __builtin_vec_vsubsws
#define vec_vsubshs __builtin_vec_vsubshs
#define vec_vsubsbs __builtin_vec_vsubsbs
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 9bdc2b4..f1c8ae0 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -1465,6 +1465,8 @@ BU_ALTIVEC_OVERLOAD_X (STVLX, "stvlx")
BU_ALTIVEC_OVERLOAD_X (STVLXL, "stvlxl")
BU_ALTIVEC_OVERLOAD_X (STVRX, "stvrx")
BU_ALTIVEC_OVERLOAD_X (STVRXL, "stvrxl")
+BU_ALTIVEC_OVERLOAD_X (SUBE, "sube")
+BU_ALTIVEC_OVERLOAD_X (SUBEC, "subec")
BU_ALTIVEC_OVERLOAD_X (VCFSX, "vcfsx")
BU_ALTIVEC_OVERLOAD_X (VCFUX, "vcfux")
BU_ALTIVEC_OVERLOAD_X (VSPLTB, "vspltb")
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 0752ef9..46a99d5 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -2950,8 +2950,17 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 },
+
+ { ALTIVEC_BUILTIN_VEC_SUBC, ALTIVEC_BUILTIN_VSUBCUW,
+ RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SUBC, ALTIVEC_BUILTIN_VSUBCUW,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SUBC, P8V_BUILTIN_VSUBCUQ,
+ RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI,
+ RS6000_BTI_unsigned_V1TI, 0 },
+ { ALTIVEC_BUILTIN_VEC_SUBC, P8V_BUILTIN_VSUBCUQ,
+ RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0 },
+
{ ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUBS,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUBS,
@@ -5855,13 +5864,14 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
/* else, fall through and process the Power9 alternative below */
}
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDE)
+ if ((fcode == ALTIVEC_BUILTIN_VEC_ADDE)
+ || (fcode == ALTIVEC_BUILTIN_VEC_SUBE))
{
/* vec_adde needs to be special cased because there is no instruction
for the {un}signed int version. */
if (nargs != 3)
{
- error ("vec_adde only accepts 3 arguments");
+ error ("vec_adde and vec_sube only accepts 3 arguments");
return error_mark_node;
}
@@ -5884,14 +5894,24 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
{
/* For {un}signed ints,
vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb),
+ vec_and (carryv, 0x1)).
+ vec_sube (va, vb, carryv) == vec_sub (vec_sub (va, vb),
vec_and (carryv, 0x1)). */
case SImode:
{
+ tree add_sub_builtin;
+
vec<tree, va_gc> *params = make_tree_vector ();
vec_safe_push (params, arg0);
vec_safe_push (params, arg1);
- tree add_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD];
- tree call = altivec_resolve_overloaded_builtin (loc, add_builtin,
+
+ if (fcode == ALTIVEC_BUILTIN_VEC_ADDE)
+ add_sub_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD];
+ else
+ add_sub_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_SUB];
+
+ tree call = altivec_resolve_overloaded_builtin (loc,
+ add_sub_builtin,
params);
tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
tree ones_vector = build_vector_from_val (arg0_type, const1);
@@ -5900,16 +5920,28 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
params = make_tree_vector ();
vec_safe_push (params, call);
vec_safe_push (params, and_expr);
- return altivec_resolve_overloaded_builtin (loc, add_builtin,
+ return altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
params);
}
/* For {un}signed __int128s use the vaddeuqm instruction
directly. */
case TImode:
{
- tree adde_bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDEUQM];
- return altivec_resolve_overloaded_builtin (loc, adde_bii,
- arglist);
+ if (fcode == ALTIVEC_BUILTIN_VEC_ADDE)
+ {
+ tree adde_bii
+ = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDEUQM];
+ return altivec_resolve_overloaded_builtin (loc, adde_bii,
+ arglist);
+ }
+
+ else
+ {
+ tree sube_bii
+ = rs6000_builtin_decls[P8V_BUILTIN_VEC_VSUBEUQM];
+ return altivec_resolve_overloaded_builtin (loc, sube_bii,
+ arglist);
+ }
}
/* Types other than {un}signed int and {un}signed __int128
@@ -5919,13 +5951,14 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
}
}
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
+ if ((fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
+ || (fcode == ALTIVEC_BUILTIN_VEC_SUBEC))
{
- /* vec_addec needs to be special cased because there is no instruction
- for the {un}signed int version. */
+ /* vec_addec and vec_subec needs to be special cased because there is
+ no instruction for the {un}signed int version. */
if (nargs != 3)
{
- error ("vec_addec only accepts 3 arguments");
+ error ("vec_addec and vec_subec only accepts 3 arguments");
return error_mark_node;
}
@@ -5956,19 +5989,37 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
/* Use save_expr to ensure that operands used more than once
that may have side effects (like calls) are only evaluated
once. */
+ tree addc_subc_builtin;
+ tree add_sub_builtin;
+
arg0 = save_expr (arg0);
arg1 = save_expr (arg1);
vec<tree, va_gc> *params = make_tree_vector ();
vec_safe_push (params, arg0);
vec_safe_push (params, arg1);
- tree addc_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADDC];
- tree call1 = altivec_resolve_overloaded_builtin (loc, addc_builtin,
+
+ if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
+ addc_subc_builtin
+ = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADDC];
+ else
+ addc_subc_builtin
+ = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_SUBC];
+
+ tree call1 = altivec_resolve_overloaded_builtin (loc,
+ addc_subc_builtin,
params);
params = make_tree_vector ();
vec_safe_push (params, arg0);
vec_safe_push (params, arg1);
- tree add_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD];
- tree call2 = altivec_resolve_overloaded_builtin (loc, add_builtin,
+
+
+ if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
+ add_sub_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD];
+ else
+ add_sub_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_SUB];
+
+ tree call2 = altivec_resolve_overloaded_builtin (loc,
+ add_sub_builtin,
params);
tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
tree ones_vector = build_vector_from_val (arg0_type, const1);
@@ -5977,7 +6028,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
params = make_tree_vector ();
vec_safe_push (params, call2);
vec_safe_push (params, and_expr);
- call2 = altivec_resolve_overloaded_builtin (loc, addc_builtin,
+ call2 = altivec_resolve_overloaded_builtin (loc, addc_subc_builtin,
params);
params = make_tree_vector ();
vec_safe_push (params, call1);
@@ -5986,12 +6037,25 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
return altivec_resolve_overloaded_builtin (loc, or_builtin,
params);
}
- /* For {un}signed __int128s use the vaddecuq instruction. */
+ /* For {un}signed __int128s use the vaddecuq/vsubbecuq
+ instructions. */
case TImode:
{
- tree VADDECUQ_bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDECUQ];
- return altivec_resolve_overloaded_builtin (loc, VADDECUQ_bii,
- arglist);
+ if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
+ {
+ tree VADDECUQ_bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDECUQ];
+ return altivec_resolve_overloaded_builtin (loc,
+ VADDECUQ_bii,
+ arglist);
+ }
+
+ else
+ {
+ tree VSUBECUQ_bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VSUBECUQ];
+ return altivec_resolve_overloaded_builtin (loc,
+ VSUBECUQ_bii,
+ arglist);
+ }
}
/* Types other than {un}signed int and {un}signed __int128
are errors. */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 181794d..60d2f9f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -17581,6 +17581,10 @@ altivec_init_builtins (void)
ALTIVEC_BUILTIN_VEC_CMPNE);
def_builtin ("__builtin_vec_mul", opaque_ftype_opaque_opaque,
ALTIVEC_BUILTIN_VEC_MUL);
+ def_builtin ("__builtin_vec_sube", opaque_ftype_opaque_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_SUBE);
+ def_builtin ("__builtin_vec_subec", opaque_ftype_opaque_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_SUBEC);
/* Cell builtins. */
def_builtin ("__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f87c1f3..efe1239 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -17103,7 +17103,34 @@ vector unsigned char vec_vsububm (vector unsigned char,
vector unsigned char vec_vsububm (vector unsigned char,
vector unsigned char);
+vector signed int vec_subc (vector signed int, vector signed int);
vector unsigned int vec_subc (vector unsigned int, vector unsigned int);
+vector signed __int128 vec_subc (vector signed __int128,
+ vector signed __int128);
+vector unsigned __int128 vec_subc (vector unsigned __int128,
+ vector unsigned __int128);
+
+vector signed int vec_sube (vector signed int, vector signed int,
+ vector signed int);
+vector unsigned int vec_sube (vector unsigned int, vector unsigned int,
+ vector unsigned int);
+vector signed __int128 vec_sube (vector signed __int128,
+ vector signed __int128,
+ vector signed__int128);
+vector unsigned __int128 vec_sube (vector unsigned __int128,
+ vector unsigned __int128,
+ vector unsigned __int128);
+
+vector signed int vec_subec (vector signed int, vector signed int,
+ vector signed int);
+vector unsigned int vec_subec (vector unsigned int, vector unsigned int,
+ vector unsigned int);
+vector signed __int128 vec_subec (vector signed __int128,
+ vector signed __int128,
+ vector signed__int128);
+vector unsigned __int128 vec_subec (vector unsigned __int128,
+ vector unsigned __int128,
+ vector unsigned __int128);
vector unsigned char vec_subs (vector bool char, vector unsigned char);
vector unsigned char vec_subs (vector unsigned char, vector bool char);
diff --git a/gcc/testsuite/gcc.target/powerpc/p8vector-builtin-8.c b/gcc/testsuite/gcc.target/powerpc/p8vector-builtin-8.c
index 3334774..4b0370b 100644
--- a/gcc/testsuite/gcc.target/powerpc/p8vector-builtin-8.c
+++ b/gcc/testsuite/gcc.target/powerpc/p8vector-builtin-8.c
@@ -11,7 +11,8 @@ vector unsigned char vuca, vucb, vucc;
vector bool char vbca, vbcb;
vector unsigned short vusa, vusb;
vector bool short vbsa, vbsb;
-vector unsigned int vuia, vuib;
+vector signed int vsia, vsib, vsic;
+vector unsigned int vuia, vuib, vuic;
vector bool int vbia, vbib;
vector signed long long vsla, vslb;
vector unsigned long long vula, vulb, vulc;
@@ -24,6 +25,7 @@ void foo (vector unsigned char *vucr,
vector bool char *vbcr,
vector unsigned short *vusr,
vector bool short *vbsr,
+ vector signed int *vsir,
vector unsigned int *vuir,
vector bool int *vbir,
vector unsigned long long *vulr,
@@ -32,10 +34,16 @@ void foo (vector unsigned char *vucr,
vector unsigned __int128 *vuxr,
vector double *vdr)
{
+ *vsir++ = vec_addc (vsia, vsib);
+ *vuir++ = vec_addc (vuia, vuib);
*vsxr++ = vec_addc (vsxa, vsxb);
*vuxr++ = vec_addc (vuxa, vuxb);
+ *vsir++ = vec_adde (vsia, vsib, vsic);
+ *vuir++ = vec_adde (vuia, vuib, vuic);
*vsxr++ = vec_adde (vsxa, vsxb, vsxc);
*vuxr++ = vec_adde (vuxa, vuxb, vuxc);
+ *vsir++ = vec_addec (vsia, vsib, vsic);
+ *vuir++ = vec_addec (vuia, vuib, vuic);
*vsxr++ = vec_addec (vsxa, vsxb, vsxc);
*vuxr++ = vec_addec (vuxa, vuxb, vuxc);
*vucr++ = vec_bperm (vuca, vucb);
@@ -60,11 +68,30 @@ void foo (vector unsigned char *vucr,
*vuxr++ = vec_pmsum_be (vula, vulb);
*vuir++ = vec_shasigma_be (vuia, 0, 1);
*vulr++ = vec_shasigma_be (vula, 0, 1);
+ *vsir++ = vec_subc (vsia, vsib);
+ *vuir++ = vec_subc (vuia, vuib);
+ *vsxr++ = vec_subc (vsxa, vsxb);
+ *vuxr++ = vec_subc (vuxa, vuxb);
+ *vsir++ = vec_sube (vsia, vsib, vsic);
+ *vuir++ = vec_sube (vuia, vuib, vuic);
+ *vsxr++ = vec_sube (vsxa, vsxb, vsxc);
+ *vuxr++ = vec_sube (vuxa, vuxb, vuxc);
+ *vsir++ = vec_subec (vsia, vsib, vsic);
+ *vuir++ = vec_subec (vuia, vuib, vuic);
+ *vsxr++ = vec_subec (vsxa, vsxb, vsxc);
+ *vuxr++ = vec_subec (vuxa, vuxb, vuxc);
}
/* { dg-final { scan-assembler-times "vaddcuq" 2 } } */
/* { dg-final { scan-assembler-times "vaddeuqm" 2 } } */
/* { dg-final { scan-assembler-times "vaddecuq" 2 } } */
+/* { dg-final { scan-assembler-times "vaddcuw" 6 } } */
+/* { dg-final { scan-assembler-times "vadduwm" 4 } } */
+/* { dg-final { scan-assembler-times "vsubcuq" 2 } } */
+/* { dg-final { scan-assembler-times "vsubeuqm" 2 } } */
+/* { dg-final { scan-assembler-times "vsubecuq" 2 } } */
+/* { dg-final { scan-assembler-times "vsubcuw" 4 } } */
+/* { dg-final { scan-assembler-times "vsubuwm" 4 } } */
/* { dg-final { scan-assembler-times "vbpermq" 2 } } */
/* { dg-final { scan-assembler-times "xxleqv" 4 } } */
/* { dg-final { scan-assembler-times "vgbbd" 1 } } */
--
1.9.1