diff mbox series

rs6000: Vector string isolate instructions

Message ID 20200509131626.65355-1-wschmidt@linux.ibm.com
State New
Headers show
Series rs6000: Vector string isolate instructions | expand

Commit Message

Bill Schmidt May 9, 2020, 1:16 p.m. UTC
From: Kelvin Nilsen <kelvin@gcc.gnu.org>

Adds new instructions vstribr, vstrihr, vstribl, and vstrihl, with
overloaded built-in support.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
regressions, using a compiler configured for Power9.  Is this okay
for master?

Thanks,
Bill

[gcc]

2020-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* config/rs6000/altivec.h (vec_strir): New #define.
	(vec_stril): Likewise.
	(vec_strir_p): Likewise.
	(vec_stril_p): Likewise.
	* config/rs6000/altivec.md (UNSPEC_VSTRIR): New constant.
	(UNSPEC_VSTRIL): Likewise.
	(vstrir_<mode>): New expansion.
	(vstrir_code_<mode>): New insn.
	(vstrir_p_<mode>): New expansion.
	(vstrir_p_code_<mode>): New insn.
	(vstril_<mode>): New expansion.
	(vstril_code_<mode>): New insn.
	(vstril_p_<mode>): New expansion.
	(vstril_p_code_<mode>): New insn.
	* config/rs6000/rs6000-builtin.def (__builtin_altivec_vstribr):
	New built-in function.
	(__builtin_altivec_vstrihr): Likewise.
	(__builtin_altivec_vstribl): Likewise.
	(__builtin_altivec_vstrihl): Likewise.
	(__builtin_altivec_vstribr_p): Likewise.
	(__builtin_altivec_vstrihr_p): Likewise.
	(__builtin_altivec_vstribl_p): Likewise.
	(__builtin_altivec_vstrihl_p): Likewise.
	(__builtin_vec_strir): New overloaded built-in function.
	(__builtin_vec_stril): Likewise.
	(__builtin_vec_strir_p): Likewise.
	(__builtin_vec_stril_p): Likewise.
	* config/rs6000/rs6000-call.c (altivec_overloaded_builtins):
	Define overloaded forms of __builtin_vec_strir,
	__builtin_vec_stril, __builtin_vec_strir_p, and
	__builtin_vec_stril_p.
	* doc/extend.texi (PowerPC AltiVec Built-in Functions Available
	for a Future Architecture): Add description of vec_stril,
	vec_stril_p, vec_strir, and vec_strir_p built-in functions.

[gcc]

2020-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* gcc.target/powerpc/vec-stril-0.c: New.
	* gcc.target/powerpc/vec-stril-1.c: New.
	* gcc.target/powerpc/vec-stril-10.c: New.
	* gcc.target/powerpc/vec-stril-11.c: New.
	* gcc.target/powerpc/vec-stril-12.c: New.
	* gcc.target/powerpc/vec-stril-13.c: New.
	* gcc.target/powerpc/vec-stril-14.c: New.
	* gcc.target/powerpc/vec-stril-15.c: New.
	* gcc.target/powerpc/vec-stril-16.c: New.
	* gcc.target/powerpc/vec-stril-17.c: New.
	* gcc.target/powerpc/vec-stril-18.c: New.
	* gcc.target/powerpc/vec-stril-19.c: New.
	* gcc.target/powerpc/vec-stril-2.c: New.
	* gcc.target/powerpc/vec-stril-20.c: New.
	* gcc.target/powerpc/vec-stril-21.c: New.
	* gcc.target/powerpc/vec-stril-22.c: New.
	* gcc.target/powerpc/vec-stril-23.c: New.
	* gcc.target/powerpc/vec-stril-3.c: New.
	* gcc.target/powerpc/vec-stril-4.c: New.
	* gcc.target/powerpc/vec-stril-5.c: New.
	* gcc.target/powerpc/vec-stril-6.c: New.
	* gcc.target/powerpc/vec-stril-7.c: New.
	* gcc.target/powerpc/vec-stril-8.c: New.
	* gcc.target/powerpc/vec-stril-9.c: New.
	* gcc.target/powerpc/vec-stril_p-0.c: New.
	* gcc.target/powerpc/vec-stril_p-1.c: New.
	* gcc.target/powerpc/vec-stril_p-10.c: New.
	* gcc.target/powerpc/vec-stril_p-11.c: New.
	* gcc.target/powerpc/vec-stril_p-2.c: New.
	* gcc.target/powerpc/vec-stril_p-3.c: New.
	* gcc.target/powerpc/vec-stril_p-4.c: New.
	* gcc.target/powerpc/vec-stril_p-5.c: New.
	* gcc.target/powerpc/vec-stril_p-6.c: New.
	* gcc.target/powerpc/vec-stril_p-7.c: New.
	* gcc.target/powerpc/vec-stril_p-8.c: New.
	* gcc.target/powerpc/vec-stril_p-9.c: New.
	* gcc.target/powerpc/vec-strir-0.c: New.
	* gcc.target/powerpc/vec-strir-1.c: New.
	* gcc.target/powerpc/vec-strir-10.c: New.
	* gcc.target/powerpc/vec-strir-11.c: New.
	* gcc.target/powerpc/vec-strir-12.c: New.
	* gcc.target/powerpc/vec-strir-13.c: New.
	* gcc.target/powerpc/vec-strir-14.c: New.
	* gcc.target/powerpc/vec-strir-15.c: New.
	* gcc.target/powerpc/vec-strir-16.c: New.
	* gcc.target/powerpc/vec-strir-17.c: New.
	* gcc.target/powerpc/vec-strir-18.c: New.
	* gcc.target/powerpc/vec-strir-19.c: New.
	* gcc.target/powerpc/vec-strir-2.c: New.
	* gcc.target/powerpc/vec-strir-20.c: New.
	* gcc.target/powerpc/vec-strir-21.c: New.
	* gcc.target/powerpc/vec-strir-22.c: New.
	* gcc.target/powerpc/vec-strir-23.c: New.
	* gcc.target/powerpc/vec-strir-3.c: New.
	* gcc.target/powerpc/vec-strir-4.c: New.
	* gcc.target/powerpc/vec-strir-5.c: New.
	* gcc.target/powerpc/vec-strir-6.c: New.
	* gcc.target/powerpc/vec-strir-7.c: New.
	* gcc.target/powerpc/vec-strir-8.c: New.
	* gcc.target/powerpc/vec-strir-9.c: New.
	* gcc.target/powerpc/vec-strir_p-0.c: New.
	* gcc.target/powerpc/vec-strir_p-1.c: New.
	* gcc.target/powerpc/vec-strir_p-10.c: New.
	* gcc.target/powerpc/vec-strir_p-11.c: New.
	* gcc.target/powerpc/vec-strir_p-2.c: New.
	* gcc.target/powerpc/vec-strir_p-3.c: New.
	* gcc.target/powerpc/vec-strir_p-4.c: New.
	* gcc.target/powerpc/vec-strir_p-5.c: New.
	* gcc.target/powerpc/vec-strir_p-6.c: New.
	* gcc.target/powerpc/vec-strir_p-7.c: New.
	* gcc.target/powerpc/vec-strir_p-8.c: New.
	* gcc.target/powerpc/vec-strir_p-9.c: New.
---
 gcc/config/rs6000/altivec.h                   |   6 +
 gcc/config/rs6000/altivec.md                  | 105 ++++++++++++++++++
 gcc/config/rs6000/rs6000-builtin.def          |  15 +++
 gcc/config/rs6000/rs6000-call.c               |  40 +++++++
 gcc/doc/extend.texi                           |  56 ++++++++++
 .../gcc.target/powerpc/vec-stril-0.c          |  21 ++++
 .../gcc.target/powerpc/vec-stril-1.c          |  52 +++++++++
 .../gcc.target/powerpc/vec-stril-10.c         |  27 +++++
 .../gcc.target/powerpc/vec-stril-11.c         |  29 +++++
 .../gcc.target/powerpc/vec-stril-12.c         |  27 +++++
 .../gcc.target/powerpc/vec-stril-13.c         |  28 +++++
 .../gcc.target/powerpc/vec-stril-14.c         |  27 +++++
 .../gcc.target/powerpc/vec-stril-15.c         |  28 +++++
 .../gcc.target/powerpc/vec-stril-16.c         |  56 ++++++++++
 .../gcc.target/powerpc/vec-stril-17.c         |  54 +++++++++
 .../gcc.target/powerpc/vec-stril-18.c         |  56 ++++++++++
 .../gcc.target/powerpc/vec-stril-19.c         |  54 +++++++++
 .../gcc.target/powerpc/vec-stril-2.c          |  21 ++++
 .../gcc.target/powerpc/vec-stril-20.c         |  46 ++++++++
 .../gcc.target/powerpc/vec-stril-21.c         |  44 ++++++++
 .../gcc.target/powerpc/vec-stril-22.c         |  44 ++++++++
 .../gcc.target/powerpc/vec-stril-23.c         |  42 +++++++
 .../gcc.target/powerpc/vec-stril-3.c          |  52 +++++++++
 .../gcc.target/powerpc/vec-stril-4.c          |  21 ++++
 .../gcc.target/powerpc/vec-stril-5.c          |  45 ++++++++
 .../gcc.target/powerpc/vec-stril-6.c          |  21 ++++
 .../gcc.target/powerpc/vec-stril-7.c          |  43 +++++++
 .../gcc.target/powerpc/vec-stril-8.c          |  27 +++++
 .../gcc.target/powerpc/vec-stril-9.c          |  28 +++++
 .../gcc.target/powerpc/vec-stril_p-0.c        |  24 ++++
 .../gcc.target/powerpc/vec-stril_p-1.c        |  41 +++++++
 .../gcc.target/powerpc/vec-stril_p-10.c       |  37 ++++++
 .../gcc.target/powerpc/vec-stril_p-11.c       |  37 ++++++
 .../gcc.target/powerpc/vec-stril_p-2.c        |  23 ++++
 .../gcc.target/powerpc/vec-stril_p-3.c        |  40 +++++++
 .../gcc.target/powerpc/vec-stril_p-4.c        |  23 ++++
 .../gcc.target/powerpc/vec-stril_p-5.c        |  35 ++++++
 .../gcc.target/powerpc/vec-stril_p-6.c        |  23 ++++
 .../gcc.target/powerpc/vec-stril_p-7.c        |  36 ++++++
 .../gcc.target/powerpc/vec-stril_p-8.c        |  42 +++++++
 .../gcc.target/powerpc/vec-stril_p-9.c        |  42 +++++++
 .../gcc.target/powerpc/vec-strir-0.c          |  21 ++++
 .../gcc.target/powerpc/vec-strir-1.c          |  52 +++++++++
 .../gcc.target/powerpc/vec-strir-10.c         |  27 +++++
 .../gcc.target/powerpc/vec-strir-11.c         |  28 +++++
 .../gcc.target/powerpc/vec-strir-12.c         |  28 +++++
 .../gcc.target/powerpc/vec-strir-13.c         |  29 +++++
 .../gcc.target/powerpc/vec-strir-14.c         |  27 +++++
 .../gcc.target/powerpc/vec-strir-15.c         |  28 +++++
 .../gcc.target/powerpc/vec-strir-16.c         |  56 ++++++++++
 .../gcc.target/powerpc/vec-strir-17.c         |  54 +++++++++
 .../gcc.target/powerpc/vec-strir-18.c         |  56 ++++++++++
 .../gcc.target/powerpc/vec-strir-19.c         |  54 +++++++++
 .../gcc.target/powerpc/vec-strir-2.c          |  21 ++++
 .../gcc.target/powerpc/vec-strir-20.c         |  48 ++++++++
 .../gcc.target/powerpc/vec-strir-21.c         |  46 ++++++++
 .../gcc.target/powerpc/vec-strir-22.c         |  48 ++++++++
 .../gcc.target/powerpc/vec-strir-23.c         |  46 ++++++++
 .../gcc.target/powerpc/vec-strir-3.c          |  52 +++++++++
 .../gcc.target/powerpc/vec-strir-4.c          |  21 ++++
 .../gcc.target/powerpc/vec-strir-5.c          |  44 ++++++++
 .../gcc.target/powerpc/vec-strir-6.c          |  21 ++++
 .../gcc.target/powerpc/vec-strir-7.c          |  44 ++++++++
 .../gcc.target/powerpc/vec-strir-8.c          |  27 +++++
 .../gcc.target/powerpc/vec-strir-9.c          |  28 +++++
 .../gcc.target/powerpc/vec-strir_p-0.c        |  23 ++++
 .../gcc.target/powerpc/vec-strir_p-1.c        |  39 +++++++
 .../gcc.target/powerpc/vec-strir_p-10.c       |  46 ++++++++
 .../gcc.target/powerpc/vec-strir_p-11.c       |  38 +++++++
 .../gcc.target/powerpc/vec-strir_p-2.c        |  23 ++++
 .../gcc.target/powerpc/vec-strir_p-3.c        |  40 +++++++
 .../gcc.target/powerpc/vec-strir_p-4.c        |  23 ++++
 .../gcc.target/powerpc/vec-strir_p-5.c        |  44 ++++++++
 .../gcc.target/powerpc/vec-strir_p-6.c        |  23 ++++
 .../gcc.target/powerpc/vec-strir_p-7.c        |  36 ++++++
 .../gcc.target/powerpc/vec-strir_p-8.c        |  43 +++++++
 .../gcc.target/powerpc/vec-strir_p-9.c        |  42 +++++++
 77 files changed, 2844 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-0.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-1.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-10.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-11.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-12.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-13.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-14.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-15.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-16.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-17.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-18.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-19.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-2.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-20.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-21.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-22.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-23.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-4.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-5.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-6.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-7.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-8.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-9.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-0.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-1.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-10.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-11.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-2.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-4.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-5.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-6.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-7.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-8.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-9.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-0.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-1.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-10.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-11.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-12.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-13.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-14.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-15.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-16.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-17.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-18.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-19.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-2.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-20.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-21.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-22.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-23.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-4.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-5.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-6.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-7.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-8.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-9.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-0.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-1.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-10.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-11.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-2.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-4.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-5.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-6.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-7.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-8.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-9.c

Comments

David Edelsohn May 10, 2020, 1:33 a.m. UTC | #1
On Sat, May 9, 2020 at 9:16 AM Bill Schmidt <wschmidt@linux.ibm.com> wrote:
>
> From: Kelvin Nilsen <kelvin@gcc.gnu.org>
>
> Adds new instructions vstribr, vstrihr, vstribl, and vstrihl, with
> overloaded built-in support.
>
> Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
> regressions, using a compiler configured for Power9.  Is this okay
> for master?
>
> Thanks,
> Bill
>
> [gcc]
>
> 2020-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>
>
>         * config/rs6000/altivec.h (vec_strir): New #define.
>         (vec_stril): Likewise.
>         (vec_strir_p): Likewise.
>         (vec_stril_p): Likewise.
>         * config/rs6000/altivec.md (UNSPEC_VSTRIR): New constant.
>         (UNSPEC_VSTRIL): Likewise.
>         (vstrir_<mode>): New expansion.
>         (vstrir_code_<mode>): New insn.
>         (vstrir_p_<mode>): New expansion.
>         (vstrir_p_code_<mode>): New insn.
>         (vstril_<mode>): New expansion.
>         (vstril_code_<mode>): New insn.
>         (vstril_p_<mode>): New expansion.
>         (vstril_p_code_<mode>): New insn.
>         * config/rs6000/rs6000-builtin.def (__builtin_altivec_vstribr):
>         New built-in function.
>         (__builtin_altivec_vstrihr): Likewise.
>         (__builtin_altivec_vstribl): Likewise.
>         (__builtin_altivec_vstrihl): Likewise.
>         (__builtin_altivec_vstribr_p): Likewise.
>         (__builtin_altivec_vstrihr_p): Likewise.
>         (__builtin_altivec_vstribl_p): Likewise.
>         (__builtin_altivec_vstrihl_p): Likewise.
>         (__builtin_vec_strir): New overloaded built-in function.
>         (__builtin_vec_stril): Likewise.
>         (__builtin_vec_strir_p): Likewise.
>         (__builtin_vec_stril_p): Likewise.
>         * config/rs6000/rs6000-call.c (altivec_overloaded_builtins):
>         Define overloaded forms of __builtin_vec_strir,
>         __builtin_vec_stril, __builtin_vec_strir_p, and
>         __builtin_vec_stril_p.
>         * doc/extend.texi (PowerPC AltiVec Built-in Functions Available
>         for a Future Architecture): Add description of vec_stril,
>         vec_stril_p, vec_strir, and vec_strir_p built-in functions.
>
> [gcc]
>
> 2020-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>
>
>         * gcc.target/powerpc/vec-stril-0.c: New.
>         * gcc.target/powerpc/vec-stril-1.c: New.
>         * gcc.target/powerpc/vec-stril-10.c: New.
>         * gcc.target/powerpc/vec-stril-11.c: New.
>         * gcc.target/powerpc/vec-stril-12.c: New.
>         * gcc.target/powerpc/vec-stril-13.c: New.
>         * gcc.target/powerpc/vec-stril-14.c: New.
>         * gcc.target/powerpc/vec-stril-15.c: New.
>         * gcc.target/powerpc/vec-stril-16.c: New.
>         * gcc.target/powerpc/vec-stril-17.c: New.
>         * gcc.target/powerpc/vec-stril-18.c: New.
>         * gcc.target/powerpc/vec-stril-19.c: New.
>         * gcc.target/powerpc/vec-stril-2.c: New.
>         * gcc.target/powerpc/vec-stril-20.c: New.
>         * gcc.target/powerpc/vec-stril-21.c: New.
>         * gcc.target/powerpc/vec-stril-22.c: New.
>         * gcc.target/powerpc/vec-stril-23.c: New.
>         * gcc.target/powerpc/vec-stril-3.c: New.
>         * gcc.target/powerpc/vec-stril-4.c: New.
>         * gcc.target/powerpc/vec-stril-5.c: New.
>         * gcc.target/powerpc/vec-stril-6.c: New.
>         * gcc.target/powerpc/vec-stril-7.c: New.
>         * gcc.target/powerpc/vec-stril-8.c: New.
>         * gcc.target/powerpc/vec-stril-9.c: New.
>         * gcc.target/powerpc/vec-stril_p-0.c: New.
>         * gcc.target/powerpc/vec-stril_p-1.c: New.
>         * gcc.target/powerpc/vec-stril_p-10.c: New.
>         * gcc.target/powerpc/vec-stril_p-11.c: New.
>         * gcc.target/powerpc/vec-stril_p-2.c: New.
>         * gcc.target/powerpc/vec-stril_p-3.c: New.
>         * gcc.target/powerpc/vec-stril_p-4.c: New.
>         * gcc.target/powerpc/vec-stril_p-5.c: New.
>         * gcc.target/powerpc/vec-stril_p-6.c: New.
>         * gcc.target/powerpc/vec-stril_p-7.c: New.
>         * gcc.target/powerpc/vec-stril_p-8.c: New.
>         * gcc.target/powerpc/vec-stril_p-9.c: New.
>         * gcc.target/powerpc/vec-strir-0.c: New.
>         * gcc.target/powerpc/vec-strir-1.c: New.
>         * gcc.target/powerpc/vec-strir-10.c: New.
>         * gcc.target/powerpc/vec-strir-11.c: New.
>         * gcc.target/powerpc/vec-strir-12.c: New.
>         * gcc.target/powerpc/vec-strir-13.c: New.
>         * gcc.target/powerpc/vec-strir-14.c: New.
>         * gcc.target/powerpc/vec-strir-15.c: New.
>         * gcc.target/powerpc/vec-strir-16.c: New.
>         * gcc.target/powerpc/vec-strir-17.c: New.
>         * gcc.target/powerpc/vec-strir-18.c: New.
>         * gcc.target/powerpc/vec-strir-19.c: New.
>         * gcc.target/powerpc/vec-strir-2.c: New.
>         * gcc.target/powerpc/vec-strir-20.c: New.
>         * gcc.target/powerpc/vec-strir-21.c: New.
>         * gcc.target/powerpc/vec-strir-22.c: New.
>         * gcc.target/powerpc/vec-strir-23.c: New.
>         * gcc.target/powerpc/vec-strir-3.c: New.
>         * gcc.target/powerpc/vec-strir-4.c: New.
>         * gcc.target/powerpc/vec-strir-5.c: New.
>         * gcc.target/powerpc/vec-strir-6.c: New.
>         * gcc.target/powerpc/vec-strir-7.c: New.
>         * gcc.target/powerpc/vec-strir-8.c: New.
>         * gcc.target/powerpc/vec-strir-9.c: New.
>         * gcc.target/powerpc/vec-strir_p-0.c: New.
>         * gcc.target/powerpc/vec-strir_p-1.c: New.
>         * gcc.target/powerpc/vec-strir_p-10.c: New.
>         * gcc.target/powerpc/vec-strir_p-11.c: New.
>         * gcc.target/powerpc/vec-strir_p-2.c: New.
>         * gcc.target/powerpc/vec-strir_p-3.c: New.
>         * gcc.target/powerpc/vec-strir_p-4.c: New.
>         * gcc.target/powerpc/vec-strir_p-5.c: New.
>         * gcc.target/powerpc/vec-strir_p-6.c: New.
>         * gcc.target/powerpc/vec-strir_p-7.c: New.
>         * gcc.target/powerpc/vec-strir_p-8.c: New.
>         * gcc.target/powerpc/vec-strir_p-9.c: New.

This is okay, modulo any comments from Segher.

Thanks, David

> ---
>  gcc/config/rs6000/altivec.h                   |   6 +
>  gcc/config/rs6000/altivec.md                  | 105 ++++++++++++++++++
>  gcc/config/rs6000/rs6000-builtin.def          |  15 +++
>  gcc/config/rs6000/rs6000-call.c               |  40 +++++++
>  gcc/doc/extend.texi                           |  56 ++++++++++
>  .../gcc.target/powerpc/vec-stril-0.c          |  21 ++++
>  .../gcc.target/powerpc/vec-stril-1.c          |  52 +++++++++
>  .../gcc.target/powerpc/vec-stril-10.c         |  27 +++++
>  .../gcc.target/powerpc/vec-stril-11.c         |  29 +++++
>  .../gcc.target/powerpc/vec-stril-12.c         |  27 +++++
>  .../gcc.target/powerpc/vec-stril-13.c         |  28 +++++
>  .../gcc.target/powerpc/vec-stril-14.c         |  27 +++++
>  .../gcc.target/powerpc/vec-stril-15.c         |  28 +++++
>  .../gcc.target/powerpc/vec-stril-16.c         |  56 ++++++++++
>  .../gcc.target/powerpc/vec-stril-17.c         |  54 +++++++++
>  .../gcc.target/powerpc/vec-stril-18.c         |  56 ++++++++++
>  .../gcc.target/powerpc/vec-stril-19.c         |  54 +++++++++
>  .../gcc.target/powerpc/vec-stril-2.c          |  21 ++++
>  .../gcc.target/powerpc/vec-stril-20.c         |  46 ++++++++
>  .../gcc.target/powerpc/vec-stril-21.c         |  44 ++++++++
>  .../gcc.target/powerpc/vec-stril-22.c         |  44 ++++++++
>  .../gcc.target/powerpc/vec-stril-23.c         |  42 +++++++
>  .../gcc.target/powerpc/vec-stril-3.c          |  52 +++++++++
>  .../gcc.target/powerpc/vec-stril-4.c          |  21 ++++
>  .../gcc.target/powerpc/vec-stril-5.c          |  45 ++++++++
>  .../gcc.target/powerpc/vec-stril-6.c          |  21 ++++
>  .../gcc.target/powerpc/vec-stril-7.c          |  43 +++++++
>  .../gcc.target/powerpc/vec-stril-8.c          |  27 +++++
>  .../gcc.target/powerpc/vec-stril-9.c          |  28 +++++
>  .../gcc.target/powerpc/vec-stril_p-0.c        |  24 ++++
>  .../gcc.target/powerpc/vec-stril_p-1.c        |  41 +++++++
>  .../gcc.target/powerpc/vec-stril_p-10.c       |  37 ++++++
>  .../gcc.target/powerpc/vec-stril_p-11.c       |  37 ++++++
>  .../gcc.target/powerpc/vec-stril_p-2.c        |  23 ++++
>  .../gcc.target/powerpc/vec-stril_p-3.c        |  40 +++++++
>  .../gcc.target/powerpc/vec-stril_p-4.c        |  23 ++++
>  .../gcc.target/powerpc/vec-stril_p-5.c        |  35 ++++++
>  .../gcc.target/powerpc/vec-stril_p-6.c        |  23 ++++
>  .../gcc.target/powerpc/vec-stril_p-7.c        |  36 ++++++
>  .../gcc.target/powerpc/vec-stril_p-8.c        |  42 +++++++
>  .../gcc.target/powerpc/vec-stril_p-9.c        |  42 +++++++
>  .../gcc.target/powerpc/vec-strir-0.c          |  21 ++++
>  .../gcc.target/powerpc/vec-strir-1.c          |  52 +++++++++
>  .../gcc.target/powerpc/vec-strir-10.c         |  27 +++++
>  .../gcc.target/powerpc/vec-strir-11.c         |  28 +++++
>  .../gcc.target/powerpc/vec-strir-12.c         |  28 +++++
>  .../gcc.target/powerpc/vec-strir-13.c         |  29 +++++
>  .../gcc.target/powerpc/vec-strir-14.c         |  27 +++++
>  .../gcc.target/powerpc/vec-strir-15.c         |  28 +++++
>  .../gcc.target/powerpc/vec-strir-16.c         |  56 ++++++++++
>  .../gcc.target/powerpc/vec-strir-17.c         |  54 +++++++++
>  .../gcc.target/powerpc/vec-strir-18.c         |  56 ++++++++++
>  .../gcc.target/powerpc/vec-strir-19.c         |  54 +++++++++
>  .../gcc.target/powerpc/vec-strir-2.c          |  21 ++++
>  .../gcc.target/powerpc/vec-strir-20.c         |  48 ++++++++
>  .../gcc.target/powerpc/vec-strir-21.c         |  46 ++++++++
>  .../gcc.target/powerpc/vec-strir-22.c         |  48 ++++++++
>  .../gcc.target/powerpc/vec-strir-23.c         |  46 ++++++++
>  .../gcc.target/powerpc/vec-strir-3.c          |  52 +++++++++
>  .../gcc.target/powerpc/vec-strir-4.c          |  21 ++++
>  .../gcc.target/powerpc/vec-strir-5.c          |  44 ++++++++
>  .../gcc.target/powerpc/vec-strir-6.c          |  21 ++++
>  .../gcc.target/powerpc/vec-strir-7.c          |  44 ++++++++
>  .../gcc.target/powerpc/vec-strir-8.c          |  27 +++++
>  .../gcc.target/powerpc/vec-strir-9.c          |  28 +++++
>  .../gcc.target/powerpc/vec-strir_p-0.c        |  23 ++++
>  .../gcc.target/powerpc/vec-strir_p-1.c        |  39 +++++++
>  .../gcc.target/powerpc/vec-strir_p-10.c       |  46 ++++++++
>  .../gcc.target/powerpc/vec-strir_p-11.c       |  38 +++++++
>  .../gcc.target/powerpc/vec-strir_p-2.c        |  23 ++++
>  .../gcc.target/powerpc/vec-strir_p-3.c        |  40 +++++++
>  .../gcc.target/powerpc/vec-strir_p-4.c        |  23 ++++
>  .../gcc.target/powerpc/vec-strir_p-5.c        |  44 ++++++++
>  .../gcc.target/powerpc/vec-strir_p-6.c        |  23 ++++
>  .../gcc.target/powerpc/vec-strir_p-7.c        |  36 ++++++
>  .../gcc.target/powerpc/vec-strir_p-8.c        |  43 +++++++
>  .../gcc.target/powerpc/vec-strir_p-9.c        |  42 +++++++
>  77 files changed, 2844 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-0.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-1.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-10.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-11.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-12.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-13.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-14.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-15.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-16.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-17.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-18.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-19.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-2.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-20.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-21.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-22.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-23.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-3.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-4.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-5.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-6.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-7.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-8.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril-9.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-0.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-1.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-10.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-11.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-2.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-3.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-4.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-5.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-6.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-7.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-8.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-stril_p-9.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-0.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-1.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-10.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-11.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-12.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-13.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-14.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-15.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-16.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-17.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-18.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-19.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-2.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-20.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-21.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-22.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-23.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-3.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-4.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-5.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-6.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-7.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-8.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir-9.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-0.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-1.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-10.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-11.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-2.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-3.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-4.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-5.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-6.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-7.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-8.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-strir_p-9.c
>
> diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
> index addf7d0db52..b29413deb6d 100644
> --- a/gcc/config/rs6000/altivec.h
> +++ b/gcc/config/rs6000/altivec.h
> @@ -700,6 +700,12 @@ __altivec_scalar_pred(vec_any_nle,
>  #define vec_clrl(a, b) __builtin_vec_clrl (a, b)
>  #define vec_clrr(a, b) __builtin_vec_clrr (a, b)
>  #define vec_ternarylogic(a, b, c, d)   __builtin_vec_xxeval (a, b, c, d)
> +
> +#define vec_strir(a)   __builtin_vec_strir (a)
> +#define vec_stril(a)   __builtin_vec_stril (a)
> +
> +#define vec_strir_p(a) __builtin_vec_strir_p (a)
> +#define vec_stril_p(a) __builtin_vec_stril_p (a)
>  #endif
>
>  #endif /* _ALTIVEC_H */
> diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
> index 7382d7c4b44..1c0bbb7527a 100644
> --- a/gcc/config/rs6000/altivec.md
> +++ b/gcc/config/rs6000/altivec.md
> @@ -169,6 +169,8 @@ (define_c_enum "unspec"
>     UNSPEC_VCLRLB
>     UNSPEC_VCLRRB
>     UNSPEC_XXEVAL
> +   UNSPEC_VSTRIR
> +   UNSPEC_VSTRIL
>  ])
>
>  (define_c_enum "unspecv"
> @@ -781,6 +783,109 @@ (define_expand "mulv8hi3"
>    DONE;
>  })
>
> +(define_expand "vstrir_<mode>"
> +  [(set (match_operand:VIshort 0 "altivec_register_operand")
> +       (unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")]
> +                       UNSPEC_VSTRIR))]
> +  "TARGET_FUTURE"
> +{
> +  if (BYTES_BIG_ENDIAN)
> +    emit_insn (gen_vstrir_code_<mode> (operands[0], operands[1]));
> +  else
> +    emit_insn (gen_vstril_code_<mode> (operands[0], operands[1]));
> +  DONE;
> +})
> +
> +(define_insn "vstrir_code_<mode>"
> +  [(set (match_operand:VIshort 0 "altivec_register_operand" "=v")
> +       (unspec:VIshort
> +          [(match_operand:VIshort 1 "altivec_register_operand" "v")]
> +          UNSPEC_VSTRIR))]
> +  "TARGET_FUTURE"
> +  "vstri<wd>r %0,%1"
> +  [(set_attr "type" "vecsimple")])
> +
> +;; This expands into same code as vstrir_<mode> followed by condition logic
> +;; so that a single vstribr. or vstrihr. or vstribl. or vstrihl. instruction
> +;; can, for example, satisfy the needs of a vec_strir () function paired
> +;; with a vec_strir_p () function if both take the same incoming arguments.
> +(define_expand "vstrir_p_<mode>"
> +  [(match_operand:SI 0 "gpc_reg_operand")
> +   (match_operand:VIshort 1 "altivec_register_operand")]
> +  "TARGET_FUTURE"
> +{
> +  rtx scratch = gen_reg_rtx (<MODE>mode);
> +  if (BYTES_BIG_ENDIAN)
> +    emit_insn (gen_vstrir_p_code_<mode> (scratch, operands[1]));
> +  else
> +    emit_insn (gen_vstril_p_code_<mode> (scratch, operands[1]));
> +  emit_insn (gen_cr6_test_for_zero (operands[0]));
> +  DONE;
> +})
> +
> +(define_insn "vstrir_p_code_<mode>"
> +  [(set (match_operand:VIshort 0 "altivec_register_operand" "=v")
> +       (unspec:VIshort
> +          [(match_operand:VIshort 1 "altivec_register_operand" "v")]
> +          UNSPEC_VSTRIR))
> +   (set (reg:CC CR6_REGNO)
> +       (unspec:CC [(match_dup 1)]
> +                  UNSPEC_VSTRIR))]
> +  "TARGET_FUTURE"
> +  "vstri<wd>r. %0,%1"
> +  [(set_attr "type" "vecsimple")])
> +
> +(define_expand "vstril_<mode>"
> +  [(set (match_operand:VIshort 0 "altivec_register_operand")
> +       (unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")]
> +                       UNSPEC_VSTRIR))]
> +  "TARGET_FUTURE"
> +{
> +  if (BYTES_BIG_ENDIAN)
> +    emit_insn (gen_vstril_code_<mode> (operands[0], operands[1]));
> +  else
> +    emit_insn (gen_vstrir_code_<mode> (operands[0], operands[1]));
> +  DONE;
> +})
> +
> +(define_insn "vstril_code_<mode>"
> +  [(set (match_operand:VIshort 0 "altivec_register_operand" "=v")
> +       (unspec:VIshort
> +          [(match_operand:VIshort 1 "altivec_register_operand" "v")]
> +          UNSPEC_VSTRIL))]
> +  "TARGET_FUTURE"
> +  "vstri<wd>l %0,%1"
> +  [(set_attr "type" "vecsimple")])
> +
> +;; This expands into same code as vstril_<mode> followed by condition logic
> +;; so that a single vstribr. or vstrihr. or vstribl. or vstrihl. instruction
> +;; can, for example, satisfy the needs of a vec_stril () function paired
> +;; with a vec_stril_p () function if both take the same incoming arguments.
> +(define_expand "vstril_p_<mode>"
> +  [(match_operand:SI 0 "gpc_reg_operand")
> +   (match_operand:VIshort 1 "altivec_register_operand")]
> +  "TARGET_FUTURE"
> +{
> +  rtx scratch = gen_reg_rtx (<MODE>mode);
> +  if (BYTES_BIG_ENDIAN)
> +    emit_insn (gen_vstril_p_code_<mode> (scratch, operands[1]));
> +  else
> +    emit_insn (gen_vstrir_p_code_<mode> (scratch, operands[1]));
> +  emit_insn (gen_cr6_test_for_zero (operands[0]));
> +  DONE;
> +})
> +
> +(define_insn "vstril_p_code_<mode>"
> +  [(set (match_operand:VIshort 0 "altivec_register_operand" "=v")
> +       (unspec:VIshort
> +          [(match_operand:VIshort 1 "altivec_register_operand" "v")]
> +          UNSPEC_VSTRIL))
> +   (set (reg:CC CR6_REGNO)
> +       (unspec:CC [(match_dup 1)]
> +                  UNSPEC_VSTRIR))]
> +  "TARGET_FUTURE"
> +  "vstri<wd>l. %0,%1"
> +  [(set_attr "type" "vecsimple")])
>
>  ;; Fused multiply subtract
>  (define_insn "*altivec_vnmsubfp"
> diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
> index 7ff8db5dccc..1f86293d0e2 100644
> --- a/gcc/config/rs6000/rs6000-builtin.def
> +++ b/gcc/config/rs6000/rs6000-builtin.def
> @@ -2612,12 +2612,27 @@ BU_FUTURE_V_2 (VPEXTD, "vpextd", CONST, vpextd)
>  BU_FUTURE_V_2 (VGNB, "vgnb", CONST, vgnb)
>  BU_FUTURE_V_4 (XXEVAL, "xxeval", CONST, xxeval)
>
> +BU_FUTURE_V_1 (VSTRIBR, "vstribr", CONST, vstrir_v16qi)
> +BU_FUTURE_V_1 (VSTRIHR, "vstrihr", CONST, vstrir_v8hi)
> +BU_FUTURE_V_1 (VSTRIBL, "vstribl", CONST, vstril_v16qi)
> +BU_FUTURE_V_1 (VSTRIHL, "vstrihl", CONST, vstril_v8hi)
> +
> +BU_FUTURE_V_1 (VSTRIBR_P, "vstribr_p", CONST, vstrir_p_v16qi)
> +BU_FUTURE_V_1 (VSTRIHR_P, "vstrihr_p", CONST, vstrir_p_v8hi)
> +BU_FUTURE_V_1 (VSTRIBL_P, "vstribl_p", CONST, vstril_p_v16qi)
> +BU_FUTURE_V_1 (VSTRIHL_P, "vstrihl_p", CONST, vstril_p_v8hi)
> +
>  /* Future architecture overloaded vector built-ins.  */
>  BU_FUTURE_OVERLOAD_2 (CLRL, "clrl")
>  BU_FUTURE_OVERLOAD_2 (CLRR, "clrr")
>  BU_FUTURE_OVERLOAD_2 (GNB, "gnb")
>  BU_FUTURE_OVERLOAD_4 (XXEVAL, "xxeval")
>
> +BU_FUTURE_OVERLOAD_1 (VSTRIR, "strir")
> +BU_FUTURE_OVERLOAD_1 (VSTRIL, "stril")
> +
> +BU_FUTURE_OVERLOAD_1 (VSTRIR_P, "strir_p")
> +BU_FUTURE_OVERLOAD_1 (VSTRIL_P, "stril_p")
>
>  /* 1 argument crypto functions.  */
>  BU_CRYPTO_1 (VSBOX,            "vsbox",          CONST, crypto_vsbox_v2di)
> diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
> index 9b9562ce4c3..64a9ba2818d 100644
> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -5551,6 +5551,46 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
>      RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI,
>      RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI },
>
> +  { FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIBL,
> +    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 },
> +  { FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIBL,
> +    RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
> +
> +  { FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIHL,
> +    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 },
> +  { FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIHL,
> +    RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 },
> +
> +  { FUTURE_BUILTIN_VEC_VSTRIL_P, FUTURE_BUILTIN_VSTRIBL_P,
> +    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0 },
> +  { FUTURE_BUILTIN_VEC_VSTRIL_P, FUTURE_BUILTIN_VSTRIBL_P,
> +    RS6000_BTI_INTSI, RS6000_BTI_V16QI, 0, 0 },
> +
> +  { FUTURE_BUILTIN_VEC_VSTRIL_P, FUTURE_BUILTIN_VSTRIHL_P,
> +    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, 0, 0 },
> +  { FUTURE_BUILTIN_VEC_VSTRIL_P, FUTURE_BUILTIN_VSTRIHL_P,
> +    RS6000_BTI_INTSI, RS6000_BTI_V8HI, 0, 0 },
> +
> +  { FUTURE_BUILTIN_VEC_VSTRIR, FUTURE_BUILTIN_VSTRIBR,
> +    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 },
> +  { FUTURE_BUILTIN_VEC_VSTRIR, FUTURE_BUILTIN_VSTRIBR,
> +    RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
> +
> +  { FUTURE_BUILTIN_VEC_VSTRIR, FUTURE_BUILTIN_VSTRIHR,
> +    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 },
> +  { FUTURE_BUILTIN_VEC_VSTRIR, FUTURE_BUILTIN_VSTRIHR,
> +    RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 },
> +
> +  { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIBR_P,
> +    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0 },
> +  { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIBR_P,
> +    RS6000_BTI_INTSI, RS6000_BTI_V16QI, 0, 0 },
> +
> +  { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
> +    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, 0, 0 },
> +  { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
> +    RS6000_BTI_INTSI, RS6000_BTI_V8HI, 0, 0 },
> +
>    { RS6000_BUILTIN_NONE, RS6000_BUILTIN_NONE, 0, 0, 0, 0 }
>  };
>
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index c66a9ac7c3d..e35db4387dc 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -20833,6 +20833,62 @@ Perform a vector parallel bit extract operation, as if implemented by
>  the Future @code{vpextd} instruction.
>  @findex vec_pext
>
> +@smallexample
> +@exdent vector unsigned char vec_stril (vector unsigned char)
> +@exdent vector signed char vec_stril (vector signed char)
> +@exdent vector unsigned short vec_stril (vector unsigned short)
> +@exdent vector signed short vec_stril (vector signed short)
> +@end smallexample
> +Isolate the left-most non-zero elements of the incoming vector argument,
> +replacing all elements to the right of the left-most zero element
> +found within the argument with zero.  The typical implementation uses
> +the @code{vstribl} or @code{vstrihl} instruction on big-endian targets
> +and uses the @code{vstribr} or @code{vstrihr} instruction on
> +little-endian targets.
> +@findex vec_stril
> +
> +@smallexample
> +@exdent int vec_stril_p (vector unsigned char)
> +@exdent int vec_stril_p (vector signed char)
> +@exdent int short vec_stril_p (vector unsigned short)
> +@exdent int vec_stril_p (vector signed short)
> +@end smallexample
> +Return a non-zero value if and only if the argument contains a zero
> +element.  The typical implementation uses
> +the @code{vstribl.} or @code{vstrihl.} instruction on big-endian targets
> +and uses the @code{vstribr.} or @code{vstrihr.} instruction on
> +little-endian targets.  Choose this built-in to check for presence of
> +zero element if the same argument is also passed to @code{vec_stril}.
> +@findex vec_stril_p
> +
> +@smallexample
> +@exdent vector unsigned char vec_strir (vector unsigned char)
> +@exdent vector signed char vec_strir (vector signed char)
> +@exdent vector unsigned short vec_strir (vector unsigned short)
> +@exdent vector signed short vec_strir (vector signed short)
> +@end smallexample
> +Isolate the right-most non-zero elements of the incoming vector argument,
> +replacing all elements to the left of the right-most zero element
> +found within the argument with zero.  The typical implementation uses
> +the @code{vstribr} or @code{vstrihr} instruction on big-endian targets
> +and uses the @code{vstribl} or @code{vstrihl} instruction on
> +little-endian targets.
> +@findex vec_strir
> +
> +@smallexample
> +@exdent int vec_strir_p (vector unsigned char)
> +@exdent int vec_strir_p (vector signed char)
> +@exdent int short vec_strir_p (vector unsigned short)
> +@exdent int vec_strir_p (vector signed short)
> +@end smallexample
> +Return a non-zero value if and only if the argument contains a zero
> +element.  The typical implementation uses
> +the @code{vstribr.} or @code{vstrihr.} instruction on big-endian targets
> +and uses the @code{vstribl.} or @code{vstrihl.} instruction on
> +little-endian targets.  Choose this built-in to check for presence of
> +zero element if the same argument is also passed to @code{vec_strir}.
> +@findex vec_strir_p
> +
>  @node PowerPC Hardware Transactional Memory Built-in Functions
>  @subsection PowerPC Hardware Transactional Memory Built-in Functions
>  GCC provides two interfaces for accessing the Hardware Transactional
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-0.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-0.c
> new file mode 100644
> index 00000000000..d9ae5e8c39d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-0.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of unsigned char.  */
> +vector unsigned char
> +silj (vector unsigned char arg)
> +{
> +  return vec_stril (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\M} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-1.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-1.c
> new file mode 100644
> index 00000000000..a966ddc1699
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-1.c
> @@ -0,0 +1,52 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of unsigned char.  */
> +vector unsigned char
> +silj (vector unsigned char arg)
> +{
> +  return vec_stril (arg);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char input1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char expected1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char input2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char expected2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
> +  vector unsigned char input3 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char expected3 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
> +  vector unsigned char input4 =
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char expected4 =
> +    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (!vec_all_eq (silj (input1), expected1))
> +    abort ();
> +  if (!vec_all_eq (silj (input2), expected2))
> +    abort ();
> +  if (!vec_all_eq (silj (input3), expected3))
> +    abort ();
> +  if (!vec_all_eq (silj (input4), expected4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-10.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-10.c
> new file mode 100644
> index 00000000000..8afa5098fdd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-10.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-stril-11.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +vector signed char
> +doString(vector signed char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector signed char result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } }} } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } }} } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-11.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-11.c
> new file mode 100644
> index 00000000000..7e4ec69371f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-11.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +vector signed char
> +doString(vector signed char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both and should
> +     convert tail recursion to iteration with two copies of the "loop
> +     body" when compiled with -O2 or -O3.  */
> +  vector signed char result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that exactly two dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 2 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 2 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> +
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-12.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-12.c
> new file mode 100644
> index 00000000000..097503ea8ce
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-12.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-stril-13.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +vector unsigned short
> +doString(vector unsigned short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector unsigned short result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-13.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-13.c
> new file mode 100644
> index 00000000000..58e91ed5607
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-13.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +vector unsigned short
> +doString(vector unsigned short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both and should
> +     convert tail recursion to iteration with two copies of the "loop
> +     body" when compiled with -O2 or -O3.  */
> +  vector unsigned short result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that exactly two dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 2 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 2 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-14.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-14.c
> new file mode 100644
> index 00000000000..e0211900171
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-14.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-stril-15.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +vector signed short
> +doString(vector signed short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector signed short result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-15.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-15.c
> new file mode 100644
> index 00000000000..fa38112b255
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-15.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +vector signed short
> +doString(vector signed short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both and should
> +     convert tail recursion to iteration with two copies of the "loop
> +     body" when compiled with -O2 or -O3.  */
> +  vector signed short result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that exactly two dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 2 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 2 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-16.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-16.c
> new file mode 100644
> index 00000000000..2c5ea7ecc06
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-16.c
> @@ -0,0 +1,56 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-stril-17.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector unsigned char
> +doString(vector unsigned char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector unsigned char result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char composed_string [4] = {
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
> +  };
> +
> +  vector unsigned char expected0 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char expected1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
> +  vector unsigned char expected2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
> +  vector unsigned char expected3 =
> +    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-17.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-17.c
> new file mode 100644
> index 00000000000..2f82393bf9b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-17.c
> @@ -0,0 +1,54 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector unsigned char
> +doString(vector unsigned char *vp)
> +{
> +  /* Tail recursion replaced with iteration with -O2.  */
> +  vector unsigned char result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char composed_string [4] = {
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
> +  };
> +
> +  vector unsigned char expected0 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char expected1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
> +  vector unsigned char expected2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
> +  vector unsigned char expected3 =
> +    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-18.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-18.c
> new file mode 100644
> index 00000000000..37c18c1ddb3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-18.c
> @@ -0,0 +1,56 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-stril-19.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector signed char
> +doString(vector signed char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector signed char result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char composed_string [4] = {
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
> +  };
> +
> +  vector signed char expected0 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector signed char expected1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
> +  vector signed char expected2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
> +  vector signed char expected3 =
> +    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-19.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-19.c
> new file mode 100644
> index 00000000000..a0bdd64848a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-19.c
> @@ -0,0 +1,54 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector signed char
> +doString(vector signed char *vp)
> +{
> +  /* Tail recursion replaced with iteration with -O2.  */
> +  vector signed char result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char composed_string [4] = {
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
> +  };
> +
> +  vector signed char expected0 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector signed char expected1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
> +  vector signed char expected2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
> +  vector signed char expected3 =
> +    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-2.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-2.c
> new file mode 100644
> index 00000000000..baffe92e4ad
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-2.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of signed char.  */
> +vector signed char
> +silj (vector signed char arg)
> +{
> +  return vec_stril (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\M} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-20.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-20.c
> new file mode 100644
> index 00000000000..879b1aea22f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-20.c
> @@ -0,0 +1,46 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-stril-21.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector unsigned short
> +doString(vector unsigned short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector unsigned short result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short composed_string [4] = {
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 }
> +  };
> +
> +  vector unsigned short expected0 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected1 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short expected2 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short expected3 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> +
> +
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-21.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-21.c
> new file mode 100644
> index 00000000000..430ed0bbe4a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-21.c
> @@ -0,0 +1,44 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector unsigned short
> +doString(vector unsigned short *vp)
> +{
> +  /* Iteration replaces tail recursion with -O2.  */
> +  vector unsigned short result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short composed_string [4] = {
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 }
> +  };
> +
> +  vector unsigned short expected0 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected1 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short expected2 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short expected3 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> +
> +
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-22.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-22.c
> new file mode 100644
> index 00000000000..acc438852fc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-22.c
> @@ -0,0 +1,44 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-stril-23.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector signed short
> +doString(vector signed short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector signed short result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short composed_string [4] = {
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 }
> +  };
> +
> +  vector signed short expected0 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected1 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short expected2 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short expected3 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-23.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-23.c
> new file mode 100644
> index 00000000000..75d1e10607a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-23.c
> @@ -0,0 +1,42 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector signed short
> +doString(vector signed short *vp)
> +{
> +  /* Iteration replaces tail recursion with -O2.  */
> +  vector signed short result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short composed_string [4] = {
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 }
> +  };
> +
> +  vector signed short expected0 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected1 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short expected2 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short expected3 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-3.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-3.c
> new file mode 100644
> index 00000000000..50f359b6068
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-3.c
> @@ -0,0 +1,52 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed char.  */
> +vector signed char
> +silj (vector signed char arg)
> +{
> +  return vec_stril (arg);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char input1 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char expected1 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char input2 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector signed char expected2 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
> +  vector signed char input3 =
> +    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +  vector signed char expected3 =
> +    { 0x1, 0x2, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed char input4 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +  vector signed char expected4 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x0 };
> +
> +  if (!vec_all_eq (silj (input1), expected1))
> +    abort ();
> +  if (!vec_all_eq (silj (input2), expected2))
> +    abort ();
> +  if (!vec_all_eq (silj (input3), expected3))
> +    abort ();
> +  if (!vec_all_eq (silj (input4), expected4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-4.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-4.c
> new file mode 100644
> index 00000000000..35447b96b33
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-4.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of unsigned short.  */
> +vector unsigned short
> +silj (vector unsigned short arg)
> +{
> +  return vec_stril (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\M} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-5.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-5.c
> new file mode 100644
> index 00000000000..16f6bcf6400
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-5.c
> @@ -0,0 +1,45 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of unsigned short.  */
> +vector unsigned short
> +silj (vector unsigned short arg)
> +{
> +  return vec_stril (arg);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected2 =
> +    { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short expected3 =
> +    { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short expected4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +
> +  if (!vec_all_eq (silj (input1), expected1))
> +    abort ();
> +  if (!vec_all_eq (silj (input2), expected2))
> +    abort ();
> +  if (!vec_all_eq (silj (input3), expected3))
> +    abort ();
> +  if (!vec_all_eq (silj (input4), expected4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-6.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-6.c
> new file mode 100644
> index 00000000000..b40e65b80c5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-6.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of signed short.  */
> +vector signed short
> +silj (vector signed short arg)
> +{
> +  return vec_stril (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\M} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-7.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-7.c
> new file mode 100644
> index 00000000000..b6f90ce5414
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-7.c
> @@ -0,0 +1,43 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of signed short.  */
> +vector signed short
> +silj (vector signed short arg)
> +{
> +  return vec_stril (arg);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected2 =
> +    { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector signed short expected3 =
> +    { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector signed short expected4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (!vec_all_eq (silj (input1), expected1))
> +    abort ();
> +  if (!vec_all_eq (silj (input2), expected2))
> +    abort ();
> +  if (!vec_all_eq (silj (input3), expected3))
> +    abort ();
> +  if (!vec_all_eq (silj (input4), expected4))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-8.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-8.c
> new file mode 100644
> index 00000000000..9f2f3e34a99
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-8.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future -O1" } */
> +/* See vec-stril-9.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +vector unsigned char
> +doString(vector unsigned char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector unsigned char result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-9.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-9.c
> new file mode 100644
> index 00000000000..56864f4e477
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-9.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +vector unsigned char
> +doString(vector unsigned char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both and should
> +     convert tail recursion to iteration with two copies of the "loop
> +     body" when compiled with -O2 or -O3.  */
> +  vector unsigned char result = vec_stril (*vp);
> +  if (vec_stril_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that exactly two dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 2 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 2 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-0.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-0.c
> new file mode 100644
> index 00000000000..2ec2e706593
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-0.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified predicate on array of
> +   unsigned char.  */
> +int
> +silj_p (vector unsigned char arg)
> +{
> +  return vec_stril_p (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-1.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-1.c
> new file mode 100644
> index 00000000000..0ec3541d810
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-1.c
> @@ -0,0 +1,41 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified predicate on array of
> +   unsigned char.  */
> +int
> +silj_p (vector unsigned char arg)
> +{
> +  return vec_stril_p (arg);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char input1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char input2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char input3 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char input4 =
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +
> +  if (silj_p (input1))
> +    abort ();
> +  if (!silj_p (input2))
> +    abort ();
> +  if (!silj_p (input3))
> +    abort ();
> +  if (!silj_p (input4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-10.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-10.c
> new file mode 100644
> index 00000000000..3c4ce86f1fa
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-10.c
> @@ -0,0 +1,37 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (vec_stril_p (input1))
> +    abort ();
> +  if (!vec_stril_p (input2))
> +    abort ();
> +  if (!vec_stril_p (input3))
> +    abort ();
> +  if (!vec_stril_p (input4))
> +    abort ();
> +}
> +
> +/* Enforce that exactly four dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 4 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 4 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-11.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-11.c
> new file mode 100644
> index 00000000000..60f7ccd8c33
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-11.c
> @@ -0,0 +1,37 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector signed short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (vec_stril_p (input1))
> +    abort ();
> +  if (!vec_stril_p (input2))
> +    abort ();
> +  if (!vec_stril_p (input3))
> +    abort ();
> +  if (!vec_stril_p (input4))
> +    abort ();
> +}
> +
> +/* Enforce that exactly four dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 4 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 4 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-2.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-2.c
> new file mode 100644
> index 00000000000..2b0b347c127
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-2.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of signed char.  */
> +int
> +silj_p (vector signed char arg)
> +{
> +  return vec_stril_p (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-3.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-3.c
> new file mode 100644
> index 00000000000..be477398648
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-3.c
> @@ -0,0 +1,40 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed char.  */
> +int
> +silj_p (vector signed char arg)
> +{
> +  return vec_stril_p (arg);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char input1 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char input2 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector signed char input3 =
> +    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +  vector signed char input4 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +
> +  if (silj_p (input1))
> +    abort ();
> +  if (!silj_p (input2))
> +    abort ();
> +  if (!silj_p (input3))
> +    abort ();
> +  if (!silj_p (input4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-4.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-4.c
> new file mode 100644
> index 00000000000..4be60ac53da
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-4.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of unsigned short.  */
> +int
> +silj_p (vector unsigned short arg)
> +{
> +  return vec_stril_p (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-5.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-5.c
> new file mode 100644
> index 00000000000..2b520b1745c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-5.c
> @@ -0,0 +1,35 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of unsigned short.  */
> +int
> +silj_p (vector unsigned short arg)
> +{
> +  return vec_stril_p (arg);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (silj_p (input1))
> +    abort ();
> +  if (!silj_p (input2))
> +    abort ();
> +  if (!silj_p (input3))
> +    abort ();
> +  if (!silj_p (input4))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-6.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-6.c
> new file mode 100644
> index 00000000000..de719f92b00
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-6.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of signed short.  */
> +int
> +silj_p (vector signed short arg)
> +{
> +  return vec_stril_p (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-7.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-7.c
> new file mode 100644
> index 00000000000..22f394fa6e0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-7.c
> @@ -0,0 +1,36 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate left-justified on array of signed short.  */
> +int
> +silj_p (vector signed short arg)
> +{
> +  return vec_stril_p (arg);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector signed short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (silj_p (input1))
> +    abort ();
> +  if (!silj_p (input2))
> +    abort ();
> +  if (!silj_p (input3))
> +    abort ();
> +  if (!silj_p (input4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-8.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-8.c
> new file mode 100644
> index 00000000000..daf322070ef
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-8.c
> @@ -0,0 +1,42 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char input1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char input2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char input3 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char input4 =
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +
> +  if (vec_stril_p (input1))
> +    abort ();
> +  if (!vec_stril_p (input2))
> +    abort ();
> +  if (!vec_stril_p (input3))
> +    abort ();
> +  if (!vec_stril_p (input4))
> +    abort ();
> +
> +}
> +
> +/* Enforce that exactly four dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 4 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 4 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-9.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-9.c
> new file mode 100644
> index 00000000000..85e8ea750fd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-9.c
> @@ -0,0 +1,42 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char input1 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char input2 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector signed char input3 =
> +    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +  vector signed char input4 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +
> +  if (vec_stril_p (input1))
> +    abort ();
> +  if (!vec_stril_p (input2))
> +    abort ();
> +  if (!vec_stril_p (input3))
> +    abort ();
> +  if (!vec_stril_p (input4))
> +    abort ();
> +
> +}
> +
> +/* Enforce that exactly four dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 4 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 4 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-0.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-0.c
> new file mode 100644
> index 00000000000..6e9e944ca6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-0.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of unsigned char.  */
> +vector unsigned char
> +sirj (vector unsigned char arg)
> +{
> +  return vec_strir (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\M} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-1.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-1.c
> new file mode 100644
> index 00000000000..8bf326afbc7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-1.c
> @@ -0,0 +1,52 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of unsigned char.  */
> +vector unsigned char
> +sirj (vector unsigned char arg)
> +{
> +  return vec_strir (arg);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char input1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char expected1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char input2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +  vector unsigned char input3 =
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +  vector unsigned char input4 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char expected4 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +
> +  if (!vec_all_eq (sirj (input1), expected1))
> +    abort ();
> +  if (!vec_all_eq (sirj (input2), expected2))
> +    abort ();
> +  if (!vec_all_eq (sirj (input3), expected3))
> +    abort ();
> +  if (!vec_all_eq (sirj (input4), expected4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-10.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-10.c
> new file mode 100644
> index 00000000000..b129168510f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-10.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-strir-11.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +vector signed char
> +doString(vector signed char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector signed char result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-11.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-11.c
> new file mode 100644
> index 00000000000..12d751a62f2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-11.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +vector signed char
> +doString(vector signed char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both and should
> +     convert tail recursion to iteration with two copies of the "loop
> +     body" when compiled with -O2 or -O3.  */
> +  vector signed char result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that exactly two dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 2 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 2 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-12.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-12.c
> new file mode 100644
> index 00000000000..2ee44dabfd9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-12.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-strir-13.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +vector unsigned short
> +doString(vector unsigned short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector unsigned short result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> +
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-13.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-13.c
> new file mode 100644
> index 00000000000..91ca59bb826
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-13.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +vector unsigned short
> +doString(vector unsigned short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both and should
> +     convert tail recursion to iteration with two copies of the "loop
> +     body" when compiled with -O2 or -O3.  */
> +  vector unsigned short result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that exactly two dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 2 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 2 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> +
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-14.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-14.c
> new file mode 100644
> index 00000000000..5f7d4341992
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-14.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-strir-15.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +vector signed short
> +doString(vector signed short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector signed short result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-15.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-15.c
> new file mode 100644
> index 00000000000..0a3d8d02ac1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-15.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +vector signed short
> +doString(vector signed short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both and should
> +     convert tail recursion to iteration with two copies of the "loop
> +     body" when compiled with -O2 or -O3.  */
> +  vector signed short result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that exactly two dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 2 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 2 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-16.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-16.c
> new file mode 100644
> index 00000000000..2418b2f40fe
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-16.c
> @@ -0,0 +1,56 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-strir-17.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector unsigned char
> +doString(vector unsigned char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector unsigned char result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char composed_string [4] = {
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
> +  };
> +
> +  vector unsigned char expected0 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char expected1 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +  vector unsigned char expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-17.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-17.c
> new file mode 100644
> index 00000000000..1404342d4b4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-17.c
> @@ -0,0 +1,54 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector unsigned char
> +doString(vector unsigned char *vp)
> +{
> +  /* Tail recursion replaced with iteration with -O2.  */
> +  vector unsigned char result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char composed_string [4] = {
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
> +  };
> +
> +  vector unsigned char expected0 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char expected1 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +  vector unsigned char expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-18.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-18.c
> new file mode 100644
> index 00000000000..ab9592f49ee
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-18.c
> @@ -0,0 +1,56 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-strir-19.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector signed char
> +doString(vector signed char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector signed char result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char composed_string [4] = {
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 },
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 },
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 }
> +  };
> +
> +  vector signed char expected0 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char expected1 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +  vector signed char expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
> +  vector signed char expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-19.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-19.c
> new file mode 100644
> index 00000000000..b0f78df40b3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-19.c
> @@ -0,0 +1,54 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector signed char
> +doString(vector signed char *vp)
> +{
> +  /* Tail recursion replaced with iteration with -O2.  */
> +  vector signed char result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char composed_string [4] = {
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 },
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
> +    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 },
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 }
> +  };
> +
> +  vector signed char expected0 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char expected1 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +  vector signed char expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
> +  vector signed char expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-2.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-2.c
> new file mode 100644
> index 00000000000..a7efde73d56
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-2.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed char.  */
> +vector signed char
> +sirj (vector signed char arg)
> +{
> +  return vec_strir (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\M} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-20.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-20.c
> new file mode 100644
> index 00000000000..8ac643e1dbf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-20.c
> @@ -0,0 +1,48 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-strir-21.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector unsigned short
> +doString(vector unsigned short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector unsigned short result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short composed_string [4] = {
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0x0, 0xd, 0xe }
> +  };
> +
> +  vector unsigned short expected0 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected1 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-21.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-21.c
> new file mode 100644
> index 00000000000..47bf0db8946
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-21.c
> @@ -0,0 +1,46 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector unsigned short
> +doString(vector unsigned short *vp)
> +{
> +  /* Iteration replaces tail recursion with -O2.  */
> +  vector unsigned short result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short composed_string [4] = {
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0x0, 0xd, 0xe }
> +  };
> +
> +  vector unsigned short expected0 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected1 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-22.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-22.c
> new file mode 100644
> index 00000000000..48a57983860
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-22.c
> @@ -0,0 +1,48 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-strir-23.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector signed short
> +doString(vector signed short *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector signed short result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short composed_string [4] = {
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0x0, 0xd, 0xe }
> +  };
> +
> +  vector signed short expected0 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected1 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-23.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-23.c
> new file mode 100644
> index 00000000000..b3b143f3b68
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-23.c
> @@ -0,0 +1,46 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +vector signed short
> +doString(vector signed short *vp)
> +{
> +  /* Iteration replaces tail recursion with -O2.  */
> +  vector signed short result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short composed_string [4] = {
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0x0, 0xd, 0xe }
> +  };
> +
> +  vector signed short expected0 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected1 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe };
> +
> +  if (!vec_all_eq (doString (&composed_string[0]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[1]), expected1))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[2]), expected2))
> +    abort ();
> +  if (!vec_all_eq (doString (&composed_string[3]), expected3))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-3.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-3.c
> new file mode 100644
> index 00000000000..25db69c52a6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-3.c
> @@ -0,0 +1,52 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed char.  */
> +vector signed char
> +sirj (vector signed char arg)
> +{
> +  return vec_strir (arg);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char input1 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char expected1 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char input2 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector signed char expected2 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
> +  vector signed char input3 =
> +    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +  vector signed char expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
> +  vector signed char input4 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +  vector signed char expected4 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
> +
> +  if (!vec_all_eq (sirj (input1), expected1))
> +    abort ();
> +  if (!vec_all_eq (sirj (input2), expected2))
> +    abort ();
> +  if (!vec_all_eq (sirj (input3), expected3))
> +    abort ();
> +  if (!vec_all_eq (sirj (input4), expected4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-4.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-4.c
> new file mode 100644
> index 00000000000..85a3f56d24f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-4.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of unsigned short.  */
> +vector unsigned short
> +sirj (vector unsigned short arg)
> +{
> +  return vec_strir (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\M} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-5.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-5.c
> new file mode 100644
> index 00000000000..7047039deab
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-5.c
> @@ -0,0 +1,44 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of unsigned short.  */
> +vector unsigned short
> +sirj (vector unsigned short arg)
> +{
> +  return vec_strir (arg);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected2 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector unsigned short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short expected4 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (!vec_all_eq (sirj (input1), expected1))
> +    abort ();
> +  if (!vec_all_eq (sirj (input2), expected2))
> +    abort ();
> +  if (!vec_all_eq (sirj (input3), expected3))
> +    abort ();
> +  if (!vec_all_eq (sirj (input4), expected4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-6.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-6.c
> new file mode 100644
> index 00000000000..56e81812120
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-6.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed short.  */
> +vector signed short
> +sirj (vector signed short arg)
> +{
> +  return vec_strir (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\M} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-7.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-7.c
> new file mode 100644
> index 00000000000..fddee218759
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-7.c
> @@ -0,0 +1,44 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed short.  */
> +vector signed short
> +sirj (vector signed short arg)
> +{
> +  return vec_strir (arg);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short expected2 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector signed short expected3 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +  vector signed short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector signed short expected4 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (!vec_all_eq (sirj (input1), expected1))
> +    abort ();
> +  if (!vec_all_eq (sirj (input2), expected2))
> +    abort ();
> +  if (!vec_all_eq (sirj (input3), expected3))
> +    abort ();
> +  if (!vec_all_eq (sirj (input4), expected4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-8.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-8.c
> new file mode 100644
> index 00000000000..211cdeb8e50
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-8.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -mdejagnu-cpu=future" } */
> +/* See vec-strir-9.c for the same test with -O2 optimization.  */
> +
> +#include <altivec.h>
> +
> +vector unsigned char
> +doString(vector unsigned char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both with -O1.  */
> +  vector unsigned char result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-9.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-9.c
> new file mode 100644
> index 00000000000..b95711c71f4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-9.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +vector unsigned char
> +doString(vector unsigned char *vp)
> +{
> +  /* Though two built-in functions are called, the implementation
> +     should use a single instruction to implement both and should
> +     convert tail recursion to iteration with two copies of the "loop
> +     body" when compiled with -O2 or -O3.  */
> +  vector unsigned char result = vec_strir (*vp);
> +  if (vec_strir_p (*vp))
> +    return result;
> +  else
> +    return doString (vp + 1);
> +}
> +
> +/* Enforce that exactly two dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 2 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 2 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-0.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-0.c
> new file mode 100644
> index 00000000000..f94703dfe77
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-0.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of unsigned char.  */
> +int
> +sirj_p (vector unsigned char arg)
> +{
> +  return vec_strir_p (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-1.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-1.c
> new file mode 100644
> index 00000000000..ce527a7c530
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-1.c
> @@ -0,0 +1,39 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of unsigned char.  */
> +int
> +sirj_p (vector unsigned char arg)
> +{
> +  return vec_strir_p (arg);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char input1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char input2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char input3 =
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char input4 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +
> +  if (sirj_p (input1))
> +    abort ();
> +  if (!sirj_p (input2))
> +    abort ();
> +  if (!sirj_p (input3))
> +    abort ();
> +  if (!sirj_p (input4))
> +    abort ();
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-10.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-10.c
> new file mode 100644
> index 00000000000..5a4c63940e1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-10.c
> @@ -0,0 +1,46 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected2 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short expected3 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short expected4 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (vec_strir_p (input1))
> +    abort ();
> +  if (!vec_strir_p (input2))
> +    abort ();
> +  if (!vec_strir_p (input3))
> +    abort ();
> +  if (!vec_strir_p (input4))
> +    abort ();
> +
> +}
> +
> +/* Enforce that exactly four dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 4 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 4 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-11.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-11.c
> new file mode 100644
> index 00000000000..786b2798a11
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-11.c
> @@ -0,0 +1,38 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector signed short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (vec_strir_p (input1))
> +    abort ();
> +  if (!vec_strir_p (input2))
> +    abort ();
> +  if (!vec_strir_p (input3))
> +    abort ();
> +  if (!vec_strir_p (input4))
> +    abort ();
> +
> +}
> +
> +/* Enforce that exactly four dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 4 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 4 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-2.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-2.c
> new file mode 100644
> index 00000000000..becb3220567
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-2.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed char.  */
> +int
> +sirj_p (vector signed char arg)
> +{
> +  return vec_strir_p (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-3.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-3.c
> new file mode 100644
> index 00000000000..42777702b3a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-3.c
> @@ -0,0 +1,40 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed char.  */
> +int
> +sirj_p (vector signed char arg)
> +{
> +  return vec_strir_p (arg);
> +}
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char input1 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char input2 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector signed char input3 =
> +    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +  vector signed char input4 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +
> +  if (sirj_p (input1))
> +    abort ();
> +  if (!sirj_p (input2))
> +    abort ();
> +  if (!sirj_p (input3))
> +    abort ();
> +  if (!sirj_p (input4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-4.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-4.c
> new file mode 100644
> index 00000000000..f9b214caa29
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-4.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of unsigned short.  */
> +int
> +sirj_p (vector unsigned short arg)
> +{
> +  return vec_strir_p (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-5.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-5.c
> new file mode 100644
> index 00000000000..337f2d08875
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-5.c
> @@ -0,0 +1,44 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of unsigned short.  */
> +int
> +sirj_p (vector unsigned short arg)
> +{
> +  return vec_strir_p (arg);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector unsigned short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short expected2 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector unsigned short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short expected3 =
> +    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector unsigned short expected4 =
> +    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
> +
> +  if (sirj_p (input1))
> +    abort ();
> +  if (!sirj_p (input2))
> +    abort ();
> +  if (!sirj_p (input3))
> +    abort ();
> +  if (!sirj_p (input4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-6.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-6.c
> new file mode 100644
> index 00000000000..d1b79ee1250
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-6.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed short.  */
> +int
> +sirj_p (vector signed short arg)
> +{
> +  return vec_strir_p (arg);
> +}
> +
> +/* Enforce that a single dot-form instruction which is properly biased
> +   for the target's endianness implements this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-7.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-7.c
> new file mode 100644
> index 00000000000..a6794d29fd1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-7.c
> @@ -0,0 +1,36 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_future_hw } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +/* Vector string isolate right-justified on array of signed short.  */
> +int
> +sirj_p (vector signed short arg)
> +{
> +  return vec_strir_p (arg);
> +}
> +
> +int main (int argc, short *argv [])
> +{
> +  vector signed short input1 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input2 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
> +  vector signed short input3 =
> +    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +  vector signed short input4 =
> +    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
> +
> +  if (sirj_p (input1))
> +    abort ();
> +  if (!sirj_p (input2))
> +    abort ();
> +  if (!sirj_p (input3))
> +    abort ();
> +  if (!sirj_p (input4))
> +    abort ();
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-8.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-8.c
> new file mode 100644
> index 00000000000..f25528c7b46
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-8.c
> @@ -0,0 +1,43 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +int main (int argc, char *argv [])
> +{
> +  vector unsigned char input1 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
> +  vector unsigned char input2 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char input3 =
> +    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector unsigned char input4 =
> +    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +
> +  if (!vec_strir_p (input1))
> +    abort ();
> +  if (!vec_strir_p (input2))
> +    abort ();
> +  if (!vec_strir_p (input3))
> +    abort ();
> +  if (!vec_strir_p (input4))
> +    abort ();
> +}
> +
> +/* Enforce that exactly four dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 4 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 4 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
> +
> +
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-9.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-9.c
> new file mode 100644
> index 00000000000..42831a4cbed
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-9.c
> @@ -0,0 +1,42 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future" } */
> +
> +#include <altivec.h>
> +
> +extern void abort (void);
> +
> +int main (int argc, char *argv [])
> +{
> +  vector signed char input1 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
> +  vector signed char input2 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
> +  vector signed char input3 =
> +    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +  vector signed char input4 =
> +    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
> +      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
> +
> +  if (vec_strir_p (input1))
> +    abort ();
> +  if (!vec_strir_p (input2))
> +    abort ();
> +  if (!vec_strir_p (input3))
> +    abort ();
> +  if (!vec_strir_p (input4))
> +    abort ();
> +
> +}
> +
> +/* Enforce that exactly four dot-form instructions which are properly biased
> +   for the target's endianness implement this built-in.  */
> +
> +/* { dg-final { scan-assembler-times {\mvstribr\.} 4 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\.} 4 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
> +/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */

> --
> 2.17.1
>
Segher Boessenkool May 12, 2020, 9:54 a.m. UTC | #2
Hi!

Looks fine to me...  Just the same generic things as before, things we
can improve later, not even limited to this series:

On Sat, May 09, 2020 at 08:16:26AM -0500, Bill Schmidt wrote:
> 	* config/rs6000/altivec.md (UNSPEC_VSTRIR): New constant.
> 	(UNSPEC_VSTRIL): Likewise.

Names for these could perhaps be better.  Or maybe not, they are short
now, there's something to say for that as well :-)

> 	(vstrir_<mode>): New expansion.
> 	(vstrir_code_<mode>): New insn.

Could you make this vstrir<mode> and vstrir<mode>_internal, like the
rest?

> 	(vstrir_p_<mode>): New expansion.
> 	(vstrir_p_code_<mode>): New insn.

But, not sure what to do with those.  "Something to improve later" then
I guess, for all of it :-)

> +(define_expand "vstrir_<mode>"
> +  [(set (match_operand:VIshort 0 "altivec_register_operand")
> +	(unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")]
> +			UNSPEC_VSTRIR))]
> +  "TARGET_FUTURE"
> +{
> +  if (BYTES_BIG_ENDIAN)
> +    emit_insn (gen_vstrir_code_<mode> (operands[0], operands[1]));
> +  else
> +    emit_insn (gen_vstril_code_<mode> (operands[0], operands[1]));
> +  DONE;
> +})

So the reason this pattern is special at all is that left and right are
swapped for LE.  Maybe that could/should be done in the code for the
builtin, instead?

> +;; This expands into same code as vstrir_<mode> followed by condition logic
> +;; so that a single vstribr. or vstrihr. or vstribl. or vstrihl. instruction
> +;; can, for example, satisfy the needs of a vec_strir () function paired
> +;; with a vec_strir_p () function if both take the same incoming arguments.
> +(define_expand "vstrir_p_<mode>"
> +  [(match_operand:SI 0 "gpc_reg_operand")
> +   (match_operand:VIshort 1 "altivec_register_operand")]
> +  "TARGET_FUTURE"
> +{
> +  rtx scratch = gen_reg_rtx (<MODE>mode);
> +  if (BYTES_BIG_ENDIAN)
> +    emit_insn (gen_vstrir_p_code_<mode> (scratch, operands[1]));
> +  else
> +    emit_insn (gen_vstril_p_code_<mode> (scratch, operands[1]));
> +  emit_insn (gen_cr6_test_for_zero (operands[0]));
> +  DONE;
> +})

And the code for the builtin can do this then, as well.

Not sure how easy that is to fit in with the current code, or after your
work on it.  Either way, it looks fine to me :-)


Segher
Li, Pan2 via Gcc-patches May 12, 2020, 1:50 p.m. UTC | #3
On 5/12/20 4:54 AM, Segher Boessenkool wrote:
> Hi!
>
> Looks fine to me...  Just the same generic things as before, things we
> can improve later, not even limited to this series:
>
> On Sat, May 09, 2020 at 08:16:26AM -0500, Bill Schmidt wrote:
>> 	* config/rs6000/altivec.md (UNSPEC_VSTRIR): New constant.
>> 	(UNSPEC_VSTRIL): Likewise.
> Names for these could perhaps be better.  Or maybe not, they are short
> now, there's something to say for that as well :-)
>
>> 	(vstrir_<mode>): New expansion.
>> 	(vstrir_code_<mode>): New insn.
> Could you make this vstrir<mode> and vstrir<mode>_internal, like the
> rest?
>
>> 	(vstrir_p_<mode>): New expansion.
>> 	(vstrir_p_code_<mode>): New insn.
> But, not sure what to do with those.  "Something to improve later" then
> I guess, for all of it :-)
>
>> +(define_expand "vstrir_<mode>"
>> +  [(set (match_operand:VIshort 0 "altivec_register_operand")
>> +	(unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")]
>> +			UNSPEC_VSTRIR))]
>> +  "TARGET_FUTURE"
>> +{
>> +  if (BYTES_BIG_ENDIAN)
>> +    emit_insn (gen_vstrir_code_<mode> (operands[0], operands[1]));
>> +  else
>> +    emit_insn (gen_vstril_code_<mode> (operands[0], operands[1]));
>> +  DONE;
>> +})
> So the reason this pattern is special at all is that left and right are
> swapped for LE.  Maybe that could/should be done in the code for the
> builtin, instead?
>
>> +;; This expands into same code as vstrir_<mode> followed by condition logic
>> +;; so that a single vstribr. or vstrihr. or vstribl. or vstrihl. instruction
>> +;; can, for example, satisfy the needs of a vec_strir () function paired
>> +;; with a vec_strir_p () function if both take the same incoming arguments.
>> +(define_expand "vstrir_p_<mode>"
>> +  [(match_operand:SI 0 "gpc_reg_operand")
>> +   (match_operand:VIshort 1 "altivec_register_operand")]
>> +  "TARGET_FUTURE"
>> +{
>> +  rtx scratch = gen_reg_rtx (<MODE>mode);
>> +  if (BYTES_BIG_ENDIAN)
>> +    emit_insn (gen_vstrir_p_code_<mode> (scratch, operands[1]));
>> +  else
>> +    emit_insn (gen_vstril_p_code_<mode> (scratch, operands[1]));
>> +  emit_insn (gen_cr6_test_for_zero (operands[0]));
>> +  DONE;
>> +})
> And the code for the builtin can do this then, as well.
>
> Not sure how easy that is to fit in with the current code, or after your
> work on it.  Either way, it looks fine to me :-)

Thanks, lots of good cleanups here.  I've committed this patch, but will 
open an internal issue to track the cleanups from this series of patches 
and try to get them cleaned up later in the release. Thanks for the review!

Bill
>
>
> Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index addf7d0db52..b29413deb6d 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -700,6 +700,12 @@  __altivec_scalar_pred(vec_any_nle,
 #define vec_clrl(a, b)	__builtin_vec_clrl (a, b)
 #define vec_clrr(a, b)	__builtin_vec_clrr (a, b)
 #define vec_ternarylogic(a, b, c, d)	__builtin_vec_xxeval (a, b, c, d)
+
+#define vec_strir(a)	__builtin_vec_strir (a)
+#define vec_stril(a)	__builtin_vec_stril (a)
+
+#define vec_strir_p(a)	__builtin_vec_strir_p (a)
+#define vec_stril_p(a)	__builtin_vec_stril_p (a)
 #endif
 
 #endif /* _ALTIVEC_H */
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 7382d7c4b44..1c0bbb7527a 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -169,6 +169,8 @@  (define_c_enum "unspec"
    UNSPEC_VCLRLB
    UNSPEC_VCLRRB
    UNSPEC_XXEVAL
+   UNSPEC_VSTRIR
+   UNSPEC_VSTRIL
 ])
 
 (define_c_enum "unspecv"
@@ -781,6 +783,109 @@  (define_expand "mulv8hi3"
   DONE;
 })
 
+(define_expand "vstrir_<mode>"
+  [(set (match_operand:VIshort 0 "altivec_register_operand")
+	(unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")]
+			UNSPEC_VSTRIR))]
+  "TARGET_FUTURE"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vstrir_code_<mode> (operands[0], operands[1]));
+  else
+    emit_insn (gen_vstril_code_<mode> (operands[0], operands[1]));
+  DONE;
+})
+
+(define_insn "vstrir_code_<mode>"
+  [(set (match_operand:VIshort 0 "altivec_register_operand" "=v")
+	(unspec:VIshort
+	   [(match_operand:VIshort 1 "altivec_register_operand" "v")]
+	   UNSPEC_VSTRIR))]
+  "TARGET_FUTURE"
+  "vstri<wd>r %0,%1"
+  [(set_attr "type" "vecsimple")])
+
+;; This expands into same code as vstrir_<mode> followed by condition logic
+;; so that a single vstribr. or vstrihr. or vstribl. or vstrihl. instruction
+;; can, for example, satisfy the needs of a vec_strir () function paired
+;; with a vec_strir_p () function if both take the same incoming arguments.
+(define_expand "vstrir_p_<mode>"
+  [(match_operand:SI 0 "gpc_reg_operand")
+   (match_operand:VIshort 1 "altivec_register_operand")]
+  "TARGET_FUTURE"
+{
+  rtx scratch = gen_reg_rtx (<MODE>mode);
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vstrir_p_code_<mode> (scratch, operands[1]));
+  else
+    emit_insn (gen_vstril_p_code_<mode> (scratch, operands[1]));
+  emit_insn (gen_cr6_test_for_zero (operands[0]));
+  DONE;
+})
+
+(define_insn "vstrir_p_code_<mode>"
+  [(set (match_operand:VIshort 0 "altivec_register_operand" "=v")
+	(unspec:VIshort
+	   [(match_operand:VIshort 1 "altivec_register_operand" "v")]
+	   UNSPEC_VSTRIR))
+   (set (reg:CC CR6_REGNO)
+	(unspec:CC [(match_dup 1)]
+		   UNSPEC_VSTRIR))]
+  "TARGET_FUTURE"
+  "vstri<wd>r. %0,%1"
+  [(set_attr "type" "vecsimple")])
+
+(define_expand "vstril_<mode>"
+  [(set (match_operand:VIshort 0 "altivec_register_operand")
+	(unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")]
+			UNSPEC_VSTRIR))]
+  "TARGET_FUTURE"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vstril_code_<mode> (operands[0], operands[1]));
+  else
+    emit_insn (gen_vstrir_code_<mode> (operands[0], operands[1]));
+  DONE;
+})
+
+(define_insn "vstril_code_<mode>"
+  [(set (match_operand:VIshort 0 "altivec_register_operand" "=v")
+	(unspec:VIshort
+	   [(match_operand:VIshort 1 "altivec_register_operand" "v")]
+	   UNSPEC_VSTRIL))]
+  "TARGET_FUTURE"
+  "vstri<wd>l %0,%1"
+  [(set_attr "type" "vecsimple")])
+
+;; This expands into same code as vstril_<mode> followed by condition logic
+;; so that a single vstribr. or vstrihr. or vstribl. or vstrihl. instruction
+;; can, for example, satisfy the needs of a vec_stril () function paired
+;; with a vec_stril_p () function if both take the same incoming arguments.
+(define_expand "vstril_p_<mode>"
+  [(match_operand:SI 0 "gpc_reg_operand")
+   (match_operand:VIshort 1 "altivec_register_operand")]
+  "TARGET_FUTURE"
+{
+  rtx scratch = gen_reg_rtx (<MODE>mode);
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vstril_p_code_<mode> (scratch, operands[1]));
+  else
+    emit_insn (gen_vstrir_p_code_<mode> (scratch, operands[1]));
+  emit_insn (gen_cr6_test_for_zero (operands[0]));
+  DONE;
+})
+
+(define_insn "vstril_p_code_<mode>"
+  [(set (match_operand:VIshort 0 "altivec_register_operand" "=v")
+	(unspec:VIshort
+	   [(match_operand:VIshort 1 "altivec_register_operand" "v")]
+	   UNSPEC_VSTRIL))
+   (set (reg:CC CR6_REGNO)
+	(unspec:CC [(match_dup 1)]
+		   UNSPEC_VSTRIR))]
+  "TARGET_FUTURE"
+  "vstri<wd>l. %0,%1"
+  [(set_attr "type" "vecsimple")])
 
 ;; Fused multiply subtract 
 (define_insn "*altivec_vnmsubfp"
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 7ff8db5dccc..1f86293d0e2 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -2612,12 +2612,27 @@  BU_FUTURE_V_2 (VPEXTD, "vpextd", CONST, vpextd)
 BU_FUTURE_V_2 (VGNB, "vgnb", CONST, vgnb)
 BU_FUTURE_V_4 (XXEVAL, "xxeval", CONST, xxeval)
 
+BU_FUTURE_V_1 (VSTRIBR, "vstribr", CONST, vstrir_v16qi)
+BU_FUTURE_V_1 (VSTRIHR, "vstrihr", CONST, vstrir_v8hi)
+BU_FUTURE_V_1 (VSTRIBL, "vstribl", CONST, vstril_v16qi)
+BU_FUTURE_V_1 (VSTRIHL, "vstrihl", CONST, vstril_v8hi)
+
+BU_FUTURE_V_1 (VSTRIBR_P, "vstribr_p", CONST, vstrir_p_v16qi)
+BU_FUTURE_V_1 (VSTRIHR_P, "vstrihr_p", CONST, vstrir_p_v8hi)
+BU_FUTURE_V_1 (VSTRIBL_P, "vstribl_p", CONST, vstril_p_v16qi)
+BU_FUTURE_V_1 (VSTRIHL_P, "vstrihl_p", CONST, vstril_p_v8hi)
+
 /* Future architecture overloaded vector built-ins.  */
 BU_FUTURE_OVERLOAD_2 (CLRL, "clrl")
 BU_FUTURE_OVERLOAD_2 (CLRR, "clrr")
 BU_FUTURE_OVERLOAD_2 (GNB, "gnb")
 BU_FUTURE_OVERLOAD_4 (XXEVAL, "xxeval")
 
+BU_FUTURE_OVERLOAD_1 (VSTRIR, "strir")
+BU_FUTURE_OVERLOAD_1 (VSTRIL, "stril")
+
+BU_FUTURE_OVERLOAD_1 (VSTRIR_P, "strir_p")
+BU_FUTURE_OVERLOAD_1 (VSTRIL_P, "stril_p")
 
 /* 1 argument crypto functions.  */
 BU_CRYPTO_1 (VSBOX,		"vsbox",	  CONST, crypto_vsbox_v2di)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 9b9562ce4c3..64a9ba2818d 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -5551,6 +5551,46 @@  const struct altivec_builtin_types altivec_overloaded_builtins[] = {
     RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI,
     RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI },
 
+  { FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIBL,
+    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 },
+  { FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIBL,
+    RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
+
+  { FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIHL,
+    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 },
+  { FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIHL,
+    RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 },
+
+  { FUTURE_BUILTIN_VEC_VSTRIL_P, FUTURE_BUILTIN_VSTRIBL_P,
+    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0 },
+  { FUTURE_BUILTIN_VEC_VSTRIL_P, FUTURE_BUILTIN_VSTRIBL_P,
+    RS6000_BTI_INTSI, RS6000_BTI_V16QI, 0, 0 },
+
+  { FUTURE_BUILTIN_VEC_VSTRIL_P, FUTURE_BUILTIN_VSTRIHL_P,
+    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, 0, 0 },
+  { FUTURE_BUILTIN_VEC_VSTRIL_P, FUTURE_BUILTIN_VSTRIHL_P,
+    RS6000_BTI_INTSI, RS6000_BTI_V8HI, 0, 0 },
+
+  { FUTURE_BUILTIN_VEC_VSTRIR, FUTURE_BUILTIN_VSTRIBR,
+    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 },
+  { FUTURE_BUILTIN_VEC_VSTRIR, FUTURE_BUILTIN_VSTRIBR,
+    RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
+
+  { FUTURE_BUILTIN_VEC_VSTRIR, FUTURE_BUILTIN_VSTRIHR,
+    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 },
+  { FUTURE_BUILTIN_VEC_VSTRIR, FUTURE_BUILTIN_VSTRIHR,
+    RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 },
+
+  { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIBR_P,
+    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0 },
+  { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIBR_P,
+    RS6000_BTI_INTSI, RS6000_BTI_V16QI, 0, 0 },
+
+  { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
+    RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, 0, 0 },
+  { FUTURE_BUILTIN_VEC_VSTRIR_P, FUTURE_BUILTIN_VSTRIHR_P,
+    RS6000_BTI_INTSI, RS6000_BTI_V8HI, 0, 0 },
+
   { RS6000_BUILTIN_NONE, RS6000_BUILTIN_NONE, 0, 0, 0, 0 }
 };
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c66a9ac7c3d..e35db4387dc 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -20833,6 +20833,62 @@  Perform a vector parallel bit extract operation, as if implemented by
 the Future @code{vpextd} instruction.
 @findex vec_pext
 
+@smallexample
+@exdent vector unsigned char vec_stril (vector unsigned char)
+@exdent vector signed char vec_stril (vector signed char)
+@exdent vector unsigned short vec_stril (vector unsigned short)
+@exdent vector signed short vec_stril (vector signed short)
+@end smallexample
+Isolate the left-most non-zero elements of the incoming vector argument,
+replacing all elements to the right of the left-most zero element
+found within the argument with zero.  The typical implementation uses
+the @code{vstribl} or @code{vstrihl} instruction on big-endian targets
+and uses the @code{vstribr} or @code{vstrihr} instruction on
+little-endian targets.
+@findex vec_stril
+
+@smallexample
+@exdent int vec_stril_p (vector unsigned char)
+@exdent int vec_stril_p (vector signed char)
+@exdent int short vec_stril_p (vector unsigned short)
+@exdent int vec_stril_p (vector signed short)
+@end smallexample
+Return a non-zero value if and only if the argument contains a zero
+element.  The typical implementation uses
+the @code{vstribl.} or @code{vstrihl.} instruction on big-endian targets
+and uses the @code{vstribr.} or @code{vstrihr.} instruction on
+little-endian targets.  Choose this built-in to check for presence of
+zero element if the same argument is also passed to @code{vec_stril}.
+@findex vec_stril_p
+
+@smallexample
+@exdent vector unsigned char vec_strir (vector unsigned char)
+@exdent vector signed char vec_strir (vector signed char)
+@exdent vector unsigned short vec_strir (vector unsigned short)
+@exdent vector signed short vec_strir (vector signed short)
+@end smallexample
+Isolate the right-most non-zero elements of the incoming vector argument,
+replacing all elements to the left of the right-most zero element
+found within the argument with zero.  The typical implementation uses
+the @code{vstribr} or @code{vstrihr} instruction on big-endian targets
+and uses the @code{vstribl} or @code{vstrihl} instruction on
+little-endian targets.
+@findex vec_strir
+
+@smallexample
+@exdent int vec_strir_p (vector unsigned char)
+@exdent int vec_strir_p (vector signed char)
+@exdent int short vec_strir_p (vector unsigned short)
+@exdent int vec_strir_p (vector signed short)
+@end smallexample
+Return a non-zero value if and only if the argument contains a zero
+element.  The typical implementation uses
+the @code{vstribr.} or @code{vstrihr.} instruction on big-endian targets
+and uses the @code{vstribl.} or @code{vstrihl.} instruction on
+little-endian targets.  Choose this built-in to check for presence of
+zero element if the same argument is also passed to @code{vec_strir}.
+@findex vec_strir_p
+
 @node PowerPC Hardware Transactional Memory Built-in Functions
 @subsection PowerPC Hardware Transactional Memory Built-in Functions
 GCC provides two interfaces for accessing the Hardware Transactional
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-0.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-0.c
new file mode 100644
index 00000000000..d9ae5e8c39d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-0.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of unsigned char.  */
+vector unsigned char
+silj (vector unsigned char arg)
+{
+  return vec_stril (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\M} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-1.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-1.c
new file mode 100644
index 00000000000..a966ddc1699
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-1.c
@@ -0,0 +1,52 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of unsigned char.  */
+vector unsigned char
+silj (vector unsigned char arg)
+{
+  return vec_stril (arg);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char input1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char expected1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char input2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char expected2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
+  vector unsigned char input3 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char expected3 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
+  vector unsigned char input4 =
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char expected4 =
+    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (!vec_all_eq (silj (input1), expected1))
+    abort ();
+  if (!vec_all_eq (silj (input2), expected2))
+    abort ();
+  if (!vec_all_eq (silj (input3), expected3))
+    abort ();
+  if (!vec_all_eq (silj (input4), expected4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-10.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-10.c
new file mode 100644
index 00000000000..8afa5098fdd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-10.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-stril-11.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+vector signed char
+doString(vector signed char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector signed char result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } }} } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } }} } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-11.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-11.c
new file mode 100644
index 00000000000..7e4ec69371f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-11.c
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector signed char
+doString(vector signed char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both and should
+     convert tail recursion to iteration with two copies of the "loop
+     body" when compiled with -O2 or -O3.  */
+  vector signed char result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that exactly two dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\.} 2 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\.} 2 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-12.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-12.c
new file mode 100644
index 00000000000..097503ea8ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-12.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-stril-13.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+vector unsigned short
+doString(vector unsigned short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector unsigned short result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-13.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-13.c
new file mode 100644
index 00000000000..58e91ed5607
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-13.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector unsigned short
+doString(vector unsigned short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both and should
+     convert tail recursion to iteration with two copies of the "loop
+     body" when compiled with -O2 or -O3.  */
+  vector unsigned short result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that exactly two dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 2 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 2 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-14.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-14.c
new file mode 100644
index 00000000000..e0211900171
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-14.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-stril-15.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+vector signed short
+doString(vector signed short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector signed short result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-15.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-15.c
new file mode 100644
index 00000000000..fa38112b255
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-15.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector signed short
+doString(vector signed short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both and should
+     convert tail recursion to iteration with two copies of the "loop
+     body" when compiled with -O2 or -O3.  */
+  vector signed short result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that exactly two dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 2 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 2 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-16.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-16.c
new file mode 100644
index 00000000000..2c5ea7ecc06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-16.c
@@ -0,0 +1,56 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-stril-17.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned char
+doString(vector unsigned char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector unsigned char result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char composed_string [4] = {
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
+  };
+
+  vector unsigned char expected0 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char expected1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
+  vector unsigned char expected2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
+  vector unsigned char expected3 =
+    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-17.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-17.c
new file mode 100644
index 00000000000..2f82393bf9b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-17.c
@@ -0,0 +1,54 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned char
+doString(vector unsigned char *vp)
+{
+  /* Tail recursion replaced with iteration with -O2.  */
+  vector unsigned char result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char composed_string [4] = {
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
+  };
+
+  vector unsigned char expected0 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char expected1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
+  vector unsigned char expected2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
+  vector unsigned char expected3 =
+    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-18.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-18.c
new file mode 100644
index 00000000000..37c18c1ddb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-18.c
@@ -0,0 +1,56 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-stril-19.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector signed char
+doString(vector signed char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector signed char result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, char *argv [])
+{
+  vector signed char composed_string [4] = {
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
+  };
+
+  vector signed char expected0 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector signed char expected1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
+  vector signed char expected2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
+  vector signed char expected3 =
+    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-19.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-19.c
new file mode 100644
index 00000000000..a0bdd64848a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-19.c
@@ -0,0 +1,54 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector signed char
+doString(vector signed char *vp)
+{
+  /* Tail recursion replaced with iteration with -O2.  */
+  vector signed char result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, char *argv [])
+{
+  vector signed char composed_string [4] = {
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
+  };
+
+  vector signed char expected0 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector signed char expected1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 00, 0x0 };
+  vector signed char expected2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
+  vector signed char expected3 =
+    { 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-2.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-2.c
new file mode 100644
index 00000000000..baffe92e4ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-2.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of signed char.  */
+vector signed char
+silj (vector signed char arg)
+{
+  return vec_stril (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\M} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-20.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-20.c
new file mode 100644
index 00000000000..879b1aea22f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-20.c
@@ -0,0 +1,46 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-stril-21.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned short
+doString(vector unsigned short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector unsigned short result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short composed_string [4] = {
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 }
+  };
+
+  vector unsigned short expected0 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected1 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short expected2 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short expected3 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
+
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-21.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-21.c
new file mode 100644
index 00000000000..430ed0bbe4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-21.c
@@ -0,0 +1,44 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned short
+doString(vector unsigned short *vp)
+{
+  /* Iteration replaces tail recursion with -O2.  */
+  vector unsigned short result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short composed_string [4] = {
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 }
+  };
+
+  vector unsigned short expected0 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected1 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short expected2 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short expected3 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
+
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-22.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-22.c
new file mode 100644
index 00000000000..acc438852fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-22.c
@@ -0,0 +1,44 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-stril-23.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector signed short
+doString(vector signed short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector signed short result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, short *argv [])
+{
+  vector signed short composed_string [4] = {
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 }
+  };
+
+  vector signed short expected0 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected1 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short expected2 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short expected3 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-23.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-23.c
new file mode 100644
index 00000000000..75d1e10607a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-23.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector signed short
+doString(vector signed short *vp)
+{
+  /* Iteration replaces tail recursion with -O2.  */
+  vector signed short result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, short *argv [])
+{
+  vector signed short composed_string [4] = {
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 }
+  };
+
+  vector signed short expected0 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected1 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short expected2 = { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short expected3 = { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-3.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-3.c
new file mode 100644
index 00000000000..50f359b6068
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-3.c
@@ -0,0 +1,52 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed char.  */
+vector signed char
+silj (vector signed char arg)
+{
+  return vec_stril (arg);
+}
+
+int main (int argc, char *argv [])
+{
+  vector signed char input1 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char expected1 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char input2 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector signed char expected2 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0 };
+  vector signed char input3 =
+    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+  vector signed char expected3 =
+    { 0x1, 0x2, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed char input4 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+  vector signed char expected4 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x0 };
+
+  if (!vec_all_eq (silj (input1), expected1))
+    abort ();
+  if (!vec_all_eq (silj (input2), expected2))
+    abort ();
+  if (!vec_all_eq (silj (input3), expected3))
+    abort ();
+  if (!vec_all_eq (silj (input4), expected4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-4.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-4.c
new file mode 100644
index 00000000000..35447b96b33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-4.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of unsigned short.  */
+vector unsigned short
+silj (vector unsigned short arg)
+{
+  return vec_stril (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\M} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-5.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-5.c
new file mode 100644
index 00000000000..16f6bcf6400
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-5.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of unsigned short.  */
+vector unsigned short
+silj (vector unsigned short arg)
+{
+  return vec_stril (arg);
+}
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected2 =
+    { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short expected3 =
+    { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short expected4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+
+  if (!vec_all_eq (silj (input1), expected1))
+    abort ();
+  if (!vec_all_eq (silj (input2), expected2))
+    abort ();
+  if (!vec_all_eq (silj (input3), expected3))
+    abort ();
+  if (!vec_all_eq (silj (input4), expected4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-6.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-6.c
new file mode 100644
index 00000000000..b40e65b80c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-6.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of signed short.  */
+vector signed short
+silj (vector signed short arg)
+{
+  return vec_stril (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\M} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-7.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-7.c
new file mode 100644
index 00000000000..b6f90ce5414
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-7.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of signed short.  */
+vector signed short
+silj (vector signed short arg)
+{
+  return vec_stril (arg);
+}
+
+int main (int argc, short *argv [])
+{
+  vector signed short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected2 =
+    { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector signed short expected3 =
+    { 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector signed short expected4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (!vec_all_eq (silj (input1), expected1))
+    abort ();
+  if (!vec_all_eq (silj (input2), expected2))
+    abort ();
+  if (!vec_all_eq (silj (input3), expected3))
+    abort ();
+  if (!vec_all_eq (silj (input4), expected4))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-8.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-8.c
new file mode 100644
index 00000000000..9f2f3e34a99
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-8.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -mdejagnu-cpu=future -O1" } */
+/* See vec-stril-9.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+vector unsigned char
+doString(vector unsigned char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector unsigned char result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril-9.c b/gcc/testsuite/gcc.target/powerpc/vec-stril-9.c
new file mode 100644
index 00000000000..56864f4e477
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril-9.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector unsigned char
+doString(vector unsigned char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both and should
+     convert tail recursion to iteration with two copies of the "loop
+     body" when compiled with -O2 or -O3.  */
+  vector unsigned char result = vec_stril (*vp);
+  if (vec_stril_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that exactly two dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\.} 2 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\.} 2 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-0.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-0.c
new file mode 100644
index 00000000000..2ec2e706593
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-0.c
@@ -0,0 +1,24 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified predicate on array of
+   unsigned char.  */
+int
+silj_p (vector unsigned char arg)
+{
+  return vec_stril_p (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-1.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-1.c
new file mode 100644
index 00000000000..0ec3541d810
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-1.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified predicate on array of
+   unsigned char.  */
+int
+silj_p (vector unsigned char arg)
+{
+  return vec_stril_p (arg);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char input1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char input2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char input3 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char input4 =
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+
+  if (silj_p (input1))
+    abort ();
+  if (!silj_p (input2))
+    abort ();
+  if (!silj_p (input3))
+    abort ();
+  if (!silj_p (input4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-10.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-10.c
new file mode 100644
index 00000000000..3c4ce86f1fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-10.c
@@ -0,0 +1,37 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (vec_stril_p (input1))
+    abort ();
+  if (!vec_stril_p (input2))
+    abort ();
+  if (!vec_stril_p (input3))
+    abort ();
+  if (!vec_stril_p (input4))
+    abort ();
+}
+
+/* Enforce that exactly four dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 4 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-11.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-11.c
new file mode 100644
index 00000000000..60f7ccd8c33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-11.c
@@ -0,0 +1,37 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int main (int argc, short *argv [])
+{
+  vector signed short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector signed short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (vec_stril_p (input1))
+    abort ();
+  if (!vec_stril_p (input2))
+    abort ();
+  if (!vec_stril_p (input3))
+    abort ();
+  if (!vec_stril_p (input4))
+    abort ();
+}
+
+/* Enforce that exactly four dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 4 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-2.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-2.c
new file mode 100644
index 00000000000..2b0b347c127
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-2.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of signed char.  */
+int
+silj_p (vector signed char arg)
+{
+  return vec_stril_p (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-3.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-3.c
new file mode 100644
index 00000000000..be477398648
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-3.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed char.  */
+int
+silj_p (vector signed char arg)
+{
+  return vec_stril_p (arg);
+}
+
+int main (int argc, char *argv [])
+{
+  vector signed char input1 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char input2 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector signed char input3 =
+    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+  vector signed char input4 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+
+  if (silj_p (input1))
+    abort ();
+  if (!silj_p (input2))
+    abort ();
+  if (!silj_p (input3))
+    abort ();
+  if (!silj_p (input4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-4.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-4.c
new file mode 100644
index 00000000000..4be60ac53da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-4.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of unsigned short.  */
+int
+silj_p (vector unsigned short arg)
+{
+  return vec_stril_p (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-5.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-5.c
new file mode 100644
index 00000000000..2b520b1745c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-5.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of unsigned short.  */
+int
+silj_p (vector unsigned short arg)
+{
+  return vec_stril_p (arg);
+}
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (silj_p (input1))
+    abort ();
+  if (!silj_p (input2))
+    abort ();
+  if (!silj_p (input3))
+    abort ();
+  if (!silj_p (input4))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-6.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-6.c
new file mode 100644
index 00000000000..de719f92b00
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-6.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of signed short.  */
+int
+silj_p (vector signed short arg)
+{
+  return vec_stril_p (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-7.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-7.c
new file mode 100644
index 00000000000..22f394fa6e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-7.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate left-justified on array of signed short.  */
+int
+silj_p (vector signed short arg)
+{
+  return vec_stril_p (arg);
+}
+
+int main (int argc, short *argv [])
+{
+  vector signed short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector signed short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (silj_p (input1))
+    abort ();
+  if (!silj_p (input2))
+    abort ();
+  if (!silj_p (input3))
+    abort ();
+  if (!silj_p (input4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-8.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-8.c
new file mode 100644
index 00000000000..daf322070ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-8.c
@@ -0,0 +1,42 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char input1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char input2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char input3 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char input4 =
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+
+  if (vec_stril_p (input1))
+    abort ();
+  if (!vec_stril_p (input2))
+    abort ();
+  if (!vec_stril_p (input3))
+    abort ();
+  if (!vec_stril_p (input4))
+    abort ();
+
+}
+
+/* Enforce that exactly four dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\.} 4 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\.} 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-stril_p-9.c b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-9.c
new file mode 100644
index 00000000000..85e8ea750fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-stril_p-9.c
@@ -0,0 +1,42 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int main (int argc, char *argv [])
+{
+  vector signed char input1 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char input2 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector signed char input3 =
+    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+  vector signed char input4 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+
+  if (vec_stril_p (input1))
+    abort ();
+  if (!vec_stril_p (input2))
+    abort ();
+  if (!vec_stril_p (input3))
+    abort ();
+  if (!vec_stril_p (input4))
+    abort ();
+
+}
+
+/* Enforce that exactly four dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribl\.} 4 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\.} 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-0.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-0.c
new file mode 100644
index 00000000000..6e9e944ca6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-0.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of unsigned char.  */
+vector unsigned char
+sirj (vector unsigned char arg)
+{
+  return vec_strir (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\M} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-1.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-1.c
new file mode 100644
index 00000000000..8bf326afbc7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-1.c
@@ -0,0 +1,52 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of unsigned char.  */
+vector unsigned char
+sirj (vector unsigned char arg)
+{
+  return vec_strir (arg);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char input1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char expected1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char input2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+  vector unsigned char input3 =
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+  vector unsigned char input4 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char expected4 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+
+  if (!vec_all_eq (sirj (input1), expected1))
+    abort ();
+  if (!vec_all_eq (sirj (input2), expected2))
+    abort ();
+  if (!vec_all_eq (sirj (input3), expected3))
+    abort ();
+  if (!vec_all_eq (sirj (input4), expected4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-10.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-10.c
new file mode 100644
index 00000000000..b129168510f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-10.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-strir-11.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+vector signed char
+doString(vector signed char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector signed char result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-11.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-11.c
new file mode 100644
index 00000000000..12d751a62f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-11.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector signed char
+doString(vector signed char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both and should
+     convert tail recursion to iteration with two copies of the "loop
+     body" when compiled with -O2 or -O3.  */
+  vector signed char result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that exactly two dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\.} 2 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\.} 2 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-12.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-12.c
new file mode 100644
index 00000000000..2ee44dabfd9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-12.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-strir-13.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+vector unsigned short
+doString(vector unsigned short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector unsigned short result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-13.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-13.c
new file mode 100644
index 00000000000..91ca59bb826
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-13.c
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector unsigned short
+doString(vector unsigned short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both and should
+     convert tail recursion to iteration with two copies of the "loop
+     body" when compiled with -O2 or -O3.  */
+  vector unsigned short result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that exactly two dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 2 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 2 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-14.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-14.c
new file mode 100644
index 00000000000..5f7d4341992
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-14.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-strir-15.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+vector signed short
+doString(vector signed short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector signed short result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-15.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-15.c
new file mode 100644
index 00000000000..0a3d8d02ac1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-15.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector signed short
+doString(vector signed short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both and should
+     convert tail recursion to iteration with two copies of the "loop
+     body" when compiled with -O2 or -O3.  */
+  vector signed short result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that exactly two dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 2 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 2 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-16.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-16.c
new file mode 100644
index 00000000000..2418b2f40fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-16.c
@@ -0,0 +1,56 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-strir-17.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned char
+doString(vector unsigned char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector unsigned char result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char composed_string [4] = {
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
+  };
+
+  vector unsigned char expected0 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char expected1 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+  vector unsigned char expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-17.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-17.c
new file mode 100644
index 00000000000..1404342d4b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-17.c
@@ -0,0 +1,54 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned char
+doString(vector unsigned char *vp)
+{
+  /* Tail recursion replaced with iteration with -O2.  */
+  vector unsigned char result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char composed_string [4] = {
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 },
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 }
+  };
+
+  vector unsigned char expected0 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char expected1 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+  vector unsigned char expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-18.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-18.c
new file mode 100644
index 00000000000..ab9592f49ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-18.c
@@ -0,0 +1,56 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-strir-19.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector signed char
+doString(vector signed char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector signed char result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, char *argv [])
+{
+  vector signed char composed_string [4] = {
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 },
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 },
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 }
+  };
+
+  vector signed char expected0 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char expected1 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+  vector signed char expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
+  vector signed char expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-19.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-19.c
new file mode 100644
index 00000000000..b0f78df40b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-19.c
@@ -0,0 +1,54 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector signed char
+doString(vector signed char *vp)
+{
+  /* Tail recursion replaced with iteration with -O2.  */
+  vector signed char result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, char *argv [])
+{
+  vector signed char composed_string [4] = {
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 },
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 },
+    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 },
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 }
+  };
+
+  vector signed char expected0 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char expected1 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+  vector signed char expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
+  vector signed char expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-2.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-2.c
new file mode 100644
index 00000000000..a7efde73d56
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-2.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed char.  */
+vector signed char
+sirj (vector signed char arg)
+{
+  return vec_strir (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\M} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-20.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-20.c
new file mode 100644
index 00000000000..8ac643e1dbf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-20.c
@@ -0,0 +1,48 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-strir-21.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned short
+doString(vector unsigned short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector unsigned short result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short composed_string [4] = {
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0x0, 0xd, 0xe }
+  };
+
+  vector unsigned short expected0 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected1 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-21.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-21.c
new file mode 100644
index 00000000000..47bf0db8946
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-21.c
@@ -0,0 +1,46 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector unsigned short
+doString(vector unsigned short *vp)
+{
+  /* Iteration replaces tail recursion with -O2.  */
+  vector unsigned short result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short composed_string [4] = {
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0x0, 0xd, 0xe }
+  };
+
+  vector unsigned short expected0 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected1 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-22.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-22.c
new file mode 100644
index 00000000000..48a57983860
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-22.c
@@ -0,0 +1,48 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-strir-23.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector signed short
+doString(vector signed short *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector signed short result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, short *argv [])
+{
+  vector signed short composed_string [4] = {
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0x0, 0xd, 0xe }
+  };
+
+  vector signed short expected0 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected1 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-23.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-23.c
new file mode 100644
index 00000000000..b3b143f3b68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-23.c
@@ -0,0 +1,46 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+vector signed short
+doString(vector signed short *vp)
+{
+  /* Iteration replaces tail recursion with -O2.  */
+  vector signed short result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+int main (int argc, short *argv [])
+{
+  vector signed short composed_string [4] = {
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf },
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 },
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0x0, 0xd, 0xe }
+  };
+
+  vector signed short expected0 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected1 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe };
+
+  if (!vec_all_eq (doString (&composed_string[0]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[1]), expected1))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[2]), expected2))
+    abort ();
+  if (!vec_all_eq (doString (&composed_string[3]), expected3))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-3.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-3.c
new file mode 100644
index 00000000000..25db69c52a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-3.c
@@ -0,0 +1,52 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed char.  */
+vector signed char
+sirj (vector signed char arg)
+{
+  return vec_strir (arg);
+}
+
+int main (int argc, char *argv [])
+{
+  vector signed char input1 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char expected1 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char input2 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector signed char expected2 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x11 };
+  vector signed char input3 =
+    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+  vector signed char expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
+  vector signed char input4 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+  vector signed char expected4 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11 };
+
+  if (!vec_all_eq (sirj (input1), expected1))
+    abort ();
+  if (!vec_all_eq (sirj (input2), expected2))
+    abort ();
+  if (!vec_all_eq (sirj (input3), expected3))
+    abort ();
+  if (!vec_all_eq (sirj (input4), expected4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-4.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-4.c
new file mode 100644
index 00000000000..85a3f56d24f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-4.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of unsigned short.  */
+vector unsigned short
+sirj (vector unsigned short arg)
+{
+  return vec_strir (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\M} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-5.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-5.c
new file mode 100644
index 00000000000..7047039deab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-5.c
@@ -0,0 +1,44 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of unsigned short.  */
+vector unsigned short
+sirj (vector unsigned short arg)
+{
+  return vec_strir (arg);
+}
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected2 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector unsigned short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short expected4 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (!vec_all_eq (sirj (input1), expected1))
+    abort ();
+  if (!vec_all_eq (sirj (input2), expected2))
+    abort ();
+  if (!vec_all_eq (sirj (input3), expected3))
+    abort ();
+  if (!vec_all_eq (sirj (input4), expected4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-6.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-6.c
new file mode 100644
index 00000000000..56e81812120
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-6.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed short.  */
+vector signed short
+sirj (vector signed short arg)
+{
+  return vec_strir (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\M} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-7.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-7.c
new file mode 100644
index 00000000000..fddee218759
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-7.c
@@ -0,0 +1,44 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed short.  */
+vector signed short
+sirj (vector signed short arg)
+{
+  return vec_strir (arg);
+}
+
+int main (int argc, short *argv [])
+{
+  vector signed short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short expected2 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector signed short expected3 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+  vector signed short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector signed short expected4 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (!vec_all_eq (sirj (input1), expected1))
+    abort ();
+  if (!vec_all_eq (sirj (input2), expected2))
+    abort ();
+  if (!vec_all_eq (sirj (input3), expected3))
+    abort ();
+  if (!vec_all_eq (sirj (input4), expected4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-8.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-8.c
new file mode 100644
index 00000000000..211cdeb8e50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-8.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -mdejagnu-cpu=future" } */
+/* See vec-strir-9.c for the same test with -O2 optimization.  */
+
+#include <altivec.h>
+
+vector unsigned char
+doString(vector unsigned char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both with -O1.  */
+  vector unsigned char result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir-9.c b/gcc/testsuite/gcc.target/powerpc/vec-strir-9.c
new file mode 100644
index 00000000000..b95711c71f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir-9.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector unsigned char
+doString(vector unsigned char *vp)
+{
+  /* Though two built-in functions are called, the implementation
+     should use a single instruction to implement both and should
+     convert tail recursion to iteration with two copies of the "loop
+     body" when compiled with -O2 or -O3.  */
+  vector unsigned char result = vec_strir (*vp);
+  if (vec_strir_p (*vp))
+    return result;
+  else
+    return doString (vp + 1);
+}
+
+/* Enforce that exactly two dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\.} 2 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\.} 2 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-0.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-0.c
new file mode 100644
index 00000000000..f94703dfe77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-0.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of unsigned char.  */
+int
+sirj_p (vector unsigned char arg)
+{
+  return vec_strir_p (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-1.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-1.c
new file mode 100644
index 00000000000..ce527a7c530
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-1.c
@@ -0,0 +1,39 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of unsigned char.  */
+int
+sirj_p (vector unsigned char arg)
+{
+  return vec_strir_p (arg);
+}
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char input1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char input2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char input3 =
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char input4 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+
+  if (sirj_p (input1))
+    abort ();
+  if (!sirj_p (input2))
+    abort ();
+  if (!sirj_p (input3))
+    abort ();
+  if (!sirj_p (input4))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-10.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-10.c
new file mode 100644
index 00000000000..5a4c63940e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-10.c
@@ -0,0 +1,46 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected2 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short expected3 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short expected4 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (vec_strir_p (input1))
+    abort ();
+  if (!vec_strir_p (input2))
+    abort ();
+  if (!vec_strir_p (input3))
+    abort ();
+  if (!vec_strir_p (input4))
+    abort ();
+
+}
+
+/* Enforce that exactly four dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 4 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-11.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-11.c
new file mode 100644
index 00000000000..786b2798a11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-11.c
@@ -0,0 +1,38 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int main (int argc, short *argv [])
+{
+  vector signed short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector signed short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (vec_strir_p (input1))
+    abort ();
+  if (!vec_strir_p (input2))
+    abort ();
+  if (!vec_strir_p (input3))
+    abort ();
+  if (!vec_strir_p (input4))
+    abort ();
+
+}
+
+/* Enforce that exactly four dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 4 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-2.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-2.c
new file mode 100644
index 00000000000..becb3220567
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-2.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed char.  */
+int
+sirj_p (vector signed char arg)
+{
+  return vec_strir_p (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-3.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-3.c
new file mode 100644
index 00000000000..42777702b3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-3.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed char.  */
+int
+sirj_p (vector signed char arg)
+{
+  return vec_strir_p (arg);
+}
+
+int main (int argc, char *argv [])
+{
+  vector signed char input1 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char input2 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector signed char input3 =
+    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+  vector signed char input4 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+
+  if (sirj_p (input1))
+    abort ();
+  if (!sirj_p (input2))
+    abort ();
+  if (!sirj_p (input3))
+    abort ();
+  if (!sirj_p (input4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-4.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-4.c
new file mode 100644
index 00000000000..f9b214caa29
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-4.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of unsigned short.  */
+int
+sirj_p (vector unsigned short arg)
+{
+  return vec_strir_p (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-5.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-5.c
new file mode 100644
index 00000000000..337f2d08875
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-5.c
@@ -0,0 +1,44 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of unsigned short.  */
+int
+sirj_p (vector unsigned short arg)
+{
+  return vec_strir_p (arg);
+}
+
+int main (int argc, short *argv [])
+{
+  vector unsigned short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short expected2 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector unsigned short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short expected3 =
+    { 0x0, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector unsigned short expected4 =
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  if (sirj_p (input1))
+    abort ();
+  if (!sirj_p (input2))
+    abort ();
+  if (!sirj_p (input3))
+    abort ();
+  if (!sirj_p (input4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-6.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-6.c
new file mode 100644
index 00000000000..d1b79ee1250
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-6.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed short.  */
+int
+sirj_p (vector signed short arg)
+{
+  return vec_strir_p (arg);
+}
+
+/* Enforce that a single dot-form instruction which is properly biased
+   for the target's endianness implements this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstrihr\.} 1 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\.} 1 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstrihr} 0 { target { le } } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-7.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-7.c
new file mode 100644
index 00000000000..a6794d29fd1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-7.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+/* Vector string isolate right-justified on array of signed short.  */
+int
+sirj_p (vector signed short arg)
+{
+  return vec_strir_p (arg);
+}
+
+int main (int argc, short *argv [])
+{
+  vector signed short input1 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input2 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf };
+  vector signed short input3 =
+    { 0x1, 0x0, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+  vector signed short input4 =
+    { 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0x0 };
+
+  if (sirj_p (input1))
+    abort ();
+  if (!sirj_p (input2))
+    abort ();
+  if (!sirj_p (input3))
+    abort ();
+  if (!sirj_p (input4))
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-8.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-8.c
new file mode 100644
index 00000000000..f25528c7b46
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-8.c
@@ -0,0 +1,43 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int main (int argc, char *argv [])
+{
+  vector unsigned char input1 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x11 };
+  vector unsigned char input2 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char input3 =
+    { 0x1, 0x2, 0x0, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector unsigned char input4 =
+    { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+
+  if (!vec_strir_p (input1))
+    abort ();
+  if (!vec_strir_p (input2))
+    abort ();
+  if (!vec_strir_p (input3))
+    abort ();
+  if (!vec_strir_p (input4))
+    abort ();
+}
+
+/* Enforce that exactly four dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\.} 4 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\.} 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */
+
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-strir_p-9.c b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-9.c
new file mode 100644
index 00000000000..42831a4cbed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-strir_p-9.c
@@ -0,0 +1,42 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int main (int argc, char *argv [])
+{
+  vector signed char input1 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0xf, 0x11 };
+  vector signed char input2 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0x0, 0xf, 0x11 };
+  vector signed char input3 =
+    { 0x1, 0x2, 0xf3, 0x0, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+  vector signed char input4 =
+    { 0x1, 0x2, 0xf3, 0x4, 0x5, 0x6, 0x7, 0x8,
+      0x9, 0xa, 0xb, 0xc, 0xd, 0xe2, 0x0, 0x11 };
+
+  if (vec_strir_p (input1))
+    abort ();
+  if (!vec_strir_p (input2))
+    abort ();
+  if (!vec_strir_p (input3))
+    abort ();
+  if (!vec_strir_p (input4))
+    abort ();
+
+}
+
+/* Enforce that exactly four dot-form instructions which are properly biased
+   for the target's endianness implement this built-in.  */
+
+/* { dg-final { scan-assembler-times {\mvstribr\.} 4 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr\M[^.]} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl} 0 { target { be } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\.} 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribl\M[^.]} 0 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\mvstribr} 0 { target { le } } } } */