diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 4bca933195..d0e939918b 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -43343,8 +43343,10 @@ The @samp{org.gnu.gdb.power.fpu} feature is optional.  It should
 contain registers @samp{f0} through @samp{f31} and @samp{fpscr}.
 
 The @samp{org.gnu.gdb.power.altivec} feature is optional.  It should
-contain registers @samp{vr0} through @samp{vr31}, @samp{vscr},
-and @samp{vrsave}.
+contain registers @samp{vr0} through @samp{vr31}, @samp{vscr}, and
+@samp{vrsave}.  @value{GDBN} will define pseudo-registers @samp{v0}
+through @samp{v31} as aliases for the corresponding @samp{vrX}
+registers.
 
 The @samp{org.gnu.gdb.power.vsx} feature is optional.  It should
 contain registers @samp{vs0h} through @samp{vs31h}.  @value{GDBN} will
diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h
index ff3c35ee49..9297fe2b09 100644
--- a/gdb/ppc-tdep.h
+++ b/gdb/ppc-tdep.h
@@ -244,6 +244,10 @@ struct gdbarch_tdep
     int ppc_vr0_regnum;		/* First AltiVec register.  */
     int ppc_vrsave_regnum;	/* Last AltiVec register.  */
 
+    /* Altivec pseudo-register vX aliases for the raw vrX
+       registers.  */
+    int ppc_v0_alias_regnum;
+
     /* SPE registers.  */
     int ppc_ev0_upper_regnum;   /* First GPR upper half register.  */
     int ppc_ev0_regnum;         /* First ev register.  */
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 53da2cc892..e875ad9536 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -36,6 +36,7 @@
 #include "infcall.h"
 #include "sim-regno.h"
 #include "gdb/sim-ppc.h"
+#include "reggroups.h"
 #include "dwarf2-frame.h"
 #include "target-descriptions.h"
 #include "user-regs.h"
@@ -95,6 +96,13 @@
     && (regnum) >= (tdep)->ppc_dl0_regnum \
     && (regnum) < (tdep)->ppc_dl0_regnum + 16)
 
+/* Determine if regnum is a "vX" alias for the raw "vrX" vector
+   registers.  */
+#define IS_V_ALIAS_PSEUDOREG(tdep, regnum) (\
+    (tdep)->ppc_v0_alias_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_v0_alias_regnum \
+    && (regnum) < (tdep)->ppc_v0_alias_regnum + ppc_num_vrs)
+
 /* Determine if regnum is a POWER7 VSX register.  */
 #define IS_VSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_vsr0_regnum >= 0 \
     && (regnum) >= (tdep)->ppc_vsr0_regnum \
@@ -2370,6 +2378,18 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
       return dfp128_regnames[regno - tdep->ppc_dl0_regnum];
     }
 
+  /* Check if this is a vX alias for a raw vrX vector register.  */
+  if (IS_V_ALIAS_PSEUDOREG (tdep, regno))
+    {
+      static const char *const vector_alias_regnames[] = {
+	"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
+	"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
+	"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
+	"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
+      };
+      return vector_alias_regnames[regno - tdep->ppc_v0_alias_regnum];
+    }
+
   /* Check if this is a VSX pseudo-register.  */
   if (IS_VSX_PSEUDOREG (tdep, regno))
     {
@@ -2460,6 +2480,11 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 	   || IS_CDFP_PSEUDOREG (tdep, regnum))
     /* PPC decimal128 pseudo-registers.  */
     return builtin_type (gdbarch)->builtin_declong;
+  else if (IS_V_ALIAS_PSEUDOREG (tdep, regnum))
+    return gdbarch_register_type (gdbarch,
+				  tdep->ppc_vr0_regnum
+				  + (regnum
+				     - tdep->ppc_v0_alias_regnum));
   else if (IS_VSX_PSEUDOREG (tdep, regnum)
 	   || IS_CVSX_PSEUDOREG (tdep, regnum))
     /* POWER7 VSX pseudo-registers.  */
@@ -2475,6 +2500,24 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 		    gdbarch_register_name (gdbarch, regnum), regnum);
 }
 
+/* Check if REGNUM is a member of REGGROUP.  We only need to handle
+   the vX aliases for the vector registers by always returning false
+   to avoid duplicated information in "info register vector/all",
+   since the raw vrX registers will already show in these cases.  For
+   other pseudo-registers we use the default membership function.  */
+
+static int
+rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+				   struct reggroup *group)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (IS_V_ALIAS_PSEUDOREG (tdep, regnum))
+    return 0;
+  else
+    return default_register_reggroup_p (gdbarch, regnum, group);
+}
+
 /* The register format for RS/6000 floating point registers is always
    double, we need a conversion if the memory format is float.  */
 
@@ -2717,6 +2760,35 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     }
 }
 
+/* Read method for the vX aliases for the raw vrX registers.  */
+
+static enum register_status
+v_alias_pseudo_register_read (struct gdbarch *gdbarch,
+			      readable_regcache *regcache, int reg_nr,
+			      gdb_byte *buffer)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+  return regcache->raw_read (tdep->ppc_vr0_regnum
+			     + (reg_nr - tdep->ppc_v0_alias_regnum),
+			     buffer);
+}
+
+/* Write method for the vX aliases for the raw vrX registers.  */
+
+static void
+v_alias_pseudo_register_write (struct gdbarch *gdbarch,
+			       struct regcache *regcache,
+			       int reg_nr, const gdb_byte *buffer)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+  regcache->raw_write (tdep->ppc_vr0_regnum
+		       + (reg_nr - tdep->ppc_v0_alias_regnum), buffer);
+}
+
 /* Read method for POWER7 VSX pseudo-registers.  */
 static enum register_status
 vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
@@ -2886,6 +2958,9 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch,
   else if (IS_DFP_PSEUDOREG (tdep, reg_nr)
 	   || IS_CDFP_PSEUDOREG (tdep, reg_nr))
     return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+  else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr))
+    return v_alias_pseudo_register_read (gdbarch, regcache, reg_nr,
+					 buffer);
   else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
 	   || IS_CVSX_PSEUDOREG (tdep, reg_nr))
     return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
@@ -2914,6 +2989,8 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch,
   else if (IS_DFP_PSEUDOREG (tdep, reg_nr)
 	   || IS_CDFP_PSEUDOREG (tdep, reg_nr))
     dfp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
+  else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr))
+    v_alias_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
   else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
 	   || IS_CVSX_PSEUDOREG (tdep, reg_nr))
     vsx_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
@@ -2954,6 +3031,20 @@ dfp_ax_pseudo_register_collect (struct gdbarch *gdbarch,
   ax_reg_mask (ax, fp0 + 2 * reg_index + 1);
 }
 
+/* Set the register mask in AX with the raw vector register that
+   corresponds to its REG_NR alias.  */
+
+static void
+v_alias_pseudo_register_collect (struct gdbarch *gdbarch,
+				 struct agent_expr *ax, int reg_nr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+  ax_reg_mask (ax, tdep->ppc_vr0_regnum
+	       + (reg_nr - tdep->ppc_v0_alias_regnum));
+}
+
 /* Set the register mask in AX with the registers that form the VSX or
    checkpointed VSX pseudo-register REG_NR.  */
 
@@ -3034,6 +3125,10 @@ rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
     {
       dfp_ax_pseudo_register_collect (gdbarch, ax, reg_nr);
     }
+  else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr))
+    {
+      v_alias_pseudo_register_collect (gdbarch, ax, reg_nr);
+    }
   else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
 	   || IS_CVSX_PSEUDOREG (tdep, reg_nr))
     {
@@ -6891,7 +6986,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     tdep->lr_frame_offset = 4;
 
-  if (have_spe || have_dfp || have_vsx || have_htm_fpu || have_htm_vsx)
+  if (have_spe || have_dfp || have_altivec
+      || have_vsx || have_htm_fpu || have_htm_vsx)
     {
       set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
       set_gdbarch_pseudo_register_write (gdbarch,
@@ -6910,6 +7006,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     num_pseudoregs += 32;
   if (have_dfp)
     num_pseudoregs += 16;
+  if (have_altivec)
+    num_pseudoregs += 32;
   if (have_vsx)
     /* Include both VSX and Extended FP registers.  */
     num_pseudoregs += 96;
@@ -7022,6 +7120,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type);
+  set_tdesc_pseudo_register_reggroup_p (gdbarch,
+					rs6000_pseudo_register_reggroup_p);
   tdesc_use_registers (gdbarch, tdesc, tdesc_data);
 
   /* Override the normal target description method to make the SPE upper
@@ -7031,6 +7131,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Choose register numbers for all supported pseudo-registers.  */
   tdep->ppc_ev0_regnum = -1;
   tdep->ppc_dl0_regnum = -1;
+  tdep->ppc_v0_alias_regnum = -1;
   tdep->ppc_vsr0_regnum = -1;
   tdep->ppc_efpr0_regnum = -1;
   tdep->ppc_cdl0_regnum = -1;
@@ -7049,6 +7150,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       tdep->ppc_dl0_regnum = cur_reg;
       cur_reg += 16;
     }
+  if (have_altivec)
+    {
+      tdep->ppc_v0_alias_regnum = cur_reg;
+      cur_reg += 32;
+    }
   if (have_vsx)
     {
       tdep->ppc_vsr0_regnum = cur_reg;
diff --git a/gdb/testsuite/gdb.arch/altivec-regs.exp b/gdb/testsuite/gdb.arch/altivec-regs.exp
index 5647fb5e86..5e4f575cf5 100644
--- a/gdb/testsuite/gdb.arch/altivec-regs.exp
+++ b/gdb/testsuite/gdb.arch/altivec-regs.exp
@@ -91,7 +91,8 @@ set vector_register ".uint128 = 0x1000000010000000100000001, v4_float = .0x0, 0x
 }
 
 for {set i 0} {$i < 32} {incr i 1} {
-        gdb_test "info reg vr$i" "vr$i.*$vector_register" "info reg vr$i"
+    gdb_test "info reg vr$i" "vr$i.*$vector_register" "info reg vr$i"
+    gdb_test "info reg v$i" "v$i.*$vector_register" "info reg v$i"
 }
 
 gdb_test "info reg vrsave" "vrsave.*0x1\[ \t\]+1" "info reg vrsave"
@@ -110,7 +111,8 @@ if {$endianness == "big"} {
 }
 
 for {set i 0} {$i < 32} {incr i 1} {
-        gdb_test "print \$vr$i" ".* = $decimal_vector" "print vr$i"
+    gdb_test "print \$vr$i" ".* = $decimal_vector" "print vr$i"
+    gdb_test "print \$v$i" ".* = $decimal_vector" "print v$i"
 }
 
 gdb_test "print \$vrsave" ".* = 1" "print vrsave"
diff --git a/gdb/testsuite/gdb.arch/powerpc-vector-regs.c b/gdb/testsuite/gdb.arch/powerpc-vector-regs.c
new file mode 100644
index 0000000000..925f0d7916
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-vector-regs.c
@@ -0,0 +1,59 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Write bytes with values ranging from 0 to 31 to each byte of each
+   corresponding vector register.  */
+int main (void)
+{
+  asm volatile ("vspltisb 0, 0" : : : "v0");
+  asm volatile ("vspltisb 1, 1" : : : "v1");
+
+  asm volatile ("vaddubm 2, 1, 1" : : : "v2");
+  asm volatile ("vaddubm 3, 2, 1" : : : "v3");
+  asm volatile ("vaddubm 4, 3, 1" : : : "v4");
+  asm volatile ("vaddubm 5, 4, 1" : : : "v5");
+  asm volatile ("vaddubm 6, 5, 1" : : : "v6");
+  asm volatile ("vaddubm 7, 6, 1" : : : "v7");
+  asm volatile ("vaddubm 8, 7, 1" : : : "v8");
+  asm volatile ("vaddubm 9, 8, 1" : : : "v9");
+  asm volatile ("vaddubm 10, 9, 1" : : : "v10");
+  asm volatile ("vaddubm 11, 10, 1" : : : "v11");
+  asm volatile ("vaddubm 12, 11, 1" : : : "v12");
+  asm volatile ("vaddubm 13, 12, 1" : : : "v13");
+  asm volatile ("vaddubm 14, 13, 1" : : : "v14");
+  asm volatile ("vaddubm 15, 14, 1" : : : "v15");
+  asm volatile ("vaddubm 16, 15, 1" : : : "v16");
+  asm volatile ("vaddubm 17, 16, 1" : : : "v17");
+  asm volatile ("vaddubm 18, 17, 1" : : : "v18");
+  asm volatile ("vaddubm 19, 18, 1" : : : "v19");
+  asm volatile ("vaddubm 20, 19, 1" : : : "v20");
+  asm volatile ("vaddubm 21, 20, 1" : : : "v21");
+  asm volatile ("vaddubm 22, 21, 1" : : : "v22");
+  asm volatile ("vaddubm 23, 22, 1" : : : "v23");
+  asm volatile ("vaddubm 24, 23, 1" : : : "v24");
+  asm volatile ("vaddubm 25, 24, 1" : : : "v25");
+  asm volatile ("vaddubm 26, 25, 1" : : : "v26");
+  asm volatile ("vaddubm 27, 26, 1" : : : "v27");
+  asm volatile ("vaddubm 28, 27, 1" : : : "v28");
+  asm volatile ("vaddubm 29, 28, 1" : : : "v29");
+  asm volatile ("vaddubm 30, 29, 1" : : : "v30");
+  asm volatile ("vaddubm 31, 30, 1" : : : "v31");
+
+  asm volatile ("nop"); // marker
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp b/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp
new file mode 100644
index 0000000000..fdf7c5662d
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp
@@ -0,0 +1,62 @@
+# Copyright (C) 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+# Test vector register access on Power.  The inferior executes
+# instructions that fill the vector registers with values ranging from
+# 0 to 31 in each of the 16 bytes of each corresponding register, and
+# we then check if gdb sees these same values.
+
+if {![istarget "powerpc*"] || [skip_altivec_tests]} {
+    verbose "Skipping PowerPC vector register tests."
+    return
+}
+
+standard_testfile
+
+if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable {debug}] != "" } {
+    untested "vector register tests for PowerPC"
+    return
+}
+
+# Check if our test binary can actually run on this processor.
+clean_restart ${binfile}
+
+gdb_run_cmd
+
+gdb_test_multiple "" "wait for exit" {
+    -re ".*Illegal instruction.*${gdb_prompt} $" {
+	unsupported "vector register tests for PowerPC"
+	return
+    }
+    -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
+    }
+}
+
+# Run the actual test.
+clean_restart ${binfile}
+
+gdb_breakpoint [gdb_get_line_number "marker"]
+
+gdb_run_cmd
+
+# Wait for the prompt.
+gdb_test "" "Breakpoint.*at.*" "wait for prompt"
+
+for {set i 0} {$i < 32} {incr i 1} {
+    gdb_test "p/z \$vr$i.uint128" ".* = 0x(0?[format %x $i]){16}.*"
+    gdb_test "p/z \$v$i.uint128" ".* = 0x(0?[format %x $i]){16}.*"
+}
diff --git a/gdb/testsuite/gdb.arch/vsx-regs.exp b/gdb/testsuite/gdb.arch/vsx-regs.exp
index 2454aee352..d2fa612699 100644
--- a/gdb/testsuite/gdb.arch/vsx-regs.exp
+++ b/gdb/testsuite/gdb.arch/vsx-regs.exp
@@ -136,6 +136,7 @@ for {set i 32} {$i < 64} {incr i 1} {
 
 for {set i 0} {$i < 32} {incr i 1} {
     gdb_test "info reg vr$i" "vr$i.*$vector_register3_vr" "info reg vr$i"
+    gdb_test "info reg v$i" "v$i.*$vector_register3_vr" "info reg v$i"
 }
 
 # Create a core file.  We create the core file before the F32~F63/VR0~VR31 test
@@ -155,6 +156,7 @@ for {set i 32} {$i < 64} {incr i 1} {
 
 for {set i 0} {$i < 32} {incr i 1} {
     gdb_test "info reg vr$i" "vr$i.*$vector_register1_vr" "info reg vr$i (doubleword 0)"
+    gdb_test "info reg v$i" "v$i.*$vector_register1_vr" "info reg v$i (doubleword 0)"
 }
 
 # 2: Set VR0~VR31 registers and check if it reflects on F32~F63.
@@ -170,6 +172,7 @@ for {set i 32} {$i < 64} {incr i 1} {
 
 for {set i 0} {$i < 32} {incr i 1} {
     gdb_test "info reg vr$i" "vr$i.*$vector_register2_vr" "info reg vr$i (doubleword 1)"
+    gdb_test "info reg v$i" "v$i.*$vector_register2_vr" "info reg v$i (doubleword 1)"
 }
 
 # Test reading the core file.
