Hi,
On 16/06/26 2:09 PM, Surya Kumari Jangala wrote:
>
>
> On 11/06/26 2:33 PM, jeevitha wrote:
>> Hi All,
>>
>> The following changes have been bootstrapped and regression tested on
>> powerpc64le-linux. Is this okay for trunk?
>>
>> Changes from V4:
>> * Modified the existing patterns for add, sub, and mulh.
>> * Added new test cases.
>> * Added the future ISA attribute.
>>
>> Changes from V3:
>> * Renamed ENB_FUTUREV and BSTZ_FUTUREV.
>> * Added subheading in extend.texi.
>>
>> Changes from V2:
>> * Added TARGET_VSX check to all new insn patterns.
>> * Added * prefix to vsx_mul pattern.
>> * Added new test cases vsx_simd-3.c and vsx_simd-4.c.
>> * Created new future-vsx stanza to map builtins.
>>
>> Changes from V1:
>> * Incorporated wording suggestions.
>> * Renamed mode iterators to VIMulH and VIArith for better clarity.
>> * Removed extra blank line in vsx_simd-*.c test case.
>> * Replaced unspec with proper smul_highpart and umul_highpart RTL
>> codes for multiply-high patterns.
>> * Added * prefix to internal patterns for vsx_add, vsx_sub, altivec_add,
>> altivec_sub, altivec_smul and altivec_umul.
>> * Updated extend.texi.
>>
>> This patch adds support for VSX vector arithmetic instructions that may
>> be added to future PowerPC processors. Note that the names of these
>> builtins may change in the future.
>>
>> New VSX patterns are added for vector add, subtract, multiply, and
>> multiply-high instructions guarded by TARGET_FUTURE. A new builtin
>> enablement stanza future-vsx is added for builtins requiring
>> both -mcpu=future and -mvsx.
>>
>> 2026-06-11 Jeevitha Palanisamy <[email protected]>
>>
>> gcc/
>> * config/rs6000/altivec.md (V16QI_V2DI): New mode iterator.
>> (add<mode>3): Split into two patterns to support future ISA
>> alternatives.
>> (sub<mode>3): Likewise.
>> * config/rs6000/vsx.md (VIArith): New mode iterator.
>> (vsx_mul<mode>3): New insn pattern.
>> (smul<mode>3_highpart): Split into mode-specific patterns.
>> (umul<mode>3_highpart): Likewise.
>> (smulv8hi3_highpart): New insn pattern.
>> (smulv4si3_highpart): Likewise.
>> (smulv2di3_highpart): Likewise.
>> (umulv8hi3_highpart): Likewise.
>> (umulv4si3_highpart): Likewise.
>> (umulv2di3_highpart): Likewise.
>> * config/rs6000/rs6000-builtins.def (__builtin_vsx_xvmulhuh): New
>> builtin.
>> (__builtin_vsx_xvmulhsh): Likewise.
>> * config/rs6000/rs6000-overload.def (__builtin_vec_mulh): Add
>> overloads for vector multiply-high signed/unsigned halfword.
>> * config/rs6000/rs6000-gen-builtins.cc (enum bif_stanza): Add entry for
>> BSTZ_FUTURE_VSX.
>> (stanza_map): Add future-vsx stanza mapping.
>> (enable_string): Add ENB_FUTURE_VSX.
>> (write_decls): Add ENB_FUTURE_VSX to the bif_enable enum in the
>> generated header file.
>> * config/rs6000/rs6000.md (define_attr "isa"): Add future to the list
>> of ISA values.
>> (define_attr "enabled"): Add check for future ISA.
>> * config/rs6000/rs6000-builtin.cc (rs6000_invalid_builtin): Handle
>> ENB_FUTURE_VSX and issue a diagnostic requiring -mcpu=future and -mvsx.
>> (rs6000_builtin_is_supported): Return TARGET_FUTURE && TARGET_VSX
>> for ENB_FUTURE_VSX built-ins.
>> * doc/extend.texi (PowerPC AltiVec/VSX Built-in Functions Available
>> on Future ISA): Document new functions.
>>
>> gcc/testsuite/
>> * gcc.target/powerpc/vsx_arith_builtin-1.c: New test.
>> * gcc.target/powerpc/vsx_arith_builtin-2.c: Likewise.
>> * gcc.target/powerpc/vsx_arith_builtin-3.c: Likewise.
>> * gcc.target/powerpc/vsx_arith_builtin-4.c: Likewise.
>> * gcc.target/powerpc/vsx_arith_vect_1.c: Likewise.
>> * gcc.target/powerpc/vsx_arith_vect_2.c: Likewise.
>>
>> diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
>> index 129f56245cd..dbe24c450e1 100644
>> --- a/gcc/config/rs6000/altivec.md
>> +++ b/gcc/config/rs6000/altivec.md
>> @@ -238,6 +238,8 @@
>> ;; Vector negate
>> (define_mode_iterator VNEG [V4SI V2DI])
>>
>> +(define_mode_iterator V16QI_V2DI [V16QI V2DI])
>> +
>> ;; Vector move instructions.
>> (define_insn "*altivec_mov<mode>"
>> [(set (match_operand:VM2 0 "nonimmediate_operand"
>> "=Z,v,v,?Y,?*r,?*r,v,v,?*r")
>> @@ -505,13 +507,24 @@
>>
>> ;; add
>> (define_insn "add<mode>3"
>> - [(set (match_operand:VI2 0 "register_operand" "=v")
>> - (plus:VI2 (match_operand:VI2 1 "register_operand" "v")
>> - (match_operand:VI2 2 "register_operand" "v")))]
>> + [(set (match_operand:V16QI_V2DI 0 "register_operand" "=v")
>> + (plus:V16QI_V2DI (match_operand:V16QI_V2DI 1 "register_operand" "v")
>> + (match_operand:V16QI_V2DI 2 "register_operand"
>> "v")))]
>> "<VI_unit>"
>> "vaddu<VI_char>m %0,%1,%2"
>> [(set_attr "type" "vecsimple")])
>>
>> +(define_insn "add<mode>3"
>> + [(set (match_operand:VIArith 0 "register_operand" "=wa,v")
>> + (plus:VIArith (match_operand:VIArith 1 "register_operand" "wa,v")
>> + (match_operand:VIArith 2 "register_operand" "wa,v")))]
>> + "<VI_unit>"
>
> <VI_unit> checks for ALTIVEC mode for V8HI & V4SI. But the xvaddu*m
> instructions should be
> generated only if VSX is true.
So looks like register allocator does not consider VSX registers when -mno-vsx
is true.
The above comment (and the other comments below) can be ignored.
This patch looks good to me. I cannot approve it though.
-Surya
>
>> + "@
>> + xvaddu<VI_char>m %x0,%x1,%x2
>> + vaddu<VI_char>m %0,%1,%2"
>> + [(set_attr "type" "vecsimple")
>> + (set_attr "isa" "future,*")])
>> +
>> (define_insn "*altivec_addv4sf3"
>> [(set (match_operand:V4SF 0 "register_operand" "=v")
>> (plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
>> @@ -549,13 +562,24 @@
>>
>> ;; sub
>> (define_insn "sub<mode>3"
>> - [(set (match_operand:VI2 0 "register_operand" "=v")
>> - (minus:VI2 (match_operand:VI2 1 "register_operand" "v")
>> - (match_operand:VI2 2 "register_operand" "v")))]
>> + [(set (match_operand:V16QI_V2DI 0 "register_operand" "=v")
>> + (minus:V16QI_V2DI (match_operand:V16QI_V2DI 1 "register_operand"
>> "v")
>> + (match_operand:V16QI_V2DI 2 "register_operand"
>> "v")))]
>> "<VI_unit>"
>> "vsubu<VI_char>m %0,%1,%2"
>> [(set_attr "type" "vecsimple")])
>>
>> +(define_insn "sub<mode>3"
>> + [(set (match_operand:VIArith 0 "register_operand" "=wa,v")
>> + (minus:VIArith (match_operand:VIArith 1 "register_operand" "wa,v")
>> + (match_operand:VIArith 2 "register_operand"
>> "wa,v")))]
>> + "<VI_unit>"
>
> Ditto.
>
>> + "@
>> + xvsubu<VI_char>m %x0,%x1,%x2
>> + vsubu<VI_char>m %0,%1,%2"
>> + [(set_attr "type" "vecsimple")
>> + (set_attr "isa" "future,*")])
>> +
>> (define_insn "*altivec_subv4sf3"
>> [(set (match_operand:V4SF 0 "register_operand" "=v")
>> (minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
>> diff --git a/gcc/config/rs6000/rs6000-builtin.cc
>> b/gcc/config/rs6000/rs6000-builtin.cc
>> index f4f3772d6cc..3d8b5acf45b 100644
>> --- a/gcc/config/rs6000/rs6000-builtin.cc
>> +++ b/gcc/config/rs6000/rs6000-builtin.cc
>> @@ -142,6 +142,10 @@ rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
>> case ENB_FUTURE:
>> error ("%qs requires the %qs option", name, "-mcpu=future");
>> break;
>> + case ENB_FUTURE_VSX:
>> + error ("%qs requires the %qs and %qs options", name, "-mcpu=future",
>> + "-mvsx");
>> + break;
>> default:
>> case ENB_ALWAYS:
>> gcc_unreachable ();
>> @@ -199,6 +203,8 @@ rs6000_builtin_is_supported (enum rs6000_gen_builtins
>> fncode)
>> return TARGET_MMA;
>> case ENB_FUTURE:
>> return TARGET_FUTURE;
>> + case ENB_FUTURE_VSX:
>> + return TARGET_FUTURE && TARGET_VSX;
>> default:
>> gcc_unreachable ();
>> }
>> diff --git a/gcc/config/rs6000/rs6000-builtins.def
>> b/gcc/config/rs6000/rs6000-builtins.def
>> index 0d1529b71d4..b5b6c98b69e 100644
>> --- a/gcc/config/rs6000/rs6000-builtins.def
>> +++ b/gcc/config/rs6000/rs6000-builtins.def
>> @@ -3970,3 +3970,10 @@
>>
>> const vuc __builtin_galois_field_mult_xts (vuc, vuc);
>> XXGFMUL128XTS xxgfmul128xts {}
>> +
>> +[future-vsx]
>> + const vus __builtin_vsx_xvmulhuh (vus, vus);
>> + XVMULHUH umulv8hi3_highpart {}
>> +
>> + const vss __builtin_vsx_xvmulhsh (vss, vss);
>> + XVMULHSH smulv8hi3_highpart {}
>> diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc
>> b/gcc/config/rs6000/rs6000-gen-builtins.cc
>> index 7436404cff5..dd60d20eaaf 100644
>> --- a/gcc/config/rs6000/rs6000-gen-builtins.cc
>> +++ b/gcc/config/rs6000/rs6000-gen-builtins.cc
>> @@ -233,6 +233,7 @@ enum bif_stanza
>> BSTZ_P10_64,
>> BSTZ_MMA,
>> BSTZ_FUTURE,
>> + BSTZ_FUTURE_VSX,
>> NUMBIFSTANZAS
>> };
>>
>> @@ -267,7 +268,8 @@ static stanza_entry stanza_map[NUMBIFSTANZAS] =
>> { "power10", BSTZ_P10 },
>> { "power10-64", BSTZ_P10_64 },
>> { "mma", BSTZ_MMA },
>> - { "future", BSTZ_FUTURE }
>> + { "future", BSTZ_FUTURE },
>> + { "future-vsx", BSTZ_FUTURE_VSX }
>> };
>>
>> static const char *enable_string[NUMBIFSTANZAS] =
>> @@ -293,7 +295,8 @@ static const char *enable_string[NUMBIFSTANZAS] =
>> "ENB_P10",
>> "ENB_P10_64",
>> "ENB_MMA",
>> - "ENB_FUTURE"
>> + "ENB_FUTURE",
>> + "ENB_FUTURE_VSX"
>> };
>>
>> /* Function modifiers provide special handling for const, pure, and fpmath
>> @@ -2253,7 +2256,8 @@ write_decls (void)
>> fprintf (header_file, " ENB_P10,\n");
>> fprintf (header_file, " ENB_P10_64,\n");
>> fprintf (header_file, " ENB_MMA,\n");
>> - fprintf (header_file, " ENB_FUTURE\n");
>> + fprintf (header_file, " ENB_FUTURE,\n");
>> + fprintf (header_file, " ENB_FUTURE_VSX\n");
>> fprintf (header_file, "};\n\n");
>>
>> fprintf (header_file, "#define PPC_MAXRESTROPNDS 3\n");
>> diff --git a/gcc/config/rs6000/rs6000-overload.def
>> b/gcc/config/rs6000/rs6000-overload.def
>> index ef7b59ed112..09be9e7de71 100644
>> --- a/gcc/config/rs6000/rs6000-overload.def
>> +++ b/gcc/config/rs6000/rs6000-overload.def
>> @@ -2530,6 +2530,10 @@
>> VMULEUD
>>
>> [VEC_MULH, vec_mulh, __builtin_vec_mulh]
>> + vss __builtin_vec_mulh (vss, vss);
>> + XVMULHSH
>> + vus __builtin_vec_mulh (vus, vus);
>> + XVMULHUH
>> vsi __builtin_vec_mulh (vsi, vsi);
>> VMULHSW
>> vui __builtin_vec_mulh (vui, vui);
>> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
>> index 2ccbe178bb5..536ea2c9d76 100644
>> --- a/gcc/config/rs6000/rs6000.md
>> +++ b/gcc/config/rs6000/rs6000.md
>> @@ -369,7 +369,7 @@
>> (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
>>
>> ;; The ISA we implement.
>> -(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10"
>> +(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,future"
>> (const_string "any"))
>>
>> ;; Is this alternative enabled for the current CPU/ISA/etc.?
>> @@ -421,6 +421,9 @@
>> (and (eq_attr "isa" "p10")
>> (match_test "TARGET_POWER10"))
>> (const_int 1)
>> + (and (eq_attr "isa" "future")
>> + (match_test "TARGET_FUTURE"))
>> + (const_int 1)
>> ] (const_int 0)))
>>
>> ;; If this instruction is microcoded on the CELL processor
>> diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
>> index 1305eff8cdd..640d3679034 100644
>> --- a/gcc/config/rs6000/vsx.md
>> +++ b/gcc/config/rs6000/vsx.md
>> @@ -418,6 +418,9 @@
>> (define_int_attr vczlsbb_char [(UNSPEC_VCLZLSBB "l")
>> (UNSPEC_VCTZLSBB "t")])
>>
>> +;; Vector integer arithmetic modes
>> +(define_mode_iterator VIArith [V8HI V4SI])
>> +
>> ;; VSX moves
>>
>> ;; TImode memory to memory move optimization on LE with p8vector
>> @@ -1711,6 +1714,13 @@
>> "xvsub<sd>p %x0,%x1,%x2"
>> [(set_attr "type" "<VStype_simple>")])
>>
>> +(define_insn "vsx_mul<mode>3"
>> + [(set (match_operand:VIArith 0 "vsx_register_operand" "=wa")
>> + (mult:VIArith (match_operand:VIArith 1 "vsx_register_operand" "wa")
>> + (match_operand:VIArith 2 "vsx_register_operand"
>> "wa")))]
>> + "TARGET_FUTURE && TARGET_VSX"
>> + "xvmulu<wd>m %x0,%x1,%x2")
>> +
>> (define_insn "*vsx_mul<mode>3"
>> [(set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
>> (mult:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "wa")
>> @@ -6546,22 +6556,62 @@
>> [(set_attr "type" "vecdiv")
>> (set_attr "size" "<bits>")])
>>
>> -(define_insn "smul<mode>3_highpart"
>> - [(set (match_operand:VIlong 0 "altivec_register_operand" "=v")
>> - (smul_highpart:VIlong
>> - (match_operand:VIlong 1 "altivec_register_operand" "v")
>> - (match_operand:VIlong 2 "altivec_register_operand" "v")))]
>> +(define_insn "smulv8hi3_highpart"
>> + [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa")
>> + (smul_highpart:V8HI
>> + (match_operand:V8HI 1 "vsx_register_operand" "wa")
>> + (match_operand:V8HI 2 "vsx_register_operand" "wa")))]
>> + "TARGET_FUTURE && TARGET_VSX"
>> + "xvmulhsh %x0,%x1,%x2")
>> +
>> +(define_insn "smulv4si3_highpart"
>> + [(set (match_operand:V4SI 0 "register_operand" "=wa,v")
>> + (smul_highpart:V4SI
>> + (match_operand:V4SI 1 "register_operand" "wa,v")
>> + (match_operand:V4SI 2 "register_operand" "wa,v")))]
>> + "TARGET_POWER10"
>
> Here too, xvmulhsw should be emitted only if VSX is true.
>
>> + "@
>> + xvmulhsw %x0,%x1,%x2
>> + vmulhsw %0,%1,%2"
>> + [(set_attr "type" "veccomplex")
>> + (set_attr "isa" "future,p10")])
>> +
>> +(define_insn "smulv2di3_highpart"
>> + [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
>> + (smul_highpart:V2DI
>> + (match_operand:V2DI 1 "altivec_register_operand" "v")
>> + (match_operand:V2DI 2 "altivec_register_operand" "v")))]
>> "TARGET_POWER10"
>> - "vmulhs<wd> %0,%1,%2"
>> + "vmulhsd %0,%1,%2"
>> [(set_attr "type" "veccomplex")])
>>
>> -(define_insn "umul<mode>3_highpart"
>> - [(set (match_operand:VIlong 0 "altivec_register_operand" "=v")
>> - (umul_highpart:VIlong
>> - (match_operand:VIlong 1 "altivec_register_operand" "v")
>> - (match_operand:VIlong 2 "altivec_register_operand" "v")))]
>> +(define_insn "umulv8hi3_highpart"
>> + [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa")
>> + (umul_highpart:V8HI
>> + (match_operand:V8HI 1 "vsx_register_operand" "wa")
>> + (match_operand:V8HI 2 "vsx_register_operand" "wa")))]
>> + "TARGET_FUTURE && TARGET_VSX"
>> + "xvmulhuh %x0,%x1,%x2")
>> +
>> +(define_insn "umulv4si3_highpart"
>> + [(set (match_operand:V4SI 0 "register_operand" "=wa,v")
>> + (umul_highpart:V4SI
>> + (match_operand:V4SI 1 "register_operand" "wa,v")
>> + (match_operand:V4SI 2 "register_operand" "wa,v")))]
>> + "TARGET_POWER10"
>
> Ditto.
>
> -Surya
>
>> + "@
>> + xvmulhuw %x0,%x1,%x2
>> + vmulhuw %0,%1,%2"
>> + [(set_attr "type" "veccomplex")
>> + (set_attr "isa" "future,p10")])
>> +
>> +(define_insn "umulv2di3_highpart"
>> + [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
>> + (umul_highpart:V2DI
>> + (match_operand:V2DI 1 "altivec_register_operand" "v")
>> + (match_operand:V2DI 2 "altivec_register_operand" "v")))]
>> "TARGET_POWER10"
>> - "vmulhu<wd> %0,%1,%2"
>> + "vmulhud %0,%1,%2"
>> [(set_attr "type" "veccomplex")])
>>
>> ;; Vector multiply low double word
>> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
>> index 4fbdc87f17c..494c0f69832 100644
>> --- a/gcc/doc/extend.texi
>> +++ b/gcc/doc/extend.texi
>> @@ -26846,6 +26846,24 @@ vec_t __builtin_galois_field_mult_gcm (vec_t,
>> vec_t);
>> vec_t __builtin_galois_field_mult_xts (vec_t, vec_t);
>> @end smallexample
>>
>> +@subsubheading PowerPC Vector Integer Multiply High Built-in Functions
>> +
>> +Future PowerPC processors may add new instructions for vector integer
>> +multiply high for halfword. GCC provides support for these instructions
>> through
>> +the following built-in functions.
>> +
>> +@findex vec_mulh
>> +@smallexample
>> +@exdent vector signed short
>> +@exdent vec_mulh (vector signed short @var{a}, vector signed short @var{b});
>> +@exdent vector unsigned short
>> +@exdent vec_mulh (vector unsigned short @var{a}, vector unsigned short
>> @var{b});
>> +@end smallexample
>> +
>> +For each integer value @code{i} from 0 to 7, do the following. The integer
>> +value in halfword element @code{i} of @var{a} is multiplied by the integer
>> +value in halfword element @code{i} of @var{b}. The high-order 16 bits of the
>> +32-bit product are placed into halfword element @code{i} of the vector
>> returned.
>>
>> @node PowerPC Hardware Transactional Memory Built-in Functions
>> @subsection PowerPC Hardware Transactional Memory Built-in Functions
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-1.c
>> b/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-1.c
>> new file mode 100644
>> index 00000000000..0421a71980e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-1.c
>> @@ -0,0 +1,64 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-mdejagnu-cpu=future -O2" } */
>> +/* { dg-require-effective-target powerpc_future_compile_ok } */
>> +
>> +#include <altivec.h>
>> +
>> +typedef vector signed int v4si_t;
>> +typedef vector signed short v8hi_t;
>> +typedef vector signed long long v2di_t;
>> +
>> +v4si_t int_add (v4si_t x, v4si_t y)
>> +{
>> + return vec_add (x, y); /* xvadduwm */
>> +}
>> +
>> +v4si_t int_sub (v4si_t x, v4si_t y)
>> +{
>> + return vec_sub (x, y); /* xvsubuwm */
>> +}
>> +
>> +v4si_t int_mul (v4si_t x, v4si_t y)
>> +{
>> + return vec_mul (x, y); /* xvmuluwm */
>> +}
>> +
>> +v4si_t int_mulhi (v4si_t x, v4si_t y)
>> +{
>> + return vec_mulh (x, y); /* xvmulhsw */
>> +}
>> +
>> +v8hi_t short_add (v8hi_t x, v8hi_t y)
>> +{
>> + return vec_add (x, y); /* xvadduhm */
>> +}
>> +
>> +v8hi_t short_sub (v8hi_t x, v8hi_t y)
>> +{
>> + return vec_sub (x, y); /* xvsubuhm */
>> +}
>> +
>> +v8hi_t short_mul (v8hi_t x, v8hi_t y)
>> +{
>> + return vec_mul (x, y); /* xvmuluhm */
>> +}
>> +
>> +v8hi_t short_mulhi (v8hi_t x, v8hi_t y)
>> +{
>> + return vec_mulh (x, y); /* xvmulhsh */
>> +}
>> +
>> +v2di_t longlong_mulhi (v2di_t x, v2di_t y)
>> +{
>> + return vec_mulh (x, y); /* vmulhsd */
>> +}
>> +
>> +/* { dg-final { scan-assembler-times "xvadduwm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvsubuwm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvmuluwm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvmulhsw" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvadduhm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvsubuhm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvmuluhm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvmulhsh" 1 } } */
>> +/* { dg-final { scan-assembler-times "vmulhsd" 1 } } */
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-2.c
>> b/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-2.c
>> new file mode 100644
>> index 00000000000..c44304041b3
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-2.c
>> @@ -0,0 +1,64 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-mdejagnu-cpu=future -O2" } */
>> +/* { dg-require-effective-target powerpc_future_compile_ok } */
>> +
>> +#include <altivec.h>
>> +
>> +typedef vector unsigned int v4si_t;
>> +typedef vector unsigned short v8hi_t;
>> +typedef vector unsigned long long v2di_t;
>> +
>> +v4si_t uint_add (v4si_t x, v4si_t y)
>> +{
>> + return vec_add (x, y); /* xvadduwm */
>> +}
>> +
>> +v4si_t uint_sub (v4si_t x, v4si_t y)
>> +{
>> + return vec_sub (x, y); /* xvsubuwm */
>> +}
>> +
>> +v4si_t uint_mul (v4si_t x, v4si_t y)
>> +{
>> + return vec_mul (x, y); /* xvmuluwm */
>> +}
>> +
>> +v4si_t uint_mulhi (v4si_t x, v4si_t y)
>> +{
>> + return vec_mulh (x, y); /* xvmulhuw */
>> +}
>> +
>> +v8hi_t ushort_add (v8hi_t x, v8hi_t y)
>> +{
>> + return vec_add (x, y); /* xvadduhm */
>> +}
>> +
>> +v8hi_t ushort_sub (v8hi_t x, v8hi_t y)
>> +{
>> + return vec_sub (x, y); /* xvsubuhm */
>> +}
>> +
>> +v8hi_t ushort_mul (v8hi_t x, v8hi_t y)
>> +{
>> + return vec_mul (x, y); /* xvmuluhm */
>> +}
>> +
>> +v8hi_t ushort_mulhi (v8hi_t x, v8hi_t y)
>> +{
>> + return vec_mulh (x, y); /* xvmulhuh */
>> +}
>> +
>> +v2di_t ulonglong_mulhi (v2di_t x, v2di_t y)
>> +{
>> + return vec_mulh (x, y); /* vmulhud */
>> +}
>> +
>> +/* { dg-final { scan-assembler-times "xvadduwm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvsubuwm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvmuluwm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvmulhuw" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvadduhm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvsubuhm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvmuluhm" 1 } } */
>> +/* { dg-final { scan-assembler-times "xvmulhuh" 1 } } */
>> +/* { dg-final { scan-assembler-times "vmulhud" 1 } } */
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-3.c
>> b/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-3.c
>> new file mode 100644
>> index 00000000000..675d6b07445
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-3.c
>> @@ -0,0 +1,52 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-mdejagnu-cpu=future -O2 -mno-vsx" } */
>> +/* { dg-require-effective-target powerpc_future_compile_ok } */
>> +
>> +#include <altivec.h>
>> +
>> +typedef vector signed int vsi;
>> +typedef vector signed short vss;
>> +typedef vector unsigned int vui;
>> +
>> +vsi int_add (vsi x, vsi y)
>> +{
>> + return vec_add (x, y); /* vadduwm */
>> +}
>> +
>> +vsi int_sub (vsi x, vsi y)
>> +{
>> + return vec_sub (x, y); /* vsubuwm */
>> +}
>> +
>> +vsi int_mulhi (vsi x, vsi y)
>> +{
>> + return vec_mulh (x, y); /* vmulhsw */
>> +}
>> +
>> +vui uint_mulh (vui x, vui y)
>> +{
>> + return vec_mulh (x, y); /* vmulhuw */
>> +}
>> +
>> +vss short_add (vss x, vss y)
>> +{
>> + return vec_add (x, y); /* vadduhm */
>> +}
>> +
>> +vss short_sub (vss x, vss y)
>> +{
>> + return vec_sub (x, y); /* vsubuhm */
>> +}
>> +
>> +vss short_mul (vss x, vss y)
>> +{
>> + return vec_mul (x, y); /* vmladduhm */
>> +}
>> +
>> +/* { dg-final { scan-assembler-times "vadduwm" 1 } } */
>> +/* { dg-final { scan-assembler-times "vsubuwm" 1 } } */
>> +/* { dg-final { scan-assembler-times "vmulhsw" 1 } } */
>> +/* { dg-final { scan-assembler-times "vmulhuw" 1 } } */
>> +/* { dg-final { scan-assembler-times "vadduhm" 1 } } */
>> +/* { dg-final { scan-assembler-times "vsubuhm" 1 } } */
>> +/* { dg-final { scan-assembler-times "vmladduhm" 1 } } */
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-4.c
>> b/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-4.c
>> new file mode 100644
>> index 00000000000..56a3f2a9784
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vsx_arith_builtin-4.c
>> @@ -0,0 +1,20 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-mdejagnu-cpu=future -O2 -mno-vsx" } */
>> +/* { dg-require-effective-target powerpc_future_compile_ok } */
>> +
>> +#include <altivec.h>
>> +
>> +typedef vector signed short vss;
>> +typedef vector unsigned short vus;
>> +
>> +__attribute__((noinline))
>> +vss short_mulhi (vss x, vss y)
>> +{
>> + return vec_mulh (x, y); /* { dg-error "'__builtin_vsx_xvmulhsh' requires
>> the '-mcpu=future' and '-mvsx' options" } */
>> +}
>> +
>> +__attribute__((noinline))
>> +vus ushort_mulhi (vus x, vus y)
>> +{
>> + return vec_mulh (x, y); /* { dg-error "'__builtin_vsx_xvmulhuh' requires
>> the '-mcpu=future' and '-mvsx' options" } */
>> +}
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vsx_arith_vect_1.c
>> b/gcc/testsuite/gcc.target/powerpc/vsx_arith_vect_1.c
>> new file mode 100644
>> index 00000000000..fce087689f6
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vsx_arith_vect_1.c
>> @@ -0,0 +1,77 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-mdejagnu-cpu=future -O2" } */
>> +/* { dg-require-effective-target powerpc_future_compile_ok } */
>> +
>> +#include <altivec.h>
>> +
>> +typedef vector signed int vsi;
>> +typedef vector unsigned int vui;
>> +typedef vector signed short vss;
>> +typedef vector unsigned short vus;
>> +
>> +vsi int_add (vsi x, vsi y)
>> +{
>> + return x + y; /* xvadduwm */
>> +}
>> +
>> +vsi int_sub (vsi x, vsi y)
>> +{
>> + return x - y; /* xvsubuwm */
>> +}
>> +
>> +vsi int_mul (vsi x, vsi y)
>> +{
>> + return x * y; /* xvmuluwm */
>> +}
>> +
>> +vui uint_add (vui x, vui y)
>> +{
>> + return x + y; /* xvadduwm */
>> +}
>> +
>> +vui uint_sub (vui x, vui y)
>> +{
>> + return x - y; /* xvsubuwm */
>> +}
>> +
>> +vui uint_mul (vui x, vui y)
>> +{
>> + return x * y; /* xvmuluwm */
>> +}
>> +
>> +vss short_add (vss x, vss y)
>> +{
>> + return x + y; /* xvadduhm */
>> +}
>> +
>> +vss short_sub (vss x, vss y)
>> +{
>> + return x - y; /* xvsubuhm */
>> +}
>> +
>> +vss short_mul (vss x, vss y)
>> +{
>> + return x * y; /* xvmuluhm */
>> +}
>> +
>> +vus ushort_add (vus x, vus y)
>> +{
>> + return x + y; /* xvadduhm */
>> +}
>> +
>> +vus ushort_sub (vus x, vus y)
>> +{
>> + return x - y; /* xvsubuhm */
>> +}
>> +
>> +vus ushort_mul (vus x, vus y)
>> +{
>> + return x * y; /* xvmuluhm */
>> +}
>> +
>> +/* { dg-final { scan-assembler-times "xvadduwm" 2 } } */
>> +/* { dg-final { scan-assembler-times "xvsubuwm" 2 } } */
>> +/* { dg-final { scan-assembler-times "xvmuluwm" 2 } } */
>> +/* { dg-final { scan-assembler-times "xvadduhm" 2 } } */
>> +/* { dg-final { scan-assembler-times "xvsubuhm" 2 } } */
>> +/* { dg-final { scan-assembler-times "xvmuluhm" 2 } } */
>> diff --git a/gcc/testsuite/gcc.target/powerpc/vsx_arith_vect_2.c
>> b/gcc/testsuite/gcc.target/powerpc/vsx_arith_vect_2.c
>> new file mode 100644
>> index 00000000000..15f85803be5
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/powerpc/vsx_arith_vect_2.c
>> @@ -0,0 +1,43 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-mdejagnu-cpu=future -O2 -ftree-vectorize
>> -fno-unroll-loops" } */
>> +/* { dg-require-effective-target powerpc_future_compile_ok } */
>> +
>> +#define N 128
>> +
>> +extern signed int si_a[N], si_b[N], si_c[N];
>> +extern unsigned int ui_a[N], ui_b[N], ui_c[N];
>> +extern signed short ss_a[N], ss_b[N], ss_c[N];
>> +extern unsigned short us_a[N], us_b[N], us_c[N];
>> +
>> +void int_mulhi ()
>> +{
>> + for (int i = 0; i < N; i++)
>> + si_c[i] = ((signed long long) si_a[i] *
>> + (signed long long) si_b[i]) >> 32;
>> +}
>> +
>> +void uint_mulhi ()
>> +{
>> + for (int i = 0; i < N; i++)
>> + ui_c[i] = ((unsigned long long) ui_a[i] *
>> + (unsigned long long) ui_b[i]) >> 32;
>> +}
>> +
>> +void short_mulhi ()
>> +{
>> + for (int i = 0; i < N; i++)
>> + ss_c[i] = ((signed int) ss_a[i] *
>> + (signed int) ss_b[i]) >> 16;
>> +}
>> +
>> +void ushort_mulhi ()
>> +{
>> + for (int i = 0; i < N; i++)
>> + us_c[i] = ((unsigned int) us_a[i] *
>> + (unsigned int) us_b[i]) >> 16;
>> +}
>> +
>> +/* { dg-final { scan-assembler-times {\mxvmulhsw\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmulhuw\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmulhsh\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxvmulhuh\M} 1 } } */
>>
>>
>