https://gcc.gnu.org/g:61715e9340ab8941d40d62158fe437e9dbe3e068

commit r15-2002-g61715e9340ab8941d40d62158fe437e9dbe3e068
Author: Stefan Schulze Frielinghaus <stefa...@gcc.gnu.org>
Date:   Fri Jul 12 13:42:08 2024 +0200

    s390: Fully exploit vgm, vgbm, vrepi
    
    Currently instructions vgm and vrepi are utilized only for constant
    vectors where the element mode equals the element mode of the
    corresponding instruction.  This patch lifts this restriction by making
    use of those instructions for constant vectors even if element modes
    do not coincide.  For example, the constant vector
    
      (v2di){0x7ffffffe7ffffffe, 0x7ffffffe7ffffffe}
    
    can be loaded via vgmf %v0,1,30.  Similar, the constant vector
    
      (v4si){0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}
    
    can be loaded via vrepiq %v0,-86.
    
    Analog, if the element mode of a constant vector is smaller than the
    element mode of a corresponding instruction, we still may make use of
    those instructions.  For example, the constant vector
    
      (v4si){0x7fff, 0xfffe0000, 0x7fff, 0xfffe0000}
    
    can be loaded via vgmg %v0,17,46.  Similar, the constant vector
    
      (v4si){-1, -16643, -1, -16643}
    
    can be loaded via vrepig %v0,-16643.
    
    Additionally this patch enables vgm, vgbm, vrepi for partial vectors,
    i.e., vectors of size less than 16 bytes.  Basically this is done by
    treating a vector as a full vector resulting in replicating constants
    into the ignored bits whereas vgbm sets those to zero.
    
    Furthermore, there is no restriction to integer vectors anymore, i.e.,
    supporting scalars of mode up to and including TI and TF and also
    floating-point vectors.
    
    Here are some numbers how often instructions are emitted for SPEC 2017:
    
            w/o patch     w/ patch
    vgbm          140          365
    vgm         17508        24452
    vrepi        1360         2775
    
    I expect most (maybe even all) to save us a load from the literal pool.
    
    gcc/ChangeLog:
    
            * config/s390/2964.md: Remove extended mnemonics for vgm.
            * config/s390/3906.md: Remove extended mnemonics for vgm.
            * config/s390/3931.md: Remove extended mnemonics for vgm.
            * config/s390/8561.md: Remove extended mnemonics for vgm.
            * config/s390/constraints.md (jKK): Remove constraint.
            (jzz): Add constraint.
            * config/s390/s390-protos.h (s390_contiguous_bitmask_vector_p):
            Add prototype.
            (s390_constant_via_vgm_p): Add prototype.
            (s390_constant_via_vrepi_p): Add prototype.
            * config/s390/s390.cc (s390_contiguous_bitmask_vector_p): New
            function.
            (s390_constant_via_vgm_vrepi_helper): New function.
            (s390_constant_via_vgm_p): New function.
            (s390_constant_via_vgbm_p): For the sake of symmetry rename
            s390_bytemask_vector_p into s390_constant_via_vgbm_p.
            (s390_bytemask_vector_p): Deal with non-integer and partial
            vectors.
            (s390_constant_via_vrepi_p): New function.
            (s390_legitimate_constant_p): Allow partial vectors.
            (legitimate_reload_constant_p): Fix indentation.
            (legitimate_reload_vector_constant_p): Restrict to constraints
            j00, jm1, jxx, jyy, jzz only, i.e., allow partial vectors.
            (s390_expand_vec_init): Also make use of vrepi if possible.
            (print_operand): Add q,p,r for vgm,vrepi,vgbm, respectively.
            Remove e,s,t for constant vectors.
            * config/s390/s390.md (movti): Add variants utilizing
            vgbm,vgm,vrepi.
            * config/s390/vector.md (mov<mode><tf_vr>): Adapt variants
            for vgbm,vgm,vrepi for the new scheme.
            (mov<mode>): Adapt variants for vgbm,vgm for the new
            scheme and add vrepi variant for modes V_8,V_16,V_32,V_64.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/s390/vector/vec-copysign.c: Change to non-extended
            mnemonic.
            * gcc.target/s390/vector/vec-genmask-1.c: Change to non-extended
            mnemonic.
            * gcc.target/s390/vector/vec-init-1.c: Change to non-extended
            mnemonic.
            * gcc.target/s390/vector/vec-vrepi-1.c: Change to non-extended
            mnemonic.
            * gcc.target/s390/zvector/autovec-double-quiet-uneq.c: Change to
            non-extended mnemonic.
            * gcc.target/s390/zvector/autovec-float-quiet-uneq.c: Change to
            non-extended mnemonic.
            * gcc.target/s390/zvector/vec-genmask-1.c: Change to
            non-extended mnemonic.
            * gcc.target/s390/zvector/vec-splat-1.c: Change to non-extended
            mnemonic.
            * gcc.target/s390/zvector/vec-splat-2.c: Change to non-extended
            mnemonic.
            * gcc.target/s390/vector/vgbm-double-1.c: New test.
            * gcc.target/s390/vector/vgbm-float-1.c: New test.
            * gcc.target/s390/vector/vgbm-int128-1.c: New test.
            * gcc.target/s390/vector/vgbm-integer-1.c: New test.
            * gcc.target/s390/vector/vgbm-longdouble-1.c: New test.
            * gcc.target/s390/vector/vgm-df-1.c: New test.
            * gcc.target/s390/vector/vgm-di-1.c: New test.
            * gcc.target/s390/vector/vgm-hi-1.c: New test.
            * gcc.target/s390/vector/vgm-int128-1.c: New test.
            * gcc.target/s390/vector/vgm-longdouble-1.c: New test.
            * gcc.target/s390/vector/vgm-qi-1.c: New test.
            * gcc.target/s390/vector/vgm-sf-1.c: New test.
            * gcc.target/s390/vector/vgm-si-1.c: New test.
            * gcc.target/s390/vector/vgm-tf-1.c: New test.
            * gcc.target/s390/vector/vgm-ti-1.c: New test.
            * gcc.target/s390/vector/vrepi-df-1.c: New test.
            * gcc.target/s390/vector/vrepi-di-1.c: New test.
            * gcc.target/s390/vector/vrepi-hi-1.c: New test.
            * gcc.target/s390/vector/vrepi-int128-1.c: New test.
            * gcc.target/s390/vector/vrepi-qi-1.c: New test.
            * gcc.target/s390/vector/vrepi-sf-1.c: New test.
            * gcc.target/s390/vector/vrepi-si-1.c: New test.
            * gcc.target/s390/vector/vrepi-tf-1.c: New test.
            * gcc.target/s390/vector/vrepi-ti-1.c: New test.

Diff:
---
 gcc/config/s390/2964.md                            |   4 +-
 gcc/config/s390/3906.md                            |   4 +-
 gcc/config/s390/3931.md                            |   8 -
 gcc/config/s390/8561.md                            |   4 +-
 gcc/config/s390/constraints.md                     |  25 +-
 gcc/config/s390/s390-protos.h                      |   5 +-
 gcc/config/s390/s390.cc                            | 329 ++++++++++++++++-----
 gcc/config/s390/s390.md                            |  13 +-
 gcc/config/s390/vector.md                          |  52 ++--
 .../gcc.target/s390/vector/vec-copysign.c          |   6 +-
 .../gcc.target/s390/vector/vec-genmask-1.c         |  10 +-
 gcc/testsuite/gcc.target/s390/vector/vec-init-1.c  |   6 +-
 gcc/testsuite/gcc.target/s390/vector/vec-vrepi-1.c |   8 +-
 .../gcc.target/s390/vector/vgbm-double-1.c         |  34 +++
 .../gcc.target/s390/vector/vgbm-float-1.c          |  34 +++
 .../gcc.target/s390/vector/vgbm-int128-1.c         |  43 +++
 .../gcc.target/s390/vector/vgbm-integer-1.c        | 115 +++++++
 .../gcc.target/s390/vector/vgbm-longdouble-1.c     |  34 +++
 gcc/testsuite/gcc.target/s390/vector/vgm-df-1.c    |  34 +++
 gcc/testsuite/gcc.target/s390/vector/vgm-di-1.c    | 130 ++++++++
 gcc/testsuite/gcc.target/s390/vector/vgm-hi-1.c    | 216 ++++++++++++++
 .../gcc.target/s390/vector/vgm-int128-1.c          |  69 +++++
 .../gcc.target/s390/vector/vgm-longdouble-1.c      |  59 ++++
 gcc/testsuite/gcc.target/s390/vector/vgm-qi-1.c    | 241 +++++++++++++++
 gcc/testsuite/gcc.target/s390/vector/vgm-sf-1.c    |  47 +++
 gcc/testsuite/gcc.target/s390/vector/vgm-si-1.c    | 179 +++++++++++
 gcc/testsuite/gcc.target/s390/vector/vgm-tf-1.c    |  57 ++++
 gcc/testsuite/gcc.target/s390/vector/vgm-ti-1.c    |  68 +++++
 gcc/testsuite/gcc.target/s390/vector/vrepi-df-1.c  |  58 ++++
 gcc/testsuite/gcc.target/s390/vector/vrepi-di-1.c  | 106 +++++++
 gcc/testsuite/gcc.target/s390/vector/vrepi-hi-1.c  | 168 +++++++++++
 .../gcc.target/s390/vector/vrepi-int128-1.c        |  69 +++++
 gcc/testsuite/gcc.target/s390/vector/vrepi-qi-1.c  | 145 +++++++++
 gcc/testsuite/gcc.target/s390/vector/vrepi-sf-1.c  |  83 ++++++
 gcc/testsuite/gcc.target/s390/vector/vrepi-si-1.c  | 143 +++++++++
 gcc/testsuite/gcc.target/s390/vector/vrepi-tf-1.c  |  33 +++
 gcc/testsuite/gcc.target/s390/vector/vrepi-ti-1.c  |  68 +++++
 .../s390/zvector/autovec-double-quiet-uneq.c       |   2 +-
 .../s390/zvector/autovec-float-quiet-uneq.c        |   2 +-
 .../gcc.target/s390/zvector/vec-genmask-1.c        |  12 +-
 .../gcc.target/s390/zvector/vec-splat-1.c          |  16 +-
 .../gcc.target/s390/zvector/vec-splat-2.c          |  16 +-
 42 files changed, 2577 insertions(+), 178 deletions(-)

diff --git a/gcc/config/s390/2964.md b/gcc/config/s390/2964.md
index 21ef972a206c..83f97da47476 100644
--- a/gcc/config/s390/2964.md
+++ b/gcc/config/s390/2964.md
@@ -92,7 +92,7 @@ 
vfchedb,vfchedbs,vfchesb,vfchesbs,vfchsb,vfchsbs,vfeeb,vfeef,vfeeh,vfeezbs,\
 vfeezhs,vfeneb,vfenef,vfeneh,vfenezb,vfenezf,vfenezh,vfidb,vfisb,vflcdb,\
 vflcsb,vflndb,vflnsb,vflpdb,vfmadb,vfmasb,vfmdb,vfmsb,vfmsdb,vfmssb,vfsdb,\
 vfssb,vftcidb,vftcisb,vgbm,vgfmab,vgfmaf,vgfmag,vgfmah,vgfmb,vgfmf,vgfmg,\
-vgfmh,vgm,vgmb,vgmf,vgmg,vgmh,vistrb,vistrbs,vistrf,vistrfs,vistrh,vlcb,\
+vgfmh,vgm,vistrb,vistrbs,vistrf,vistrfs,vistrh,vlcb,\
 vlcf,vlcg,vlch,vldeb,vleb,vledb,vlef,vleg,vleh,vleib,vleif,vleig,vleih,\
 vlpb,vlpf,vlpg,vlph,vmaeb,vmaef,vmaeh,vmahb,vmahf,vmahh,vmalb,vmaleb,\
 vmalef,vmaleh,vmalf,vmalhb,vmalhf,vmalhh,vmalhw,vmalob,vmalof,vmaloh,vmaob,\
@@ -178,7 +178,7 @@ 
verllb,verllf,verllg,verllh,verllvb,verllvf,verllvg,verllvh,veslb,veslf,\
 veslg,veslh,veslvb,veslvf,veslvg,veslvh,vesrab,vesraf,vesrag,vesrah,vesravb,\
 vesravf,vesravg,vesravh,vesrlb,vesrlf,vesrlg,vesrlh,vesrlvb,vesrlvf,vesrlvg,\
 vesrlvh,vfcedb,vfcesb,vfchdb,vfchedb,vfchesb,vfchsb,vflcdb,vflcsb,vflndb,\
-vflnsb,vflpdb,vgbm,vgm,vgmb,vgmf,vgmg,vgmh,vlcb,vlcf,vlcg,vlch,vleb,vlef,\
+vflnsb,vflpdb,vgbm,vgm,vlcb,vlcf,vlcg,vlch,vleb,vlef,\
 vleg,vleh,vleib,vleif,vleig,vleih,vlpb,vlpf,vlpg,vlph,vmnb,vmnf,vmng,vmnh,\
 vmnlb,vmnlf,vmnlg,vmnlh,vmrhb,vmrhf,vmrhg,vmrhh,vmrlb,vmrlf,vmrlg,vmrlh,\
 vmxb,vmxf,vmxg,vmxh,vn,vnc,vno,vnot,vo,vone,vpdi,vperm,vpkf,vpkg,vpkh,\
diff --git a/gcc/config/s390/3906.md b/gcc/config/s390/3906.md
index e0ba59941fed..7da2e657e3b2 100644
--- a/gcc/config/s390/3906.md
+++ b/gcc/config/s390/3906.md
@@ -95,7 +95,7 @@ 
vfeezbs,vfeezhs,vfeneb,vfenef,vfeneh,vfenezb,vfenezf,vfenezh,vfidb,vfisb,\
 vflcdb,vflcsb,vflndb,vflnsb,vflpdb,vfmadb,vfmasb,vfmaxdb,vfmaxsb,vfmdb,\
 vfmindb,vfminsb,vfmsb,vfmsdb,vfmssb,vfnmadb,vfnmsdb,vfnmssb,vfsdb,vfssb,\
 vftcidb,vftcisb,vgbm,vgfmab,vgfmaf,vgfmag,vgfmah,vgfmb,vgfmf,vgfmg,vgfmh,vgm,\
-vgmb,vgmf,vgmg,vgmh,vistrb,vistrbs,vistrf,vistrfs,vistrh,vlcb,vlcf,vlcg,\
+vistrb,vistrbs,vistrf,vistrfs,vistrh,vlcb,vlcf,vlcg,\
 vlch,vldeb,vleb,vledb,vlef,vleg,vleh,vleib,vleif,vleig,vleih,vlpb,vlpf,\
 vlpg,vlph,vmaeb,vmaef,vmaeh,vmahb,vmahf,vmahh,vmalb,vmaleb,vmalef,vmaleh,\
 vmalf,vmalhb,vmalhf,vmalhh,vmalhw,vmalob,vmalof,vmaloh,vmaob,vmaof,vmaoh,\
@@ -183,7 +183,7 @@ 
verllf,verllg,verllh,verllvb,verllvf,verllvg,verllvh,veslb,veslf,veslg,veslh,\
 veslvb,veslvf,veslvg,veslvh,vesrab,vesraf,vesrag,vesrah,vesravb,vesravf,\
 vesravg,vesravh,vesrlb,vesrlf,vesrlg,vesrlh,vesrlvb,vesrlvf,vesrlvg,vesrlvh,\
 vfcedb,vfcesb,vfchdb,vfchedb,vfchesb,vfchsb,vflcdb,vflcsb,vflndb,vflnsb,\
-vflpdb,vfmaxdb,vfmaxsb,vfmindb,vfminsb,vgbm,vgm,vgmb,vgmf,vgmg,vgmh,vlcb,\
+vflpdb,vfmaxdb,vfmaxsb,vfmindb,vfminsb,vgbm,vgm,vlcb,\
 vlcf,vlcg,vlch,vleb,vlef,vleg,vleh,vleib,vleif,vleig,vleih,vlpb,vlpf,vlpg,\
 vlph,vmnb,vmnf,vmng,vmnh,vmnlb,vmnlf,vmnlg,vmnlh,vmrhb,vmrhf,vmrhg,vmrhh,\
 vmrlb,vmrlf,vmrlg,vmrlh,vmxb,vmxf,vmxg,vmxh,vn,vnc,vnn,vno,vnot,vnx,vo,voc,\
diff --git a/gcc/config/s390/3931.md b/gcc/config/s390/3931.md
index 740e0f3718f9..632c2456b6a3 100644
--- a/gcc/config/s390/3931.md
+++ b/gcc/config/s390/3931.md
@@ -944,10 +944,6 @@ vgfmf,
 vgfmg,
 vgfmh,
 vgm,
-vgmb,
-vgmf,
-vgmg,
-vgmh,
 vistrb,
 vistrbs,
 vistrf,
@@ -1854,10 +1850,6 @@ vfmindb,
 vfminsb,
 vgbm,
 vgm,
-vgmb,
-vgmf,
-vgmg,
-vgmh,
 vlcb,
 vlcf,
 vlcg,
diff --git a/gcc/config/s390/8561.md b/gcc/config/s390/8561.md
index ca6984de8865..6e2daf21c74c 100644
--- a/gcc/config/s390/8561.md
+++ b/gcc/config/s390/8561.md
@@ -94,7 +94,7 @@ 
vfeezfs,vfeezhs,vfeneb,vfenef,vfeneh,vfenezb,vfenezf,vfenezh,vfidb,vfisb,\
 vflcdb,vflcsb,vflndb,vflnsb,vflpdb,vflpsb,vfmadb,vfmasb,vfmaxdb,vfmaxsb,\
 vfmdb,vfmindb,vfminsb,vfmsb,vfmsdb,vfmssb,vfnmadb,vfnmasb,vfnmsdb,vfnmssb,\
 vfsdb,vfssb,vftcidb,vftcisb,vgbm,vgfmab,vgfmaf,vgfmag,vgfmah,vgfmb,vgfmf,\
-vgfmg,vgfmh,vgm,vgmb,vgmf,vgmg,vgmh,vistrb,vistrbs,vistrf,vistrfs,vistrh,\
+vgfmg,vgfmh,vgm,vistrb,vistrbs,vistrf,vistrfs,vistrh,\
 vistrhs,vlcb,vlcf,vlcg,vlch,vldeb,vleb,vledb,vlef,vleg,vleh,vleib,vleif,vleig,\
 vleih,vlpb,vlpf,vlpg,vlph,vmaeb,vmaef,vmaeh,vmahb,vmahf,vmahh,vmalb,vmaleb,\
 vmalef,vmaleh,vmalf,vmalhb,vmalhf,vmalhh,vmalhw,vmalob,vmalof,vmaloh,vmaob,\
@@ -185,7 +185,7 @@ 
verllvg,verllvh,veslb,veslf,veslg,veslh,veslvb,veslvf,veslvg,veslvh,vesrab,\
 vesraf,vesrag,vesrah,vesravb,vesravf,vesravg,vesravh,vesrlb,vesrlf,vesrlg,\
 vesrlh,vesrlvb,vesrlvf,vesrlvg,vesrlvh,vfcedb,vfcesb,vfchdb,vfchedb,vfchesb,\
 vfchsb,vflcdb,vflcsb,vflndb,vflnsb,vflpdb,vflpsb,vfmaxdb,vfmaxsb,vfmindb,\
-vfminsb,vgbm,vgm,vgmb,vgmf,vgmg,vgmh,vlcb,vlcf,vlcg,vlch,vleb,vlef,vleg,vleh,\
+vfminsb,vgbm,vgm,vlcb,vlcf,vlcg,vlch,vleb,vlef,vleg,vleh,\
 vleib,vleif,vleig,vleih,vlpb,vlpf,vlpg,vlph,vmnb,vmnf,vmng,vmnh,vmnlb,vmnlf,\
 vmnlg,vmnlh,vmrhb,vmrhf,vmrhg,vmrhh,vmrlb,vmrlf,vmrlg,vmrlh,vmxb,vmxf,vmxg,\
 vmxh,vmxlb,vmxlf,vmxlg,vmxlh,vn,vnc,vnn,vno,vnot,vnx,vo,voc,vone,vpdi,\
diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md
index 51924cfd05d2..3f498d2b6aaa 100644
--- a/gcc/config/s390/constraints.md
+++ b/gcc/config/s390/constraints.md
@@ -34,8 +34,7 @@
 ;;         jm1: constant scalar or vector with all bits set
 ;;         jxx: contiguous bitmask of 0 or 1 in all vector elements
 ;;         jyy: constant consisting of byte chunks being either 0 or 0xff
-;;         jKK: constant vector with all elements having the same value and
-;;              matching K constraint
+;;         jzz: constant consisting of 16-bit chunks which may be sign-extended
 ;;         jm6: An integer operand with the lowest order 6 bits all ones.
 ;;         jdd: A constant operand that fits into the data section.
 ;;         j>f: An integer operand whose lower 32 bits are greater than or 
equal to 15
@@ -438,27 +437,21 @@
   "All one bit scalar or vector constant"
   (match_test "op == CONSTM1_RTX (GET_MODE (op))"))
 
-; vector generate mask operand - support for up to 64 bit elements
+; vector generate mask operand
 (define_constraint "jxx"
   "@internal"
-  (and (match_code "const_vector")
-       (match_test "s390_contiguous_bitmask_vector_p (op, NULL, NULL)")))
+  (match_test "s390_constant_via_vgm_p (op, NULL, NULL, NULL)"))
 
-; vector generate byte mask operand - this is only supposed to deal
-; with real vectors 128 bit values of being either 0 or -1 are handled
-; with j00 and jm1
+; vector generate byte mask operand - constant 0 and -1 vectors are handled
+; by j00 and jm1, respectively.
 (define_constraint "jyy"
   "@internal"
-  (and (match_code "const_vector")
-       (match_test "s390_bytemask_vector_p (op, NULL)")))
+  (match_test "s390_constant_via_vgbm_p (op, NULL)"))
 
-; vector replicate immediate operand - support for up to 64 bit elements
-(define_constraint "jKK"
+; vector replicate immediate operand
+(define_constraint "jzz"
   "@internal"
-  (and (and (and (match_code "const_vector")
-                (match_test "const_vec_duplicate_p (op)"))
-           (match_test "GET_MODE_UNIT_SIZE (GET_MODE (op)) <= 8"))
-       (match_test "satisfies_constraint_K (XVECEXP (op, 0, 0))")))
+  (match_test "s390_constant_via_vrepi_p (op, NULL, NULL)"))
 
 (define_constraint "jm6"
   "@internal An integer operand with the lowest order 6 bits all ones."
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 8c2985a79c4d..b4646ccb6060 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -75,8 +75,9 @@ extern int s390_const_double_ok_for_constraint_p (rtx, int, 
const char *);
 extern int s390_single_part (rtx, machine_mode, machine_mode, int);
 extern unsigned HOST_WIDE_INT s390_extract_part (rtx, machine_mode, int);
 extern bool s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT, bool, int, int 
*, int *);
-extern bool s390_contiguous_bitmask_vector_p (rtx, int *, int *);
-extern bool s390_bytemask_vector_p (rtx, unsigned *);
+extern bool s390_constant_via_vgm_p (rtx, machine_mode *, int *, int *);
+extern bool s390_constant_via_vrepi_p (rtx, machine_mode *, short *);
+extern bool s390_constant_via_vgbm_p (rtx, unsigned *);
 extern bool s390_split_ok_p (rtx, rtx, machine_mode, int);
 extern bool s390_overlap_p (rtx, rtx, HOST_WIDE_INT);
 extern bool s390_offset_p (rtx, rtx, rtx);
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 05a0fde7fb06..7aea776da2f3 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -2663,67 +2663,205 @@ s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, 
bool wrap_p,
   return b;
 }
 
-/* Return true if OP contains the same contiguous bitfield in *all*
-   its elements.  START and END can be used to obtain the start and
-   end position of the bitfield.
+/* Return true if OP is a constant which fits into a vector register and if it
+   is a 16-byte constant, then the high and low half must equal.  Otherwise
+   return false.  The out parameter *VEC2 equals the high/low half for 16-byte
+   constants and for smaller constants it equals the concatination of constant
+   OP until an 8-byte constant is constructed.  */
 
-   START/STOP give the position of the first/last bit of the bitfield
-   counting from the lowest order bit starting with zero.  In order to
-   use these values for S/390 instructions this has to be converted to
-   "bits big endian" style.  */
+static bool
+s390_constant_via_vgm_vrepi_1 (rtx op, unsigned HOST_WIDE_INT *vec2)
+{
+  unsigned HOST_WIDE_INT vec;
+
+  if (GET_CODE (op) == CONST_VECTOR)
+    switch (GET_MODE_SIZE (GET_MODE (op)))
+      {
+      case 1:
+       {
+         rtx op_v1qi = gen_lowpart (V1QImode, op);
+         vec = UINTVAL (XVECEXP (op_v1qi, 0, 0));
+         vec &= GET_MODE_MASK (QImode);
+         vec |= vec <<  8;
+         vec |= vec << 16;
+         vec |= vec << 32;
+         *vec2 = vec;
+         return true;
+       }
+      case 2:
+       {
+         rtx op_v1hi = gen_lowpart (V1HImode, op);
+         vec = UINTVAL (XVECEXP (op_v1hi, 0, 0));
+         vec &= GET_MODE_MASK (HImode);
+         vec |= vec << 16;
+         vec |= vec << 32;
+         *vec2 = vec;
+         return true;
+       }
+      case 4:
+       {
+         rtx op_v1si = gen_lowpart (V1SImode, op);
+         vec = UINTVAL (XVECEXP (op_v1si, 0, 0));
+         vec &= GET_MODE_MASK (SImode);
+         vec |= vec << 32;
+         *vec2 = vec;
+         return true;
+       }
+      case 8:
+       {
+         rtx op_v1di = gen_lowpart (V1DImode, op);
+         vec = UINTVAL (XVECEXP (op_v1di, 0, 0));
+         *vec2 = vec;
+         return true;
+       }
+      case 16:
+       {
+         rtx op_v2di = gen_lowpart (V2DImode, op);
+         vec = UINTVAL (XVECEXP (op_v2di, 0, 0));
+         unsigned HOST_WIDE_INT tmp = UINTVAL (XVECEXP (op_v2di, 0, 1));
+         if (vec != tmp)
+           return false;
+         *vec2 = vec;
+         return true;
+       }
+      default:
+       return false;
+      }
+  else if (CONST_WIDE_INT_P (op) && CONST_WIDE_INT_NUNITS (op) == 2)
+    {
+      vec = CONST_WIDE_INT_ELT (op, 0);
+      unsigned HOST_WIDE_INT tmp = CONST_WIDE_INT_ELT (op, 1);
+      if (vec != tmp)
+       return false;
+      *vec2 = vec;
+      return true;
+    }
+  else if (CONST_DOUBLE_P (op) && GET_MODE (op) == TFmode)
+    {
+      long l[4];
+      const REAL_VALUE_TYPE *rv = CONST_DOUBLE_REAL_VALUE (op);
+      REAL_VALUE_TO_TARGET_LONG_DOUBLE (*rv, l);
+      vec = ((unsigned HOST_WIDE_INT) l[0] << 32)
+           | ((unsigned HOST_WIDE_INT) l[1] & 0xffffffffUL);
+      unsigned HOST_WIDE_INT tmp
+       = ((unsigned HOST_WIDE_INT) l[2] << 32)
+        | ((unsigned HOST_WIDE_INT) l[3] & 0xffffffffUL);
+      if (vec != tmp)
+       return false;
+      *vec2 = vec;
+      return true;
+    }
+  else
+    return false;
+}
+
+/* Return true if constant OP can be loaded via VGM.  Otherwise return false.
+   If MODE, START, and END are not null, then out parameter *MODE is the
+   element size of VGM, and *START and *END are the starting and ending bit
+   positions, respectively.  */
 
 bool
-s390_contiguous_bitmask_vector_p (rtx op, int *start, int *end)
+s390_constant_via_vgm_p (rtx op, machine_mode *mode, int *start, int *end)
 {
-  unsigned HOST_WIDE_INT mask;
-  int size;
-  rtx elt;
-  bool b;
-
-  /* Handle floats by bitcasting them to ints.  */
-  op = gen_lowpart (related_int_vector_mode (GET_MODE (op)).require (), op);
+  unsigned HOST_WIDE_INT vec;
 
-  gcc_assert (!!start == !!end);
-  if (!const_vec_duplicate_p (op, &elt)
-      || !CONST_INT_P (elt))
+  if (!s390_constant_via_vgm_vrepi_1 (op, &vec))
     return false;
 
-  size = GET_MODE_UNIT_BITSIZE (GET_MODE (op));
+  machine_mode iter;
+  FOR_EACH_MODE_UNTIL (iter, TImode)
+    {
+      unsigned HOST_WIDE_INT bits = vec & GET_MODE_MASK (iter);
+      bool b = s390_contiguous_bitmask_p (bits, true, GET_MODE_BITSIZE (iter),
+                                         start, end);
+      if (!b)
+       continue;
+      unsigned HOST_WIDE_INT vec2 = bits;
+      for (int i = 1; i < 8 / GET_MODE_SIZE (iter); ++i)
+       vec2 |= bits << (GET_MODE_BITSIZE (iter) * i);
+      if (vec == vec2)
+       {
+         if (mode && start && end)
+           {
+             *mode = iter;
+             *start -= (HOST_BITS_PER_WIDE_INT - GET_MODE_BITSIZE (iter));
+             *end -= (HOST_BITS_PER_WIDE_INT - GET_MODE_BITSIZE (iter));
+           }
+         return true;
+       }
+    }
+
+  return false;
+}
+
+/* Return true if constant OP can be loaded via VREPI.  Otherwise return false.
+   If MODE and IMM are not null, then out parameter *MODE is the element size
+   of VREPI, and *IMM is the signed integer immediate.  */
+
+bool
+s390_constant_via_vrepi_p (rtx op, machine_mode *mode, short *imm)
+{
+  unsigned HOST_WIDE_INT vec;
 
-  /* We cannot deal with V1TI/V1TF. This would require a vgmq.  */
-  if (size > 64)
+  if (!s390_constant_via_vgm_vrepi_1 (op, &vec))
     return false;
 
-  mask = UINTVAL (elt);
+  unsigned HOST_WIDE_INT bits = (short) (vec & 0xffff);
 
-  b = s390_contiguous_bitmask_p (mask, true, size, start, end);
-  if (b)
+  machine_mode iter;
+  FOR_EACH_MODE_UNTIL (iter, TImode)
     {
-      if (start)
+      unsigned HOST_WIDE_INT tmp = bits & GET_MODE_MASK (iter);
+      unsigned HOST_WIDE_INT vec2 = tmp;
+      for (int i = 1; i < 8 / GET_MODE_SIZE (iter); ++i)
+       vec2 |= tmp << (GET_MODE_BITSIZE (iter) * i);
+      if (vec == vec2)
        {
-         *start -= (HOST_BITS_PER_WIDE_INT - size);
-         *end -= (HOST_BITS_PER_WIDE_INT - size);
+         if (mode && imm)
+           {
+             *mode = iter;
+             /* Although, vrepib ignores the high half of the 16-bit mask,
+                canonicalize to an 8-bit sign-extended mask.  */
+             *imm = iter == QImode ? (signed char) (bits & 0xff)
+                                   : (short) (bits & 0xffff);
+           }
+         return true;
        }
-      return true;
     }
-  else
-    return false;
+
+  return false;
 }
 
-/* Return true if C consists only of byte chunks being either 0 or
+/* Return true if OP consists only of byte chunks being either 0 or
    0xff.  If MASK is !=NULL a byte mask is generated which is
    appropriate for the vector generate byte mask instruction.  */
 
 bool
-s390_bytemask_vector_p (rtx op, unsigned *mask)
+s390_constant_via_vgbm_p (rtx op, unsigned *mask)
 {
   int i;
   unsigned tmp_mask = 0;
   int nunit, unit_size;
 
-  if (!VECTOR_MODE_P (GET_MODE (op))
-      || GET_CODE (op) != CONST_VECTOR
-      || !CONST_INT_P (XVECEXP (op, 0, 0)))
+  if (GET_CODE (op) == CONST_VECTOR)
+    {
+      if (GET_MODE_INNER (GET_MODE (op)) == TImode
+         || GET_MODE_INNER (GET_MODE (op)) == TFmode)
+       /* For the sake of simplicity, bitcast 16-byte one-element vector
+          into two-element vector so we don't have to special case them in
+          the following.  */
+       op = gen_lowpart (V2DImode, op);
+      else
+       /* Handle floats by bitcasting them to ints.  */
+       op = gen_lowpart (related_int_vector_mode (GET_MODE (op)).require (),
+                         op);
+    }
+  else if ((CONST_WIDE_INT_P (op) && CONST_WIDE_INT_NUNITS (op) == 2)
+          || (CONST_DOUBLE_P (op) && GET_MODE (op) == TFmode))
+    /* For the sake of simplicity, bitcast the 16-byte constants into a vector
+       so we don't have to special case them in the following.  */
+    op = gen_lowpart (V2DImode, op);
+  else
     return false;
 
   nunit = GET_MODE_NUNITS (GET_MODE (op));
@@ -2734,9 +2872,6 @@ s390_bytemask_vector_p (rtx op, unsigned *mask)
       unsigned HOST_WIDE_INT c;
       int j;
 
-      if (!CONST_INT_P (XVECEXP (op, 0, i)))
-       return false;
-
       c = UINTVAL (XVECEXP (op, 0, i));
       for (j = 0; j < unit_size; j++)
        {
@@ -2748,7 +2883,7 @@ s390_bytemask_vector_p (rtx op, unsigned *mask)
     }
 
   if (mask != NULL)
-    *mask = tmp_mask;
+    *mask = tmp_mask << (16 - GET_MODE_SIZE (GET_MODE (op)));
 
   return true;
 }
@@ -4317,14 +4452,11 @@ legitimate_pic_operand_p (rtx op)
 static bool
 s390_legitimate_constant_p (machine_mode mode, rtx op)
 {
-  if (TARGET_VX && VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
+  if (TARGET_VX && GET_CODE (op) == CONST_VECTOR)
     {
-      if (GET_MODE_SIZE (mode) != 16)
-       return 0;
-
       if (!satisfies_constraint_j00 (op)
          && !satisfies_constraint_jm1 (op)
-         && !satisfies_constraint_jKK (op)
+         && !satisfies_constraint_jzz (op)
          && !satisfies_constraint_jxx (op)
          && !satisfies_constraint_jyy (op))
        return 0;
@@ -4457,7 +4589,7 @@ legitimate_reload_constant_p (rtx op)
       && GET_CODE (op) == CONST_INT
       && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
       && s390_single_part (op, word_mode, HImode, 0) >= 0)
-  return true;
+    return true;
 
   if (TARGET_EXTIMM
       && GET_CODE (op) == CONST_INT
@@ -4518,15 +4650,11 @@ legitimate_reload_fp_constant_p (rtx op)
 static bool
 legitimate_reload_vector_constant_p (rtx op)
 {
-  if (TARGET_VX && GET_MODE_SIZE (GET_MODE (op)) == 16
-      && (satisfies_constraint_j00 (op)
-         || satisfies_constraint_jm1 (op)
-         || satisfies_constraint_jKK (op)
-         || satisfies_constraint_jxx (op)
-         || satisfies_constraint_jyy (op)))
-    return true;
-
-  return false;
+  return TARGET_VX && (satisfies_constraint_j00 (op)
+                      || satisfies_constraint_jm1 (op)
+                      || satisfies_constraint_jzz (op)
+                      || satisfies_constraint_jxx (op)
+                      || satisfies_constraint_jyy (op));
 }
 
 /* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
@@ -7395,13 +7523,15 @@ s390_expand_vec_init (rtx target, rtx vals)
        all_regs = false;
     }
 
-  /* Use vector gen mask or vector gen byte mask if possible.  */
+  /* Use vector gen mask or vector gen byte mask or vector replicate immediate
+     if possible.  */
   if (all_same && all_const_int)
     {
       rtx vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
       if (XVECEXP (vals, 0, 0) == const0_rtx
-         || s390_contiguous_bitmask_vector_p (vec, NULL, NULL)
-         || s390_bytemask_vector_p (vec, NULL))
+         || s390_constant_via_vgm_p (vec, NULL, NULL, NULL)
+         || s390_constant_via_vrepi_p (vec, NULL, NULL)
+         || s390_constant_via_vgbm_p (vec, NULL))
        {
          emit_insn (gen_rtx_SET (target, vec));
          return;
@@ -8455,6 +8585,9 @@ print_operand_address (FILE *file, rtx addr)
     'M': print the second word of a TImode operand.
     'N': print the second word of a DImode operand.
     'O': print only the displacement of a memory reference or address.
+    'p': print immediate and element size mask for instruction vrepi
+    'q': print start/end bit positions and element size mask for instruction 
vgm
+    'r': print immediate for instruction vgbm
     'R': print only the base register of a memory reference or address.
     'S': print S-type memory reference (base+displacement).
     'Y': print address style operand without index (e.g. shift count or setmem
@@ -8472,7 +8605,6 @@ print_operand_address (FILE *file, rtx addr)
     'o': print integer X as if it's an unsigned 32bit word.
     's': "start" of contiguous bitmask X in either DImode or vector inner mode.
     't': CONST_INT: "start" of contiguous bitmask X in SImode.
-        CONST_VECTOR: Generate a bitmask for vgbm instruction.
     'x': print integer X as if it's an unsigned halfword.
     'v': print register number as vector register (v1 instead of f1).
     'V': print the second word of a TFmode operand as vector register.
@@ -8560,6 +8692,67 @@ print_operand (FILE *file, rtx x, int code)
       }
       return;
 
+    case 'p':
+      {
+       machine_mode mode;
+       short imm;
+       bool b = s390_constant_via_vrepi_p (x, &mode, &imm);
+       gcc_checking_assert (b);
+       switch (mode)
+         {
+         case QImode:
+           fprintf (file, "%i,0", imm);
+           break;
+         case HImode:
+           fprintf (file, "%i,1", imm);
+           break;
+         case SImode:
+           fprintf (file, "%i,2", imm);
+           break;
+         case DImode:
+           fprintf (file, "%i,3", imm);
+           break;
+         default:
+           gcc_unreachable ();
+         }
+      }
+      return;
+
+    case 'q':
+      {
+       machine_mode mode;
+       int start, end;
+       bool b = s390_constant_via_vgm_p (x, &mode, &start, &end);
+       gcc_checking_assert (b);
+       switch (mode)
+         {
+         case QImode:
+           fprintf (file, "%u,%u,0", start, end);
+           break;
+         case HImode:
+           fprintf (file, "%u,%u,1", start, end);
+           break;
+         case SImode:
+           fprintf (file, "%u,%u,2", start, end);
+           break;
+         case DImode:
+           fprintf (file, "%u,%u,3", start, end);
+           break;
+         default:
+           gcc_unreachable ();
+         }
+      }
+      return;
+
+    case 'r':
+      {
+       unsigned mask;
+       bool b = s390_constant_via_vgbm_p (x, &mask);
+       gcc_checking_assert (b);
+       fprintf (file, "%u", mask);
+      }
+      return;
+
     case 'R':
       {
        struct s390_address ad;
@@ -8773,26 +8966,6 @@ print_operand (FILE *file, rtx x, int code)
          fprintf (file, HOST_WIDE_INT_PRINT_DEC,
                   ((INTVAL (XVECEXP (x, 0, 0)) & 0xffff) ^ 0x8000) - 0x8000);
          break;
-       case 'e':
-       case 's':
-         {
-           int start, end;
-           bool ok;
-
-           ok = s390_contiguous_bitmask_vector_p (x, &start, &end);
-           gcc_assert (ok);
-           ival = (code == 's') ? start : end;
-           fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
-         }
-         break;
-       case 't':
-         {
-           unsigned mask;
-           bool ok = s390_bytemask_vector_p (x, &mask);
-           gcc_assert (ok);
-           fprintf (file, "%u", mask);
-         }
-         break;
 
        default:
          output_operand_lossage ("invalid constant vector for output "
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 2555006bb4b9..303026f6af7c 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -1665,8 +1665,8 @@
 ; FIXME: More constants are possible by enabling jxx, jyy constraints
 ; for TImode (use double-int for the calculations)
 (define_insn "movti"
-  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v,  v,  v,v,d,v,R,d,  
  d, d,    d, d,o")
-        (match_operand:TI 1 "general_operand"      " 
S,d,v,j00,jm1,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
+  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v,  v,  v,  v,  v,  
v,v,d,v,R,d,    d, d,    d, d,o")
+        (match_operand:TI 1 "general_operand"      " 
S,d,v,j00,jm1,jyy,jxx,jzz,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
   "TARGET_ZARCH"
   "@
    lmg\t%0,%N0,%S1
@@ -1674,6 +1674,9 @@
    vlr\t%v0,%v1
    vzero\t%v0
    vone\t%v0
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    vlvgp\t%v0,%1,%N1
    #
    vl\t%v0,%1%A1
@@ -1684,9 +1687,9 @@
    #
    #
    #"
-  [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
-   (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*")
-   (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
+  [(set_attr "op_type" 
"RSY,RSY,VRR,VRI,VRI,VRI,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
+   (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
+   (set_attr "cpu_facility" 
"*,*,vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
 
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 26fd505f2cd9..636788596574 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -249,7 +249,7 @@
 ; vgmb, vgmh, vgmf, vgmg, vrepib, vrepih, vrepif, vrepig
 (define_insn "mov<mode><tf_vr>"
   [(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R,  v,  v,  v,  v, 
 v,v,*d,*d,?o")
-       (match_operand:V_128 1 "general_operand"      " 
v,R,v,j00,jm1,jyy,jxx,jKK,d, v,dT,*d"))]
+       (match_operand:V_128 1 "general_operand"      " 
v,R,v,j00,jm1,jyy,jxx,jzz,d, v,dT,*d"))]
   ""
   "@
    vlr\t%v0,%v1
@@ -257,9 +257,9 @@
    vst\t%v1,%0%A0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm<bhfgq>\t%v0,%s1,%e1
-   vrepi<bhfgq>\t%v0,%h1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    vlvgp\t%v0,%1,%N1
    #
    #
@@ -352,8 +352,8 @@
 ; However, this would probably be slower.
 
 (define_insn "mov<mode>"
-  [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  
v,d,  Q,  S,  Q,  S,  d,  d,d,R,T")
-        (match_operand:V_8 1 "general_operand"      " 
v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,T,d,d"))]
+  [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  
v,  v,d,  Q,  S,  Q,  S,  d,  d,d,R,T")
+        (match_operand:V_8 1 "general_operand"      " 
v,d,v,R,v,j00,jm1,jyy,jxx,jzz,d,j00,j00,jm1,jm1,j00,jm1,T,d,d"))]
   "TARGET_VX"
   "@
    vlr\t%v0,%v1
@@ -363,8 +363,9 @@
    vsteb\t%v1,%0,0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm\t%v0,%s1,%e1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    lr\t%0,%1
    mvi\t%0,0
    mviy\t%0,0
@@ -375,11 +376,11 @@
    llc\t%0,%1
    stc\t%1,%0
    stcy\t%1,%0"
-  [(set_attr "op_type"      
"VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RXY,RX,RXY")])
+  [(set_attr "op_type"      
"VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RXY,RX,RXY")])
 
 (define_insn "mov<mode>"
-  [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  
v,d,  Q,  Q,  d,  d,d,d,d,R,T,b")
-        (match_operand:V_16 1 "general_operand"      " 
v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
+  [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  
v,  v,d,  Q,  Q,  d,  d,d,d,d,R,T,b")
+        (match_operand:V_16 1 "general_operand"      " 
v,d,v,R,v,j00,jm1,jyy,jxx,jzz,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
   ""
   "@
    vlr\t%v0,%v1
@@ -389,8 +390,9 @@
    vsteh\t%v1,%0,0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm\t%v0,%s1,%e1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    lr\t%0,%1
    mvhhi\t%0,0
    mvhhi\t%0,-1
@@ -402,11 +404,11 @@
    sth\t%1,%0
    sthy\t%1,%0
    sthrl\t%1,%0"
-  [(set_attr "op_type"      
"VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
+  [(set_attr "op_type"      
"VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
 
 (define_insn "mov<mode>"
-  [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R,  
f,  v,  v,  v,  v,  Q,  Q,  d,  d,d,d,d,d,R,T,b")
-       (match_operand:V_32 1 "general_operand"      " 
f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
+  [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R,  
f,  v,  v,  v,  v,  v,  Q,  Q,  d,  d,d,d,d,d,R,T,b")
+       (match_operand:V_32 1 "general_operand"      " 
f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,jzz,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
   "TARGET_VX"
   "@
    ldr\t%v0,%v1
@@ -422,8 +424,9 @@
    lzer\t%v0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm\t%v0,%s1,%e1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    mvhi\t%0,0
    mvhi\t%0,-1
    lhi\t%0,0
@@ -435,14 +438,14 @@
    st\t%1,%0
    sty\t%1,%0
    strl\t%1,%0"
-  [(set_attr "op_type" 
"RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
+  [(set_attr "op_type" 
"RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
                         RIL,RR,RX,RXY,RX,RXY,RIL")])
 
 (define_insn "mov<mode>"
   [(set (match_operand:V_64 0 "nonimmediate_operand"
-         "=f,f,f,R,T,v,v,d,v,R,  f,  v,  v,  v,  v,  Q,  Q,  d,  
d,f,d,d,d,d,T,b")
+         "=f,f,f,R,T,v,v,d,v,R,  f,  v,  v,  v,  v,  v,  Q,  Q,  d,  
d,f,d,d,d,d,T,b")
         (match_operand:V_64 1 "general_operand"
-         " 
f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
+         " 
f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,jzz,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
   "TARGET_ZARCH"
   "@
    ldr\t%0,%1
@@ -458,8 +461,9 @@
    lzdr\t%0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm\t%v0,%s1,%e1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    mvghi\t%0,0
    mvghi\t%0,-1
    lghi\t%0,0
@@ -471,7 +475,7 @@
    lg\t%0,%1
    stg\t%1,%0
    stgrl\t%1,%0"
-  [(set_attr "op_type" 
"RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,
+  [(set_attr "op_type" 
"RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,VRI,
                         SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")])
 
 
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-copysign.c 
b/gcc/testsuite/gcc.target/s390/vector/vec-copysign.c
index b723ceb13be9..f5822cf90c7a 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-copysign.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-copysign.c
@@ -1,8 +1,8 @@
 /* { dg-do compile { target { s390*-*-* } } } */
 /* { dg-options "-O2 -ftree-vectorize -mzarch -fno-unroll-loops" } */
-/* { dg-final { scan-assembler-times "vgmg" 1 } } */
-/* { dg-final { scan-assembler-times "vgmf" 1 } } */
-/* { dg-final { scan-assembler-times "vsel" 2 } } */
+/* { dg-final { scan-assembler-times {vgm\t%v[0-9]+,[0-9]+,[0-9]+,3} 1 } } */
+/* { dg-final { scan-assembler-times {vgm\t%v[0-9]+,[0-9]+,[0-9]+,2} 1 } } */
+/* { dg-final { scan-assembler-times {vsel} 2 } } */
 
 #include <math.h>
 
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-genmask-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vec-genmask-1.c
index f3030877ca5d..05da56e6bcf4 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-genmask-1.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-genmask-1.c
@@ -12,14 +12,14 @@ foo1 ()
 {
   return (uv2di){ 0x000fffffffffff00, 0x000fffffffffff00 };
 }
-/* { dg-final { scan-assembler-times "vgmg\t%v24,12,55" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,12,55,3" 1 } } */
 
 uv4si __attribute__((noinline))
 foo2 ()
 {
   return (uv4si){ 0xff00000f, 0xff00000f, 0xff00000f, 0xff00000f };
 }
-/* { dg-final { scan-assembler-times "vgmf\t%v24,28,7" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,28,7,2" 1 } } */
 
 uv8hi __attribute__((noinline))
 foo3a ()
@@ -27,7 +27,7 @@ foo3a ()
   return (uv8hi){ 0xfff0, 0xfff0, 0xfff0, 0xfff0,
       0xfff0, 0xfff0, 0xfff0, 0xfff0 };
 }
-/* { dg-final { scan-assembler-times "vgmh\t%v24,0,11" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,0,11,1" 1 } } */
 
 uv8hi __attribute__((noinline))
 foo3b ()
@@ -35,7 +35,7 @@ foo3b ()
   return (uv8hi){ 0x0fff, 0x0fff, 0x0fff, 0x0fff,
       0x0fff, 0x0fff, 0x0fff, 0x0fff };
 }
-/* { dg-final { scan-assembler-times "vgmh\t%v24,4,15" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,4,15,1" 1 } } */
 
 uv16qi __attribute__((noinline))
 foo4 ()
@@ -45,7 +45,7 @@ foo4 ()
       0x8, 0x8, 0x8, 0x8,
       0x8, 0x8, 0x8, 0x8 };
 }
-/* { dg-final { scan-assembler-times "vgmb\t%v24,4,4" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,4,4,0" 1 } } */
 
 int
 main ()
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-init-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vec-init-1.c
index 4deb6b8db520..b584660161a5 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-init-1.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-init-1.c
@@ -30,7 +30,7 @@ h ()
 {
   return G == 1;
 }
-/* { dg-final { scan-assembler-times "vgmf\t%v.*,31,31" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v.*,31,31,2" 1 } } */
 
 v4si
 i ()
@@ -51,14 +51,14 @@ k ()
 {
   return G == (v4si){ 0xff80, 0xff80, 0xff80, 0xff80 };
 }
-/* { dg-final { scan-assembler-times "vgmf\t%v.*,16,24" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v.*,16,24,2" 1 } } */
 
 v4si
 l ()
 {
   return G == (v4si){ 0xf000000f, 0xf000000f, 0xf000000f, 0xf000000f };
 }
-/* { dg-final { scan-assembler-times "vgmf\t%v.*,28,3" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v.*,28,3,2" 1 } } */
 
 v4si
 m ()
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-vrepi-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vec-vrepi-1.c
index bfb9974342f9..327a2162bb6d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-vrepi-1.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-vrepi-1.c
@@ -12,14 +12,14 @@ foo1 ()
 {
   return (uv2di){ 0x7f0f, 0x7f0f };
 }
-/* { dg-final { scan-assembler-times "vrepig\t%v24,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v24,32527,3" 1 } } */
 
 uv4si __attribute__((noinline))
 foo2 ()
 {
   return (uv4si){ 0x7f0f, 0x7f0f, 0x7f0f, 0x7f0f };
 }
-/* { dg-final { scan-assembler-times "vrepif\t%v24,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v24,32527,2" 1 } } */
 
 uv8hi __attribute__((noinline))
 foo3 ()
@@ -27,7 +27,7 @@ foo3 ()
   return (uv8hi){ 0x7f0f, 0x7f0f, 0x7f0f, 0x7f0f,
       0x7f0f, 0x7f0f, 0x7f0f, 0x7f0f };
 }
-/* { dg-final { scan-assembler-times "vrepih\t%v24,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v24,32527,1" 1 } } */
 
 uv16qi __attribute__((noinline))
 foo4 ()
@@ -37,7 +37,7 @@ foo4 ()
       0x77, 0x77, 0x77, 0x77,
       0x77, 0x77, 0x77, 0x77 };
 }
-/* { dg-final { scan-assembler-times "vrepib\t%v24,119" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v24,119,0" 1 } } */
 
 int
 main ()
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-double-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgbm-double-1.c
new file mode 100644
index 000000000000..0bf445a4fa03
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgbm-double-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+typedef double v1df __attribute__ ((vector_size (8)));
+typedef double v2df __attribute__ ((vector_size (16)));
+
+/*
+** test_v1df:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v1df
+test_v1df (void)
+{
+  return (v1df){7.064161009310759e-304};
+}
+
+/*
+** test_v2df:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v2df
+test_v2df (void)
+{
+  return (v2df){7.064161009310759e-304, 7.064161009310759e-304};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-float-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgbm-float-1.c
new file mode 100644
index 000000000000..7090f9a5c777
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgbm-float-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+typedef float v2sf __attribute__ ((vector_size (8)));
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+/*
+** test_v2sf:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v2sf
+test_v2sf (void)
+{
+  return (v2sf){2.34184089e-38f, 0.f};
+}
+
+/*
+** test_v4sf:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v4sf
+test_v4sf (void)
+{
+  return (v4sf){2.34184089e-38f, 0.f, 2.34184089e-38f, 0.f};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-int128-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgbm-int128-1.c
new file mode 100644
index 000000000000..e8db56c20f96
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgbm-int128-1.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about V1TI const vectors.  Thus, ensure that we end up with
+   a V1TI const vector before expanding.  Likewise, for 128-bit scalar.  */
+/* { dg-final { scan-tree-dump "{ 0xff00ff0000000000ff00ff00000000 }" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "= 0xff00ff0000000000ff00ff00000000;" 
"optimized" } } */
+
+typedef long long v2di __attribute__ ((vector_size (16)));
+typedef __int128 v1ti __attribute__ ((vector_size (16)));
+
+/*
+** test_v1ti:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v1ti
+test_v1ti (void)
+{
+  return (v1ti)(v2di){0xff00ff00000000, 0xff00ff00000000};
+}
+
+/*
+** test_int128:
+**     vgbm    (%v[0-9]+),20560
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128 (void)
+{
+  return ((__int128) 0xff00ff00000000 << 64) | 0xff00ff00000000;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-integer-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgbm-integer-1.c
new file mode 100644
index 000000000000..688f8b26d468
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgbm-integer-1.c
@@ -0,0 +1,115 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+typedef char v8qi __attribute__ ((vector_size (8)));
+typedef char v16qi __attribute__ ((vector_size (16)));
+
+typedef short v4hi __attribute__ ((vector_size (8)));
+typedef short v8hi __attribute__ ((vector_size (16)));
+
+typedef int v2si __attribute__ ((vector_size (8)));
+typedef int v4si __attribute__ ((vector_size (16)));
+
+typedef long long v1di __attribute__ ((vector_size (8)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v8qi:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v8qi
+test_v8qi (void)
+{
+  return (v8qi){0, -1, 0, -1, 0, 0, 0, 0};
+}
+
+/*
+** test_v16qi:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v16qi
+test_v16qi (void)
+{
+  return (v16qi){0, -1, 0, -1, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0};
+}
+
+/*
+** test_v4hi:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v4hi
+test_v4hi (void)
+{
+  return (v4hi){0xff, 0xff, 0, 0};
+}
+
+/*
+** test_v8hi:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v8hi
+test_v8hi (void)
+{
+  return (v8hi){0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0};
+}
+
+/*
+** test_v2si:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v2si
+test_v2si (void)
+{
+  return (v2si){0xff00ff, 0};
+}
+
+/*
+** test_v4si:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v4si
+test_v4si (void)
+{
+  return (v4si){0xff00ff, 0, 0xff00ff, 0};
+}
+
+/*
+** test_v1di:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v1di
+test_v1di (void)
+{
+  return (v1di){0xff00ff00000000};
+}
+
+/*
+** test_v2di:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v2di
+test_v2di (void)
+{
+  return (v2di){0xff00ff00000000, 0xff00ff00000000};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-longdouble-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgbm-longdouble-1.c
new file mode 100644
index 000000000000..e954d3e3135d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgbm-longdouble-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+typedef long double v1tf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1tf:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v1tf
+test_v1tf (void)
+{
+  return (v1tf){9.77049323250296736880493184970933526e-4856L};
+}
+
+/*
+** test_longdouble:
+**     vgbm    (%v[0-9]+),20560
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble (void)
+{
+  return 9.77049323250296736880493184970933526e-4856L;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-df-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-df-1.c
new file mode 100644
index 000000000000..124a4e4624f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-df-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef double v1df __attribute__ ((vector_size (8)));
+typedef double v2df __attribute__ ((vector_size (16)));
+
+/*
+** test_v1df_via_vgmb:
+**     vgm     %v24,0,1,0
+**     br      %r14
+*/
+
+v1df
+test_v1df_via_vgmb (void)
+{
+  return (v1df){-8577.505882352939806878566741943359375};
+}
+
+/*
+** test_v2df_via_vgmb:
+**     vgm     %v24,0,1,0
+**     br      %r14
+*/
+
+v2df
+test_v2df_via_vgmb (void)
+{
+  return (v2df){-8577.505882352939806878566741943359375, 
-8577.505882352939806878566741943359375};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-di-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-di-1.c
new file mode 100644
index 000000000000..bd406a023cf9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-di-1.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef long long v1di __attribute__ ((vector_size (8)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v1di_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmb (void)
+{
+  return (v1di){0xe0e0e0e0e0e0e0e0};
+}
+
+/*
+** test_v2di_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmb (void)
+{
+  return (v2di){0xe0e0e0e0e0e0e0e0, 0xe0e0e0e0e0e0e0e0};
+}
+
+/*
+** test_v1di_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmb_wrap (void)
+{
+  return (v1di){0xe7e7e7e7e7e7e7e7};
+}
+
+/*
+** test_v2di_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmb_wrap (void)
+{
+  return (v2di){0xe7e7e7e7e7e7e7e7, 0xe7e7e7e7e7e7e7e7};
+}
+
+/*
+** test_v1di_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmh (void)
+{
+  return (v1di){0x7e007e007e007e0};
+}
+
+/*
+** test_v2di_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmh (void)
+{
+  return (v2di){0x7e007e007e007e0, 0x7e007e007e007e0};
+}
+
+/*
+** test_v1di_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmf (void)
+{
+  return (v1di){0x7ffffffe7ffffffe};
+}
+
+/*
+** test_v2di_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmf (void)
+{
+  return (v2di){0x7ffffffe7ffffffe, 0x7ffffffe7ffffffe};
+}
+
+/*
+** test_v1di_via_vgmg:
+**     vgm     %v24,17,46,3
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmg (void)
+{
+  return (v1di){0x7ffffffe0000};
+}
+
+/*
+** test_v2di_via_vgmg:
+**     vgm     %v24,17,46,3
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmg (void)
+{
+  return (v2di){0x7ffffffe0000, 0x7ffffffe0000};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-hi-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-hi-1.c
new file mode 100644
index 000000000000..1e0fb68b5cfd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-hi-1.c
@@ -0,0 +1,216 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef short  v1hi __attribute__ ((vector_size (2)));
+typedef short  v2hi __attribute__ ((vector_size (4)));
+typedef short  v4hi __attribute__ ((vector_size (8)));
+typedef short  v8hi __attribute__ ((vector_size (16)));
+
+/*
+** test_v1hi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vgmb (void)
+{
+  return (v1hi){0xe0e0};
+}
+
+/*
+** test_v2hi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vgmb (void)
+{
+  return (v2hi){0xe0e0, 0xe0e0};
+}
+
+/*
+** test_v4hi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmb (void)
+{
+  return (v4hi){0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0};
+}
+
+/*
+** test_v8hi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmb (void)
+{
+  return (v8hi){0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0, 
0xe0e0};
+}
+
+/*
+** test_v1hi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vgmb_wrap (void)
+{
+  return (v1hi){0xe7e7};
+}
+
+/*
+** test_v2hi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vgmb_wrap (void)
+{
+  return (v2hi){0xe7e7, 0xe7e7};
+}
+
+/*
+** test_v4hi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmb_wrap (void)
+{
+  return (v4hi){0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7};
+}
+
+/*
+** test_v8hi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmb_wrap (void)
+{
+  return (v8hi){0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 
0xe7e7};
+}
+
+/*
+** test_v1hi_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vgmh (void)
+{
+  return (v1hi){0x7e0};
+}
+
+/*
+** test_v2hi_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vgmh (void)
+{
+  return (v2hi){0x7e0, 0x7e0};
+}
+
+/*
+** test_v4hi_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmh (void)
+{
+  return (v4hi){0x7e0, 0x7e0, 0x7e0, 0x7e0};
+}
+
+/*
+** test_v8hi_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmh (void)
+{
+  return (v8hi){0x7e0, 0x7e0, 0x7e0, 0x7e0, 0x7e0, 0x7e0, 0x7e0, 0x7e0};
+}
+
+/*
+** test_v2hi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vgmf (void)
+{
+  return (v2hi){0x7fff, 0xfffe};
+}
+
+/*
+** test_v4hi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmf (void)
+{
+  return (v4hi){0x7fff, 0xfffe, 0x7fff, 0xfffe};
+}
+
+/*
+** test_v8hi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmf (void)
+{
+  return (v8hi){0x7fff, 0xfffe, 0x7fff, 0xfffe, 0x7fff, 0xfffe, 0x7fff, 
0xfffe};
+}
+
+/*
+** test_v4hi_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmg (void)
+{
+  return (v4hi){0x7fff, 0xffff, 0xffff, 0xfffe};
+}
+
+/*
+** test_v8hi_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmg (void)
+{
+  return (v8hi){0x7fff, 0xffff, 0xffff, 0xfffe, 0x7fff, 0xffff, 0xffff, 
0xfffe};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-int128-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-int128-1.c
new file mode 100644
index 000000000000..a49ed3e37c18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-int128-1.c
@@ -0,0 +1,69 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about __int128 constants.  Thus, ensure that we end up with
+   128-bit constants before expanding.  */
+/* { dg-final { scan-tree-dump "= 0xe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e;" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "= 0x7ffe7ffe7ffe7ffe7ffe7ffe7ffe7ffe;" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "= 0x7ffffffe7ffffffe7ffffffe7ffffffe;" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "= 0x7ffffffffffffffe7ffffffffffffffe;" 
"optimized" } } */
+
+/*
+** test_int128_via_vgmb:
+**     vgm     (%v[0-9]+),4,6,0
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vgmb (void)
+{
+  return ((__int128) 0x0e0e0e0e0e0e0e0e << 64) | 0x0e0e0e0e0e0e0e0e;
+}
+
+/*
+** test_int128_via_vgmh:
+**     vgm     (%v[0-9]+),1,14,1
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vgmh (void)
+{
+  return ((__int128) 0x7ffe7ffe7ffe7ffe << 64) | 0x7ffe7ffe7ffe7ffe;
+}
+
+/*
+** test_int128_via_vgmf:
+**     vgm     (%v[0-9]+),1,30,2
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vgmf (void)
+{
+  return ((__int128) 0x7ffffffe7ffffffe << 64) | 0x7ffffffe7ffffffe;
+}
+
+/*
+** test_int128_via_vgmg:
+**     vgm     (%v[0-9]+),1,62,3
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vgmg (void)
+{
+  return ((__int128) 0x7ffffffffffffffe << 64) | 0x7ffffffffffffffe;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-longdouble-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-longdouble-1.c
new file mode 100644
index 000000000000..c989ca5ddf7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-longdouble-1.c
@@ -0,0 +1,59 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+/*
+** test_longdouble_via_vgmb:
+**     vgm     (%v[0-9]+),4,6,0
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble_via_vgmb (void)
+{
+  return 2.263171865473961260249112278523378513150597635104e-3849L;
+}
+
+/*
+** test_longdouble_via_vgmh:
+**     vgm     (%v[0-9]+),1,14,1
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble_via_vgmh (void)
+{
+  return 8.9228500591371968978175957554634715383668519805586e+4931L;
+}
+
+/*
+** test_longdouble_via_vgmf:
+**     vgm     (%v[0-9]+),9,30,2
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble_via_vgmf (void)
+{
+  return 5.7202348769040302108562404806917908642856158381792e-4894L;
+}
+
+/*
+** test_longdouble_via_vgmg:
+**     vgm     (%v[0-9]+),9,62,3
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble_via_vgmg (void)
+{
+  return 5.7203220768525291179165318133287569460629228746232e-4894L;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-qi-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-qi-1.c
new file mode 100644
index 000000000000..b39c006f1c67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-qi-1.c
@@ -0,0 +1,241 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef signed char  v1qi __attribute__ ((vector_size (1)));
+typedef signed char  v2qi __attribute__ ((vector_size (2)));
+typedef signed char  v4qi __attribute__ ((vector_size (4)));
+typedef signed char  v8qi __attribute__ ((vector_size (8)));
+typedef signed char  v16qi __attribute__ ((vector_size (16)));
+
+/*
+** test_v1qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v1qi
+test_v1qi_via_vgmb (void)
+{
+  return (v1qi){0xe0};
+}
+
+/*
+** test_v2qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vgmb (void)
+{
+  return (v2qi){0xe0, 0xe0};
+}
+
+/*
+** test_v4qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vgmb (void)
+{
+  return (v4qi){0xe0, 0xe0, 0xe0, 0xe0};
+}
+
+/*
+** test_v8qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmb (void)
+{
+  return (v8qi){0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0};
+}
+
+/*
+** test_v16qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmb (void)
+{
+  return (v16qi){0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 
0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0};
+}
+
+/*
+** test_v1qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v1qi
+test_v1qi_via_vgmb_wrap (void)
+{
+  return (v1qi){0xe7};
+}
+
+/*
+** test_v2qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vgmb_wrap (void)
+{
+  return (v2qi){0xe7, 0xe7};
+}
+
+/*
+** test_v4qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vgmb_wrap (void)
+{
+  return (v4qi){0xe7, 0xe7, 0xe7, 0xe7};
+}
+
+/*
+** test_v8qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmb_wrap (void)
+{
+  return (v8qi){0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7};
+}
+
+/*
+** test_v16qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmb_wrap (void)
+{
+  return (v16qi){0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 
0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7};
+}
+
+/*
+** test_v2qi_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vgmh (void)
+{
+  return (v2qi){0x7f, 0xfe};
+}
+
+/*
+** test_v4qi_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vgmh (void)
+{
+  return (v4qi){0x7f, 0xfe, 0x7f, 0xfe};
+}
+
+/*
+** test_v8qi_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmh (void)
+{
+  return (v8qi){0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe};
+}
+
+/*
+** test_v16qi_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmh (void)
+{
+  return (v16qi){0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 
0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe};
+}
+
+/*
+** test_v4qi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vgmf (void)
+{
+  return (v4qi){0x7f, 0xff, 0xff, 0xfe};
+}
+
+/*
+** test_v8qi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmf (void)
+{
+  return (v8qi){0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe};
+}
+
+/*
+** test_v16qi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmf (void)
+{
+  return (v16qi){0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 
0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe};
+}
+
+/*
+** test_v8qi_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmg (void)
+{
+  return (v8qi){0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe};
+}
+
+/*
+** test_v16qi_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmg (void)
+{
+  return (v16qi){0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-sf-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-sf-1.c
new file mode 100644
index 000000000000..851b97bc9375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-sf-1.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef float v1sf __attribute__ ((vector_size (4)));
+typedef float v2sf __attribute__ ((vector_size (8)));
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1sf_via_vgmb:
+**     vgm     %v24,0,3,0
+**     br      %r14
+*/
+
+v1sf
+test_v1sf_via_vgmb (void)
+{
+  return (v1sf){-5.9654142e29};
+}
+
+/*
+** test_v2sf_via_vgmb:
+**     vgm     %v24,0,3,0
+**     br      %r14
+*/
+
+v2sf
+test_v2sf_via_vgmb (void)
+{
+  return (v2sf){-5.9654142e29, -5.9654142e29};
+}
+
+/*
+** test_v4sf_via_vgmb:
+**     vgm     %v24,0,3,0
+**     br      %r14
+*/
+
+v4sf
+test_v4sf_via_vgmb (void)
+{
+  return (v4sf){-5.9654142e29, -5.9654142e29, -5.9654142e29, -5.9654142e29};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-si-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-si-1.c
new file mode 100644
index 000000000000..32dbd1e69f3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-si-1.c
@@ -0,0 +1,179 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef int  v1si __attribute__ ((vector_size (4)));
+typedef int  v2si __attribute__ ((vector_size (8)));
+typedef int  v4si __attribute__ ((vector_size (16)));
+
+/*
+** test_v1si_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vgmb (void)
+{
+  return (v1si){0xe0e0e0e0};
+}
+
+/*
+** test_v2si_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmb (void)
+{
+  return (v2si){0xe0e0e0e0, 0xe0e0e0e0};
+}
+
+/*
+** test_v4si_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmb (void)
+{
+  return (v4si){0xe0e0e0e0, 0xe0e0e0e0, 0xe0e0e0e0, 0xe0e0e0e0};
+}
+
+/*
+** test_v1si_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vgmb_wrap (void)
+{
+  return (v1si){0xe7e7e7e7};
+}
+
+/*
+** test_v2si_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmb_wrap (void)
+{
+  return (v2si){0xe7e7e7e7, 0xe7e7e7e7};
+}
+
+/*
+** test_v4si_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmb_wrap (void)
+{
+  return (v4si){0xe7e7e7e7, 0xe7e7e7e7, 0xe7e7e7e7, 0xe7e7e7e7};
+}
+
+/*
+** test_v1si_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vgmh (void)
+{
+  return (v1si){0x7e007e0};
+}
+
+/*
+** test_v2si_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmh (void)
+{
+  return (v2si){0x7e007e0, 0x7e007e0};
+}
+
+/*
+** test_v4si_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmh (void)
+{
+  return (v4si){0x7e007e0, 0x7e007e0, 0x7e007e0, 0x7e007e0};
+}
+
+/*
+** test_v1si_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vgmf (void)
+{
+  return (v1si){0x7ffffffe};
+}
+
+/*
+** test_v2si_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmf (void)
+{
+  return (v2si){0x7ffffffe, 0x7ffffffe};
+}
+
+/*
+** test_v4si_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmf (void)
+{
+  return (v4si){0x7ffffffe, 0x7ffffffe, 0x7ffffffe, 0x7ffffffe};
+}
+
+/*
+** test_v2si_via_vgmg:
+**     vgm     %v24,17,46,3
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmg (void)
+{
+  return (v2si){0x7fff, 0xfffe0000};
+}
+
+/*
+** test_v4si_via_vgmg:
+**     vgm     %v24,17,46,3
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmg (void)
+{
+  return (v4si){0x7fff, 0xfffe0000, 0x7fff, 0xfffe0000};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-tf-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-tf-1.c
new file mode 100644
index 000000000000..c88c9e74ac75
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-tf-1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef long double v1tf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1tf_via_vgmb:
+**     vgm     %v24,4,6,0
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vgmb (void)
+{
+  return (v1tf){2.263171865473961260249112278523378513150597635104e-3849L};
+}
+
+/*
+** test_v1tf_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vgmh (void)
+{
+  return (v1tf){8.9228500591371968978175957554634715383668519805586e+4931L};
+}
+
+/*
+** test_v1tf_via_vgmf:
+**     vgm     %v24,9,30,2
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vgmf (void)
+{
+  return (v1tf){5.7202348769040302108562404806917908642856158381792e-4894L};
+}
+
+/*
+** test_v1tf_via_vgmg:
+**     vgm     %v24,9,62,3
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vgmg (void)
+{
+  return (v1tf){5.7203220768525291179165318133287569460629228746232e-4894L};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-ti-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vgm-ti-1.c
new file mode 100644
index 000000000000..5eaeb0c0e8b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vgm-ti-1.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about V1TI const vectors.  Thus, ensure that we end up with
+   a V1TI const vector before expanding.  */
+/* { dg-final { scan-tree-dump "{ 0xe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e }" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "{ 0x7ffe7ffe7ffe7ffe7ffe7ffe7ffe7ffe }" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "{ 0x7ffffffe7ffffffe7ffffffe7ffffffe }" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "{ 0x7ffffffffffffffe7ffffffffffffffe }" 
"optimized" } } */
+
+typedef __int128  v1ti __attribute__ ((vector_size (16)));
+typedef long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v1ti_via_vgmb:
+**     vgm     %v24,4,6,0
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vgmb (void)
+{
+  return (v1ti)(v2di){0x0e0e0e0e0e0e0e0e, 0x0e0e0e0e0e0e0e0e};
+}
+
+/*
+** test_v1ti_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vgmh (void)
+{
+  return (v1ti)(v2di){0x7ffe7ffe7ffe7ffe, 0x7ffe7ffe7ffe7ffe};
+}
+
+/*
+** test_v1ti_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vgmf (void)
+{
+  return (v1ti)(v2di){0x7ffffffe7ffffffe, 0x7ffffffe7ffffffe};
+}
+
+/*
+** test_v1ti_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vgmg (void)
+{
+  return (v1ti)(v2di){0x7ffffffffffffffe, 0x7ffffffffffffffe};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-df-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-df-1.c
new file mode 100644
index 000000000000..62c16e4a2ccb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-df-1.c
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef double v1df __attribute__ ((vector_size (8)));
+typedef double v2df __attribute__ ((vector_size (16)));
+
+/*
+** test_v1df_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1df
+test_v1df_via_vrepib (void)
+{
+  return (v1df){-3.7206620809969885e-103};
+}
+
+/*
+** test_v2df_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2df
+test_v2df_via_vrepib (void)
+{
+  return (v2df){-3.7206620809969885e-103, -3.7206620809969885e-103};
+}
+
+/*
+** test_v1df_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1df
+test_v1df_via_vrepih (void)
+{
+  return (v1df){-2.8368052823634315e-05};
+}
+
+/*
+** test_v2df_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2df
+test_v2df_via_vrepih (void)
+{
+  return (v2df){-2.8368052823634315e-05, -2.8368052823634315e-05};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-di-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-di-1.c
new file mode 100644
index 000000000000..dcd65a5ea97f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-di-1.c
@@ -0,0 +1,106 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef long long v1di __attribute__ ((vector_size (8)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v1di_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vrepib (void)
+{
+  return (v1di){0xaaaaaaaaaaaaaaaa};
+}
+
+/*
+** test_v2di_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vrepib (void)
+{
+  return (v2di){0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa};
+}
+
+/*
+** test_v1di_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vrepih (void)
+{
+  return (v1di){0xbefdbefdbefdbefd};
+}
+
+/*
+** test_v2di_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vrepih (void)
+{
+  return (v2di){0xbefdbefdbefdbefd, 0xbefdbefdbefdbefd};
+}
+
+/*
+** test_v1di_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vrepif (void)
+{
+  return (v1di){0xffffbefdffffbefd};
+}
+
+/*
+** test_v2di_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vrepif (void)
+{
+  return (v2di){0xffffbefdffffbefd, 0xffffbefdffffbefd};
+}
+
+/*
+** test_v1di_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vrepig (void)
+{
+  return (v1di){-16643};
+}
+
+/*
+** test_v2di_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vrepig (void)
+{
+  return (v2di){-16643, -16643};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-hi-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-hi-1.c
new file mode 100644
index 000000000000..5cdf71395107
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-hi-1.c
@@ -0,0 +1,168 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef short v1hi __attribute__ ((vector_size (2)));
+typedef short v2hi __attribute__ ((vector_size (4)));
+typedef short v4hi __attribute__ ((vector_size (8)));
+typedef short v8hi __attribute__ ((vector_size (16)));
+
+/*
+** test_v1hi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vrepib (void)
+{
+  return (v1hi){0xaaaa};
+}
+
+/*
+** test_v2hi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vrepib (void)
+{
+  return (v2hi){0xaaaa, 0xaaaa};
+}
+
+/*
+** test_v4hi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vrepib (void)
+{
+  return (v4hi){0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa};
+}
+
+/*
+** test_v8hi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vrepib (void)
+{
+  return (v8hi){0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 
0xaaaa};
+}
+
+/*
+** test_v1hi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vrepih (void)
+{
+  return (v1hi){-16643};
+}
+
+/*
+** test_v2hi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vrepih (void)
+{
+  return (v2hi){-16643, -16643};
+}
+
+/*
+** test_v4hi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vrepih (void)
+{
+  return (v4hi){-16643, -16643, -16643, -16643};
+}
+
+/*
+** test_v8hi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vrepih (void)
+{
+  return (v8hi){-16643, -16643, -16643, -16643, -16643, -16643, -16643, 
-16643};
+}
+
+/*
+** test_v2hi_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vrepif (void)
+{
+  return (v2hi){-1, -16643};
+}
+
+/*
+** test_v4hi_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vrepif (void)
+{
+  return (v4hi){-1, -16643, -1, -16643};
+}
+
+/*
+** test_v8hi_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vrepif (void)
+{
+  return (v8hi){-1, -16643, -1, -16643, -1, -16643, -1, -16643};
+}
+
+/*
+** test_v4hi_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vrepig (void)
+{
+  return (v4hi){-1, -1, -1, -16643};
+}
+
+/*
+** test_v8hi_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vrepig (void)
+{
+  return (v8hi){-1, -1, -1, -16643, -1, -1, -1, -16643};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-int128-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-int128-1.c
new file mode 100644
index 000000000000..95cb4cbe80df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-int128-1.c
@@ -0,0 +1,69 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about int128 const vectors.  Thus, ensure that we end up 
with
+   a int128 const vector before expanding.  */
+/* { dg-final { scan-tree-dump "= -0x55555555555555555555555555555556;" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "= -0x41024102410241024102410241024103;" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "= -0x4102000041020000410200004103;" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "= -0x41020000000000004103;" "optimized" } } */
+
+/*
+** test_int128_via_vrepib:
+**     vrepi   (%v[0-9]+),-86,0
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vrepib (void)
+{
+  return ((__int128) 0xaaaaaaaaaaaaaaaa << 64) | 0xaaaaaaaaaaaaaaaa;
+}
+
+/*
+** test_int128_via_vrepih:
+**     vrepi   (%v[0-9]+),-16643,1
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vrepih (void)
+{
+  return ((__int128) 0xbefdbefdbefdbefd << 64) | 0xbefdbefdbefdbefd;
+}
+
+/*
+** test_int128_via_vrepif:
+**     vrepi   (%v[0-9]+),-16643,2
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vrepif (void)
+{
+  return ((__int128) 0xffffbefdffffbefd << 64) | 0xffffbefdffffbefd;
+}
+
+/*
+** test_int128_via_vrepig:
+**     vrepi   (%v[0-9]+),-16643,3
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vrepig (void)
+{
+  return ((__int128) 0xffffffffffffbefd << 64) | 0xffffffffffffbefd;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-qi-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-qi-1.c
new file mode 100644
index 000000000000..735e2282e1b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-qi-1.c
@@ -0,0 +1,145 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef signed char v1qi __attribute__ ((vector_size (1)));
+typedef signed char v2qi __attribute__ ((vector_size (2)));
+typedef signed char v4qi __attribute__ ((vector_size (4)));
+typedef signed char v8qi __attribute__ ((vector_size (8)));
+typedef signed char v16qi __attribute__ ((vector_size (16)));
+
+/*
+** test_v1qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1qi
+test_v1qi_via_vrepib (void)
+{
+  return (v1qi){0xaa};
+}
+
+/*
+** test_v2qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vrepib (void)
+{
+  return (v2qi){0xaa, 0xaa};
+}
+
+/*
+** test_v4qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vrepib (void)
+{
+  return (v4qi){0xaa, 0xaa, 0xaa, 0xaa};
+}
+
+/*
+** test_v8qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vrepib (void)
+{
+  return (v8qi){0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
+}
+
+/*
+** test_v16qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vrepib (void)
+{
+  return (v16qi){0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
+}
+
+/*
+** test_v2qi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vrepih (void)
+{
+  return (v2qi){0xbe, 0xfd};
+}
+
+/*
+** test_v4qi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vrepih (void)
+{
+  return (v4qi){0xbe, 0xfd, 0xbe, 0xfd};
+}
+
+/*
+** test_v8qi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vrepih (void)
+{
+  return (v8qi){0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd};
+}
+
+/*
+** test_v16qi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vrepih (void)
+{
+  return (v16qi){0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 
0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd};
+}
+
+/*
+** test_v16qi_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vrepif (void)
+{
+  return (v16qi){-1, -1, 0xbe, 0xfd, -1, -1, 0xbe, 0xfd, -1, -1, 0xbe, 0xfd, 
-1, -1, 0xbe, 0xfd};
+}
+
+/*
+** test_v16qi_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vrepig (void)
+{
+  return (v16qi){-1, -1, -1, -1, -1, -1, 0xbe, 0xfd, -1, -1, -1, -1, -1, -1, 
0xbe, 0xfd};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-sf-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-sf-1.c
new file mode 100644
index 000000000000..4ab0c1f88899
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-sf-1.c
@@ -0,0 +1,83 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef float v1sf __attribute__ ((vector_size (4)));
+typedef float v2sf __attribute__ ((vector_size (8)));
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1sf_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1sf
+test_v1sf_via_vrepib (void)
+{
+  return (v1sf){-3.03164883e-13f};
+}
+
+/*
+** test_v2sf_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2sf
+test_v2sf_via_vrepib (void)
+{
+  return (v2sf){-3.03164883e-13f, -3.03164883e-13f};
+}
+
+/*
+** test_v4sf_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v4sf
+test_v4sf_via_vrepib (void)
+{
+  return (v4sf){-3.03164883e-13f, -3.03164883e-13f, -3.03164883e-13f, 
-3.03164883e-13f};
+}
+
+/*
+** test_v1sf_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1sf
+test_v1sf_via_vrepih (void)
+{
+  return (v1sf){-0.49559775f};
+}
+
+/*
+** test_v2sf_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2sf
+test_v2sf_via_vrepih (void)
+{
+  return (v2sf){-0.49559775f, -0.49559775f};
+}
+
+/*
+** test_v4sf_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v4sf
+test_v4sf_via_vrepih (void)
+{
+  return (v4sf){-0.49559775f, -0.49559775f, -0.49559775f, -0.49559775f};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-si-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-si-1.c
new file mode 100644
index 000000000000..54068286de14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-si-1.c
@@ -0,0 +1,143 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef int v1si __attribute__ ((vector_size (4)));
+typedef int v2si __attribute__ ((vector_size (8)));
+typedef int v4si __attribute__ ((vector_size (16)));
+
+/*
+** test_v1si_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vrepib (void)
+{
+  return (v1si){0xaaaaaaaa};
+}
+
+/*
+** test_v2si_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vrepib (void)
+{
+  return (v2si){0xaaaaaaaa, 0xaaaaaaaa};
+}
+
+/*
+** test_v4si_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vrepib (void)
+{
+  return (v4si){0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa};
+}
+
+/*
+** test_v1si_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vrepih (void)
+{
+  return (v1si){-1090666755};
+}
+
+/*
+** test_v2si_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vrepih (void)
+{
+  return (v2si){-1090666755, -1090666755};
+}
+
+/*
+** test_v4si_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vrepih (void)
+{
+  return (v4si){-1090666755, -1090666755, -1090666755, -1090666755};
+}
+
+/*
+** test_v1si_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vrepif (void)
+{
+  return (v1si){-16643};
+}
+
+/*
+** test_v2si_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vrepif (void)
+{
+  return (v2si){-16643, -16643};
+}
+
+/*
+** test_v4si_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vrepif (void)
+{
+  return (v4si){-16643, -16643, -16643, -16643};
+}
+
+/*
+** test_v2si_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vrepig (void)
+{
+  return (v2si){-1, -16643};
+}
+
+/*
+** test_v4si_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vrepig (void)
+{
+  return (v4si){-1, -16643, -1, -16643};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-tf-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-tf-1.c
new file mode 100644
index 000000000000..37eb7557a380
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-tf-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef long double v1tf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1tf_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vrepib (void)
+{
+  return (v1tf){-1.98172062152833090752940986271726055e-1644L};
+}
+
+/*
+** test_v1tf_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vrepih (void)
+{
+  return (v1tf){-3.76981572984797096816094251528390952e-78L};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-ti-1.c 
b/gcc/testsuite/gcc.target/s390/vector/vrepi-ti-1.c
new file mode 100644
index 000000000000..3966c1183fe7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vrepi-ti-1.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about V1TI const vectors.  Thus, ensure that we end up with
+   a V1TI const vector before expanding.  */
+/* { dg-final { scan-tree-dump "{ -0x55555555555555555555555555555556 }" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "{ -0x41024102410241024102410241024103 }" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "{ -0x4102000041020000410200004103 }" 
"optimized" } } */
+/* { dg-final { scan-tree-dump "{ -0x41020000000000004103 }" "optimized" } } */
+
+typedef __int128 v1ti __attribute__ ((vector_size (16)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v1ti_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vrepib (void)
+{
+  return (v1ti)(v2di){0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa};
+}
+
+/*
+** test_v1ti_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vrepih (void)
+{
+  return (v1ti)(v2di){0xbefdbefdbefdbefd, 0xbefdbefdbefdbefd};
+}
+
+/*
+** test_v1ti_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vrepif (void)
+{
+  return (v1ti)(v2di){0xffffbefdffffbefd, 0xffffbefdffffbefd};
+}
+
+/*
+** test_v1ti_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vrepig (void)
+{
+  return (v1ti)(v2di){-16643, -16643};
+}
diff --git a/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c 
b/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c
index 8948be28ed5d..7d0d0235ad7a 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c
@@ -6,7 +6,7 @@
 AUTOVEC_DOUBLE (QUIET_UNEQ);
 
 /* { dg-final { scan-assembler {\n\tvzero\t} } } */
-/* { dg-final { scan-assembler {\n\tvgmg\t} } } */
+/* { dg-final { scan-assembler {\n\tvgm\t%v[0-9]+,[0-9]+,[0-9]+,3} } } */
 /* { dg-final { scan-assembler-times {\n\tvfchdb\t} 2 } } */
 /* { dg-final { scan-assembler {\n\tvo\t} } } */
 /* { dg-final { scan-assembler {\n\tvsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c 
b/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c
index 0a2aca0d5dd3..1793367c4269 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c
@@ -6,7 +6,7 @@
 AUTOVEC_FLOAT (QUIET_UNEQ);
 
 /* { dg-final { scan-assembler {\n\tvzero\t} } } */
-/* { dg-final { scan-assembler {\n\tvgmf\t} } } */
+/* { dg-final { scan-assembler {\n\tvgm\t%v[0-9]+,[0-9]+,[0-9]+,2} } } */
 /* { dg-final { scan-assembler-times {\n\tvfchsb\t} 2 } } */
 /* { dg-final { scan-assembler {\n\tvo\t} } } */
 /* { dg-final { scan-assembler {\n\tvsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec-genmask-1.c 
b/gcc/testsuite/gcc.target/s390/zvector/vec-genmask-1.c
index 0e57b8dbc053..8acfdc88d27e 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec-genmask-1.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec-genmask-1.c
@@ -24,9 +24,9 @@ bar ()
   f = vec_genmasks_32 (6, 5);
 }
 
-/* a + f: { dg-final { scan-assembler-times "vone" 2 } } */
-/* b: { dg-final { scan-assembler-times "vgmf\t%v.*,0,0" 1 } } */
-/* c: { dg-final { scan-assembler-times "vgmf\t%v.*,31,31" 1 } } */
-/* d: { dg-final { scan-assembler-times "vgmf\t%v.*,5,5" 1 } } */
-/* e: { dg-final { scan-assembler-times "vgmf\t%v.*,31,0" 1 } } */
-/* b - e: { dg-final { scan-assembler-times "vgmf" 4 } } */
+/* a + f: { dg-final { scan-assembler-times {vone} 2 } } */
+/* b: { dg-final { scan-assembler-times {vgm\t%v.*,0,0,2} 1 } } */
+/* c: { dg-final { scan-assembler-times {vgm\t%v.*,31,31,2} 1 } } */
+/* d: { dg-final { scan-assembler-times {vgm\t%v.*,5,5,2} 1 } } */
+/* e: { dg-final { scan-assembler-times {vgm\t%v.*,31,0,2} 1 } } */
+/* b - e: { dg-final { scan-assembler-times {vgm\t%v[0-9]+,[0-9]+,[0-9]+,2} 4 
} } */
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec-splat-1.c 
b/gcc/testsuite/gcc.target/s390/zvector/vec-splat-1.c
index bab2e2d4028f..c57cd2c53a2f 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec-splat-1.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec-splat-1.c
@@ -29,14 +29,14 @@ foo ()
   uv2di = vec_splats ((unsigned long long)0x7f0f);
 }
 
-/* { dg-final { scan-assembler-times "vrepib\t%v.*,119" 1 } } */
-/* { dg-final { scan-assembler-times "vrepib\t%v.*,119" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,119,0" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,119,0" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepih\t%v.*,32527" 1 } } */
-/* { dg-final { scan-assembler-times "vrepih\t%v.*,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,1" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,1" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepif\t%v.*,32527" 1 } } */
-/* { dg-final { scan-assembler-times "vrepif\t%v.*,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,2" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,2" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepig\t%v.*,32527" 1 } } */
-/* { dg-final { scan-assembler-times "vrepig\t%v.*,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,3" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,3" 1 } } */
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec-splat-2.c 
b/gcc/testsuite/gcc.target/s390/zvector/vec-splat-2.c
index 7ad090b2d5ef..73af0e68f9f9 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/vec-splat-2.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec-splat-2.c
@@ -29,14 +29,14 @@ foo ()
   uv2di = vec_splat_u64 (64000);
 }
 
-/* { dg-final { scan-assembler-times "vrepib\t%v.*,-112" 1 } } */
-/* { dg-final { scan-assembler-times "vrepib\t%v.*,-41" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-112,0" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-41,0" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepih\t%v.*,-32000" 1 } } */
-/* { dg-final { scan-assembler-times "vrepih\t%v.*,-1536" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-32000,1" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-1536,1" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepif\t%v.*,-32000" 1 } } */
-/* { dg-final { scan-assembler-times "vrepif\t%v.*,-1536" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-32000,2" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-1536,2" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepig\t%v.*,-32000" 1 } } */
-/* { dg-final { scan-assembler-times "vrepig\t%v.*,-1536" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-32000,3" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-1536,3" 1 } } */

Reply via email to