Hello,
Below patch is bootstrapped and regtested on powerpc64le-linux-gnu with
no regressions.
Changes from v2:
- Add endian compensation sequence for LE so that the logical
vector element ordering matches BE semantics.
Changes from v1:
- Add missing author line:
2025-03-11 Kishan Parmar <[email protected]>
Thank you,
Kishan
Add support for vector uncompress and unpack instructions proposed in
RFC02691. These instructions may or may not be added to a future Power
processor, and the names of the builtins may change in the future.
The instructions are exposed through new builtins and intrinsics
interfaces and are enabled when compiling with -mcpu=future.
This patch adds RTL patterns for vector uncompress (nibble, byte, and
halfword) and unpack operations in altivec.md, along with the
corresponding builtin definitions in rs6000-builtins.def and overload
entries in rs6000-overload.def.
The following new builtins are provided:
vector unsigned short vec_uncompresshn (vector unsigned char,
vector unsigned int)
vector unsigned int vec_uncompresshb (vector unsigned short,
vector unsigned short)
vector unsigned long long vec_uncompresshh (vector unsigned int,
vector unsigned char)
vector unsigned short vec_uncompressln (vector unsigned char,
vector unsigned int)
vector unsigned int vec_uncompresslb (vector unsigned short,
vector unsigned short)
vector unsigned long long vec_uncompresslh (vector unsigned int,
vector unsigned char)
vector signed char vec_unpack_hsn_to_byte (vector unsigned long long)
vector signed char vec_unpack_lsn_to_byte (vector unsigned long long)
vector unsigned char vec_unpack_int4_to_bf16 (vector unsigned short,
const int<2>)
vector unsigned char vec_unpack_int8_to_bf16 (vector unsigned short,
const int<1>)
vector float vec_unpack_int4_to_fp32 (vector unsigned int, const int<3>)
vector float vec_unpack_int8_to_fp32 (vector unsigned int, const int<2>)
2026-05-20 Kishan Parmar <[email protected]>
gcc/ChangeLog:
* config/rs6000/altivec.md (UNSPEC_VUCMPRHN): New unspec entry.
(UNSPEC_VUCMPRLN): Likewise.
(UNSPEC_VUCMPRHB): Likewise.
(UNSPEC_VUCMPRLB): Likewise.
(UNSPEC_VUCMPRHH): Likewise.
(UNSPEC_VUCMPRLH): Likewise.
(UNSPEC_VUPKHSNTOB): Likewise.
(UNSPEC_VUPKLSNTOB): Likewise.
(UNSPEC_VUPKINT4TOBF16): Likewise.
(UNSPEC_VUPKINT8TOBF16): Likewise.
(UNSPEC_VUPKINT4TOFP32): Likewise.
(UNSPEC_VUPKINT8TOFP32): Likewise.
(vu_hl): New attribute.
(vu_lh): Likewise.
(VUPKNTOB): New int iterator.
(altivec_vupkhsntob): New define_insn.
(altivec_vupklsntob): Likewise.
(altivec_vupkint4tobf16): Likewise.
(altivec_vupkint8tobf16): Likewise.
(altivec_vupkint4tofp32): Likewise.
(altivec_vupkint8tofp32): Likewise.
(vucmpr_splat): New attribute.
(vucmpr_pcv): Likewise.
(vucmpr_uim): Likewise.
(VUCMPR_N): New int iterator.
(VUCMPR_B): Likewise.
(VUCMPR_H): Likewise.
(altivec_vucmpr<vu_hl>n): New define_expand.
(altivec_vucmpr<vu_hl>n_direct): New define_insn for vucmpr<vu_hl>n.
(altivec_vucmpr<vu_hl>b): New define_expand.
(altivec_vucmpr<vu_hl>b_direct): New define_insn for vucmpr<vu_hl>b.
(altivec_vucmpr<vu_hl>h): New define_expand.
(altivec_vucmpr<vu_hl>h_direct): New define_insn for vucmpr<vu_hl>h.
* config/rs6000/rs6000-builtins.def: Add vector uncompress and unpack
builtins under [future].
* config/rs6000/rs6000-overload.def: Add vec_uncompress* and vec_unpack*
interfaces.
gcc/testsuite/ChangeLog:
* gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c: New test.
* gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c: Likewise.
* gcc/testsuite/gcc.target/powerpc/future-vupk.c: Likewise.
---
gcc/config/rs6000/altivec.md | 286 ++++++++++++++++++
gcc/config/rs6000/rs6000-builtins.def | 36 +++
gcc/config/rs6000/rs6000-overload.def | 47 +++
.../powerpc/future-vucmpr-altivec.c | 46 +++
.../gcc.target/powerpc/future-vucmpr-vsx.c | 60 ++++
.../gcc.target/powerpc/future-vupk.c | 50 +++
6 files changed, 525 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c
create mode 100644 gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c
create mode 100644 gcc/testsuite/gcc.target/powerpc/future-vupk.c
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 129f56245cd..024829fd275 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -171,6 +171,18 @@
UNSPEC_SLDB
UNSPEC_SRDB
UNSPEC_VECTOR_SHIFT
+ UNSPEC_VUCMPRHN
+ UNSPEC_VUCMPRLN
+ UNSPEC_VUCMPRHB
+ UNSPEC_VUCMPRLB
+ UNSPEC_VUCMPRHH
+ UNSPEC_VUCMPRLH
+ UNSPEC_VUPKHSNTOB
+ UNSPEC_VUPKLSNTOB
+ UNSPEC_VUPKINT4TOBF16
+ UNSPEC_VUPKINT8TOBF16
+ UNSPEC_VUPKINT4TOFP32
+ UNSPEC_VUPKINT8TOFP32
])
(define_c_enum "unspecv"
@@ -4826,3 +4838,277 @@
(match_dup 3)]
UNSPEC_BCD_ADD_SUB)
(match_dup 4)))])])
+
+(define_int_attr vu_hl [(UNSPEC_VUPKHSNTOB "h") (UNSPEC_VUPKLSNTOB "l")
+ (UNSPEC_VUCMPRHN "h") (UNSPEC_VUCMPRLN "l")
+ (UNSPEC_VUCMPRHB "h") (UNSPEC_VUCMPRLB "l")
+ (UNSPEC_VUCMPRHH "h") (UNSPEC_VUCMPRLH "l")])
+
+(define_int_attr vu_lh [(UNSPEC_VUPKHSNTOB "l") (UNSPEC_VUPKLSNTOB "h")
+ (UNSPEC_VUCMPRHN "l") (UNSPEC_VUCMPRLN "h")
+ (UNSPEC_VUCMPRHB "l") (UNSPEC_VUCMPRLB "h")
+ (UNSPEC_VUCMPRHH "l") (UNSPEC_VUCMPRLH "h")])
+
+;; Vector unpack instructions for future.
+
+(define_int_iterator VUPKNTOB [UNSPEC_VUPKHSNTOB UNSPEC_VUPKLSNTOB])
+
+(define_insn "altivec_vupk<vu_hl>sntob_direct"
+ [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
+ (unspec:V16QI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
+ VUPKNTOB))]
+ "TARGET_FUTURE"
+ "vupk<vu_hl>sntob %0, %1"
+ [(set_attr "type" "vecperm")])
+
+(define_expand "altivec_vupk<vu_hl>sntob"
+ [(set (match_operand:V16QI 0 "altivec_register_operand")
+ (unspec:V16QI [(match_operand:V2DI 1 "altivec_register_operand")]
+ VUPKNTOB))]
+ "TARGET_FUTURE && (BYTES_BIG_ENDIAN || TARGET_VSX)"
+{
+ if (BYTES_BIG_ENDIAN)
+ emit_insn (gen_altivec_vupk<vu_hl>sntob_direct (operands[0],
+ operands[1]));
+ else
+ {
+ emit_insn (gen_altivec_vupk<vu_lh>sntob_direct (operands[0],
+ operands[1]));
+ emit_insn (gen_p9_xxbrq_v16qi (operands[0], operands[0]));
+ }
+ DONE;
+})
+
+(define_insn "altivec_vupkint4tobf16"
+ [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
+ (unspec:V8HI [(match_operand:V8HI 1 "altivec_register_operand" "v")
+ (match_operand:QI 2 "const_0_to_3_operand" "i")]
+ UNSPEC_VUPKINT4TOBF16))]
+ "TARGET_FUTURE"
+ "vupkint4tobf16 %0, %1, %2"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupkint8tobf16"
+ [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
+ (unspec:V8HI [(match_operand:V8HI 1 "altivec_register_operand" "v")
+ (match_operand:QI 2 "const_0_to_1_operand" "i")]
+ UNSPEC_VUPKINT8TOBF16))]
+ "TARGET_FUTURE"
+ "vupkint8tobf16 %0, %1, %2"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupkint4tofp32"
+ [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
+ (unspec:V4SF [(match_operand:V4SI 1 "altivec_register_operand" "v")
+ (match_operand:QI 2 "const_0_to_7_operand" "i")]
+ UNSPEC_VUPKINT4TOFP32))]
+ "TARGET_FUTURE"
+ "vupkint4tofp32 %0, %1, %2"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupkint8tofp32"
+ [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
+ (unspec:V4SF [(match_operand:V4SI 1 "altivec_register_operand" "v")
+ (match_operand:QI 2 "const_0_to_3_operand" "i")]
+ UNSPEC_VUPKINT8TOFP32))]
+ "TARGET_FUTURE"
+ "vupkint8tofp32 %0, %1, %2"
+ [(set_attr "type" "vecperm")])
+
+
+;; Vector uncompress instructions for future.
+
+;; VSX splat values for vector uncompress instructions for little endian.
+(define_int_attr vucmpr_splat [(UNSPEC_VUCMPRHN "3")
+ (UNSPEC_VUCMPRLN "2")
+ (UNSPEC_VUCMPRHB "7")
+ (UNSPEC_VUCMPRLB "6")
+ (UNSPEC_VUCMPRHH "15")
+ (UNSPEC_VUCMPRLH "14")])
+
+;; Altivec PCV(Permute Control Vector) mask values for vperm used in
+;; little endian.
+(define_int_attr vucmpr_pcv [(UNSPEC_VUCMPRHN "0x0f0e0d0c")
+ (UNSPEC_VUCMPRLN "0x0b0a0908")
+ (UNSPEC_VUCMPRHB "0x0f0e0000")
+ (UNSPEC_VUCMPRLB "0x0d0c0000")])
+
+;; Values for UIM which are used in vinsw instruction which will be used in
+;; little-endian, to know in vector.
+(define_int_attr vucmpr_uim [(UNSPEC_VUCMPRHN "4") (UNSPEC_VUCMPRLN "0")
+ (UNSPEC_VUCMPRHB "2") (UNSPEC_VUCMPRLB "0")])
+
+/* On little-endian systems, the selector/mask layout does not match
+ the architectural element ordering used by the vector uncompress
+ instructions. Byte-wise reverse the selector layout and swap the high/low
+ nibbles so that the resulting vector matches big-endian semantics. */
+
+;; Vector Uncompress Nibbles
+
+(define_int_iterator VUCMPR_N [UNSPEC_VUCMPRHN UNSPEC_VUCMPRLN])
+
+(define_insn "altivec_vucmpr<vu_hl>n_direct"
+ [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
+ (unspec:V8HI [(match_operand:V16QI 1 "altivec_register_operand" "v")
+ (match_operand:V4SI 2 "altivec_register_operand" "v")]
+ VUCMPR_N))]
+ "TARGET_FUTURE"
+ "vucmpr<vu_hl>n %0, %1, %2")
+
+(define_expand "altivec_vucmpr<vu_hl>n"
+ [(set (match_operand:V8HI 0 "altivec_register_operand")
+ (unspec:V8HI [(match_operand:V16QI 1 "altivec_register_operand")
+ (match_operand:V4SI 2 "altivec_register_operand")]
+ VUCMPR_N))]
+ "TARGET_FUTURE"
+{
+ if (BYTES_BIG_ENDIAN)
+ {
+ emit_insn (gen_altivec_vucmpr<vu_hl>n_direct(operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+ if (TARGET_VSX)
+ {
+ rtx splat = gen_reg_rtx (V4SImode);
+ rtx shift = gen_reg_rtx (V16QImode);
+ rtx bytes = gen_reg_rtx (V16QImode);
+ rtx rotated = gen_reg_rtx (V16QImode);
+ rtx selector = gen_reg_rtx (V4SImode);
+
+ emit_insn (gen_altivec_vspltw_direct (splat, operands[2],
+ GEN_INT (<vucmpr_splat>)));
+ emit_insn (gen_p9_xxbrw_v4si (splat, splat));
+ emit_move_insn (bytes, gen_lowpart (V16QImode, splat));
+ emit_insn (gen_altivec_vspltisb (shift, GEN_INT (4)));
+ emit_insn (gen_altivec_vrlb (rotated, bytes, shift));
+ emit_move_insn (selector, gen_lowpart (V4SImode, rotated));
+ emit_insn (gen_altivec_vucmpr<vu_lh>n_direct (operands[0], operands[1],
+ selector));
+ }
+ else
+ {
+ rtx pcv = gen_reg_rtx (V4SImode);
+ rtx perm = gen_reg_rtx (V16QImode);
+ rtx mask = gen_reg_rtx (SImode);
+
+ emit_move_insn (mask, GEN_INT (<vucmpr_pcv>));
+ emit_insn (gen_vreplace_elt_v4si_inst (pcv, pcv, mask,
+ GEN_INT (<vucmpr_uim>)));
+ emit_move_insn (perm, gen_lowpart (V16QImode, pcv));
+ emit_insn (gen_altivec_vperm_v4si_direct (operands[2], operands[2],
+ operands[2], perm));
+ emit_insn (gen_altivec_vucmpr<vu_lh>n_direct (operands[0], operands[1],
+ operands[2]));
+ }
+
+ DONE;
+})
+
+
+;; Vector Uncompress Bytes
+
+(define_int_iterator VUCMPR_B [UNSPEC_VUCMPRHB UNSPEC_VUCMPRLB])
+
+(define_insn "altivec_vucmpr<vu_hl>b_direct"
+ [(set (match_operand:V4SI 0 "altivec_register_operand" "=v")
+ (unspec:V4SI [(match_operand:V8HI 1 "altivec_register_operand" "v")
+ (match_operand:V8HI 2 "altivec_register_operand" "v")]
+ VUCMPR_B))]
+ "TARGET_FUTURE"
+ "vucmpr<vu_hl>b %0, %1, %2"
+ [(set_attr "type" "vecperm")])
+
+(define_expand "altivec_vucmpr<vu_hl>b"
+ [(set (match_operand:V4SI 0 "altivec_register_operand")
+ (unspec:V4SI [(match_operand:V8HI 1 "altivec_register_operand")
+ (match_operand:V8HI 2 "altivec_register_operand")]
+ VUCMPR_B))]
+ "TARGET_FUTURE"
+{
+ if (BYTES_BIG_ENDIAN)
+ {
+ emit_insn (gen_altivec_vucmpr<vu_hl>b_direct (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+ if (TARGET_VSX)
+ {
+ rtx splat = gen_reg_rtx (V8HImode);
+ rtx shift = gen_reg_rtx (V16QImode);
+ rtx bytes = gen_reg_rtx (V16QImode);
+ rtx rotated = gen_reg_rtx (V16QImode);
+ rtx selector = gen_reg_rtx (V8HImode);
+
+ emit_insn (gen_altivec_vsplth_direct (splat, operands[2],
+ GEN_INT (<vucmpr_splat>)));
+ emit_insn (gen_p9_xxbrh_v8hi (splat, splat));
+ emit_move_insn (bytes, gen_lowpart (V16QImode, splat));
+ emit_insn (gen_altivec_vspltisb (shift, GEN_INT (4)));
+ emit_insn (gen_altivec_vrlb (rotated, bytes, shift));
+ emit_move_insn (selector, gen_lowpart (V8HImode, rotated));
+ emit_insn (gen_altivec_vucmpr<vu_lh>b_direct (operands[0], operands[1],
+ selector));
+ }
+ else
+ {
+ rtx pcv = gen_reg_rtx (V4SImode);
+ rtx perm = gen_reg_rtx (V16QImode);
+ rtx mask = gen_reg_rtx (SImode);
+ rtx selector = gen_reg_rtx (V4SImode);
+
+ emit_move_insn (mask, GEN_INT (<vucmpr_pcv>));
+ emit_insn (gen_vreplace_elt_v4si_inst (pcv, pcv, mask,
+ GEN_INT (<vucmpr_uim>)));
+ emit_move_insn (perm, gen_lowpart (V16QImode, pcv));
+ emit_move_insn (selector, gen_lowpart (V4SImode, operands[2]));
+ emit_insn (gen_altivec_vperm_v4si_direct (selector, selector, selector,
+ perm));
+ emit_insn (gen_altivec_vucmpr<vu_lh>b_direct (operands[0], operands[1],
+ gen_lowpart (V8HImode,
+ selector)));
+ }
+
+ DONE;
+})
+
+;; Vector Uncompress Halfwords
+
+(define_int_iterator VUCMPR_H [UNSPEC_VUCMPRHH UNSPEC_VUCMPRLH])
+
+(define_insn "altivec_vucmpr<vu_hl>h_direct"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (unspec:V2DI [(match_operand:V4SI 1 "altivec_register_operand" "v")
+ (match_operand:V16QI 2 "altivec_register_operand" "v")]
+ VUCMPR_H))]
+ "TARGET_FUTURE"
+ "vucmpr<vu_hl>h %0, %1, %2"
+ [(set_attr "type" "vecperm")])
+
+(define_expand "altivec_vucmpr<vu_hl>h"
+ [(set (match_operand:V2DI 0 "altivec_register_operand")
+ (unspec:V2DI [(match_operand:V4SI 1 "altivec_register_operand")
+ (match_operand:V16QI 2 "altivec_register_operand")]
+ VUCMPR_H))]
+ "TARGET_FUTURE && (BYTES_BIG_ENDIAN || TARGET_VSX)"
+{
+ if (BYTES_BIG_ENDIAN)
+ {
+ emit_insn (gen_altivec_vucmpr<vu_hl>h_direct (operands[0], operands[1],
+ operands[2]));
+ }
+ else
+ {
+ rtx splat = gen_reg_rtx (V16QImode);
+ rtx shift = gen_reg_rtx (V16QImode);
+ rtx rotated = gen_reg_rtx (V16QImode);
+
+ emit_insn (gen_altivec_vspltb_direct (splat, operands[2],
+ GEN_INT (<vucmpr_splat>)));
+ emit_insn (gen_altivec_vspltisb (shift, GEN_INT (4)));
+ emit_insn (gen_altivec_vrlb (rotated, splat, shift));
+ emit_insn (gen_altivec_vucmpr<vu_lh>h_direct (operands[0], operands[1],
+ rotated));
+ }
+ DONE;
+})
diff --git a/gcc/config/rs6000/rs6000-builtins.def
b/gcc/config/rs6000/rs6000-builtins.def
index 0d1529b71d4..d4b3dab1b31 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -3970,3 +3970,39 @@
const vuc __builtin_galois_field_mult_xts (vuc, vuc);
XXGFMUL128XTS xxgfmul128xts {}
+
+ const vus __builtin_altivec_uncompresshn (vuc, vui);
+ VUCMPRHN altivec_vucmprhn {}
+
+ const vui __builtin_altivec_uncompresshb (vus, vus);
+ VUCMPRHB altivec_vucmprhb {}
+
+ const vull __builtin_altivec_uncompresshh (vui, vuc);
+ VUCMPRHH altivec_vucmprhh {}
+
+ const vus __builtin_altivec_uncompressln (vuc, vui);
+ VUCMPRLN altivec_vucmprln {}
+
+ const vui __builtin_altivec_uncompresslb (vus, vus);
+ VUCMPRLB altivec_vucmprlb {}
+
+ const vull __builtin_altivec_uncompresslh (vui, vuc);
+ VUCMPRLH altivec_vucmprlh {}
+
+ const vsc __builtin_altivec_unpack_hsn_to_byte (vull);
+ VUPKHSNTOB altivec_vupkhsntob {}
+
+ const vsc __builtin_altivec_unpack_lsn_to_byte (vull);
+ VUPKLSNTOB altivec_vupklsntob {}
+
+ const vuc __builtin_altivec_unpack_int4_to_bf16 (vus, const int<2>);
+ VUPKINT4TOBF16 altivec_vupkint4tobf16 {}
+
+ const vuc __builtin_altivec_unpack_int8_to_bf16 (vus, const int<1>);
+ VUPKINT8TOBF16 altivec_vupkint8tobf16 {}
+
+ const vf __builtin_altivec_unpack_int4_to_fp32 (vui, const int<3>);
+ VUPKINT4TOFP32 altivec_vupkint4tofp32 {}
+
+ const vf __builtin_altivec_unpack_int8_to_fp32 (vui, const int<2>);
+ VUPKINT8TOFP32 altivec_vupkint8tofp32 {}
diff --git a/gcc/config/rs6000/rs6000-overload.def
b/gcc/config/rs6000/rs6000-overload.def
index ef7b59ed112..11cd29f45c0 100644
--- a/gcc/config/rs6000/rs6000-overload.def
+++ b/gcc/config/rs6000/rs6000-overload.def
@@ -5015,6 +5015,53 @@
vd __builtin_vsx_xxsldwi (vd, vd, const int);
XXSLDWI_2DF XXSLDWI_VD2
+[VEC_UCMPRHN, vec_uncompresshn, __builtin_vec_uncompresshn]
+ vus __builtin_vec_uncompresshn (vuc, vui);
+ VUCMPRHN
+
+[VEC_UCMPRHB, vec_uncompresshb, __builtin_vec_uncomresshb]
+ vui __builtin_vec_uncomresshb (vus, vus);
+ VUCMPRHB
+
+[VEC_UCMPRHH, vec_uncompresshh, __builtin_vec_uncomresshh]
+ vull __builtin_vec_uncomresshh (vui, vuc);
+ VUCMPRHH
+
+[VEC_UCMPRLN, vec_uncompressln, __builtin_vec_uncomressln]
+ vus __builtin_vec_uncomressln (vuc, vui);
+ VUCMPRLN
+
+[VEC_UCMPRLB, vec_uncompresslb, __builtin_vec_uncomresslb]
+ vui __builtin_vec_uncomresslb (vus, vus);
+ VUCMPRLB
+
+[VEC_UCMPRLH, vec_uncompresslh, __builtin_vec_uncomresslh]
+ vull __builtin_vec_uncomresslh (vui, vuc);
+ VUCMPRLH
+
+[VEC_UNPACK_HSN_TO_BYTE, vec_unpack_hsn_to_byte,
__builtin_vec_unpack_hsn_to_byte]
+ vsc __builtin_vec_unpack_hsn_to_byte (vull);
+ VUPKHSNTOB
+
+[VEC_UNPACK_LSN_TO_BYTE, vec_unpack_lsn_to_byte,
__builtin_vec_unpack_lsn_to_byte]
+ vsc __builtin_vec_unpack_lsn_to_byte (vull);
+ VUPKLSNTOB
+
+[VEC_UNPACK_INT4_TO_BF16, vec_unpack_int4_to_bf16,
__builtin_vec_unpack_int4_to_bf16]
+ vuc __builtin_vec_unpack_int4_to_bf16 (vus, const int<2>);
+ VUPKINT4TOBF16
+
+[VEC_UNPACK_INT8_TO_BF16, vec_unpack_int8_to_bf16,
__builtin_vec_unpack_int8_to_bf16]
+ vuc __builtin_vec_unpack_int8_to_bf16 (vus, const int<1>);
+ VUPKINT8TOBF16
+
+[VEC_UNPACK_INT4_TO_FP32, vec_unpack_int4_to_fp32,
__builtin_vec_unpack_int4_to_fp32]
+ vf __builtin_vec_unpack_int4_to_fp32 (vui, const int<3>);
+ VUPKINT4TOFP32
+
+[VEC_UNPACK_INT8_TO_FP32, vec_unpack_int8_to_fp32,
__builtin_vec_unpack_int8_to_fp32]
+ vf __builtin_vec_unpack_int8_to_fp32 (vui, const int<2>);
+ VUPKINT8TOFP32
; **************************************************************************
; **************************************************************************
diff --git a/gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c
b/gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c
new file mode 100644
index 00000000000..0a1d489f9af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future -mno-vsx" } */
+
+#include <altivec.h>
+
+vector unsigned short
+test_uncompresshn (vector unsigned char a,
+ vector unsigned int b)
+{
+ return vec_uncompresshn (a, b);
+}
+
+vector unsigned int
+test_uncompresshb (vector unsigned short a,
+ vector unsigned short b)
+{
+ return vec_uncompresshb (a, b);
+}
+
+vector unsigned short
+test_uncompressln (vector unsigned char a,
+ vector unsigned int b)
+{
+ return vec_uncompressln (a, b);
+}
+
+vector unsigned int
+test_uncompresslb (vector unsigned short a,
+ vector unsigned short b)
+{
+ return vec_uncompresslb (a, b);
+}
+
+/* { dg-final { scan-assembler-not "vxor" { target { be } } } } */
+/* { dg-final { scan-assembler-not "vinsw" { target { be } } } } */
+/* { dg-final { scan-assembler-not "vperm" { target { be } } } } */
+
+
+/* { dg-final { scan-assembler-times "vxor" 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times "vinsw" 4 { target { le } } } } */
+/* { dg-final { scan-assembler-times "vperm" 4 { target { le } } } } */
+
+/* Final uncompress instructions. */
+
+/* { dg-final { scan-assembler-times {vucmpr[lh][nb]} 4 } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c
b/gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c
new file mode 100644
index 00000000000..9d783721091
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future -mvsx" } */
+
+#include <altivec.h>
+
+vector unsigned short test_uncompresshn(vector unsigned char a,
+ vector unsigned int b)
+{
+ return vec_uncompresshn(a, b);
+}
+
+vector unsigned int test_uncompresshb(vector unsigned short a,
+ vector unsigned short b)
+{
+ return vec_uncompresshb(a, b);
+}
+
+vector unsigned long long test_uncompresshh(vector unsigned int a,
+ vector unsigned char b)
+{
+ return vec_uncompresshh(a, b);
+}
+
+vector unsigned short test_uncompressln(vector unsigned char a,
+ vector unsigned int b)
+{
+ return vec_uncompressln(a, b);
+}
+
+vector unsigned int test_uncompresslb(vector unsigned short a,
+ vector unsigned short b)
+{
+ return vec_uncompresslb(a, b);
+}
+
+vector unsigned long long test_uncompresslh(vector unsigned int a,
+ vector unsigned char b)
+{
+ return vec_uncompresslh(a, b);
+}
+
+/* BE: direct instructions, no splats or reverse. */
+
+/* { dg-final { scan-assembler-not {vsplt[whb]} { target { be } } } } */
+/* { dg-final { scan-assembler-not {xxspltib} { target { be } } } } */
+/* { dg-final { scan-assembler-not {xxbr[wh]\M} { target { be } } } } */
+/* { dg-final { scan-assembler-not {vrlb} { target { be } } } } */
+
+/* LE: splats and reverse-byte + rotate must appear. */
+
+/* { dg-final { scan-assembler-times {vsplt[whb]} 6 { target { le } } } } */
+
+/* { dg-final { scan-assembler-times "xxspltib" 6 { target { le } } } } */
+
+/* { dg-final { scan-assembler-times {xxbr[wh]} 4 { target { le } } } } */
+
+/* { dg-final { scan-assembler-times "vrlb" 6 { target { le } } } } */
+
+/* { dg-final { scan-assembler-times {vucmpr[lh][nbh]} 6 } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/future-vupk.c
b/gcc/testsuite/gcc.target/powerpc/future-vupk.c
new file mode 100644
index 00000000000..6031aaaa077
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/future-vupk.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+vector signed char
+test_unpack_hsn_to_byte(vector unsigned long long a)
+{
+ return vec_unpack_hsn_to_byte(a);
+}
+
+vector signed char
+test_unpack_lsn_to_byte(vector unsigned long long a)
+{
+ return vec_unpack_lsn_to_byte(a);
+}
+
+vector unsigned char
+test_unpack_int4_to_bf16(vector unsigned short a)
+{
+ return vec_unpack_int4_to_bf16(a, 0);
+}
+
+vector unsigned char
+test_unpack_int8_to_bf16(vector unsigned short a)
+{
+ return vec_unpack_int8_to_bf16(a, 0);
+}
+
+vector float
+test_unpack_int4_to_fp32(vector unsigned int a)
+{
+ return vec_unpack_int4_to_fp32(a, 0);
+}
+
+vector float
+test_unpack_int8_to_fp32(vector unsigned int a)
+{
+ return vec_unpack_int8_to_fp32(a, 0);
+}
+
+
+/* { dg-final { scan-assembler-times "xxbrq" 2 { target { vsx_hw } } } } */
+
+/* { dg-final { scan-assembler-times "vupkhsntob" 1 } } */
+/* { dg-final { scan-assembler-times "vupklsntob" 1 } } */
+/* { dg-final { scan-assembler-times "vupkint4tobf16" 1 } } */
+/* { dg-final { scan-assembler-times "vupkint8tobf16" 1 } } */
+/* { dg-final { scan-assembler-times "vupkint4tofp32" 1 } } */
+/* { dg-final { scan-assembler-times "vupkint8tofp32" 1 } } */
--
2.47.3