aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKewen Lin <linkw@linux.ibm.com>2020-12-16 00:28:44 -0600
committerKewen Lin <linkw@linux.ibm.com>2020-12-16 02:12:08 -0600
commit31008a8bb30d8979bba5240be6b504140c5665ff (patch)
treebfe0ba276beb88f025a38c239bc54a981c05734e /gcc
parenta3bac40469b7052bfadc21cad0e53f40b147e937 (diff)
downloadgcc-31008a8bb30d8979bba5240be6b504140c5665ff.zip
gcc-31008a8bb30d8979bba5240be6b504140c5665ff.tar.gz
gcc-31008a8bb30d8979bba5240be6b504140c5665ff.tar.bz2
rs6000: Use subreg for QI/HI vector init
This patch is to use paradoxical subreg instead of zero_extend for promoting QI/HI to SI/DI when we want to construct one vector with these modes. Since we do the gpr->vsx movement and vector merge or pack later, the high part is useless and safe to use paradoxical subreg. It can avoid useless rlwinms generated for signed cases. Bootstrapped/regtested on powerpc64le-linux-gnu P9. gcc/ChangeLog: * config/rs6000/rs6000.c (rs6000_expand_vector_init): Use paradoxical subreg instead of zero_extend for QI/HI promotion. gcc/testsuite/ChangeLog: * gcc.target/powerpc/pr96933-1.c: Adjusted to check no rlwinm. * gcc.target/powerpc/pr96933-2.c: Likewise.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/rs6000/rs6000.c14
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr96933-1.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr96933-2.c1
3 files changed, 5 insertions, 11 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index f26fc13..cf17213 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -6806,17 +6806,9 @@ rs6000_expand_vector_init (rtx target, rtx vals)
/* Force the values into word_mode registers. */
for (i = 0; i < n_elts; i++)
{
- rtx tmp = force_reg (GET_MODE_INNER (mode), XVECEXP (vals, 0, i));
- if (TARGET_POWERPC64)
- {
- op[i] = gen_reg_rtx (DImode);
- emit_insn (gen_zero_extendqidi2 (op[i], tmp));
- }
- else
- {
- op[i] = gen_reg_rtx (SImode);
- emit_insn (gen_zero_extendqisi2 (op[i], tmp));
- }
+ rtx tmp = force_reg (inner_mode, XVECEXP (vals, 0, i));
+ machine_mode tmode = TARGET_POWERPC64 ? DImode : SImode;
+ op[i] = simplify_gen_subreg (tmode, tmp, inner_mode, 0);
}
/* Take unsigned char big endianness on 64bit as example for below
diff --git a/gcc/testsuite/gcc.target/powerpc/pr96933-1.c b/gcc/testsuite/gcc.target/powerpc/pr96933-1.c
index 3b63865..71d7208 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr96933-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr96933-1.c
@@ -13,3 +13,4 @@
/* { dg-final { scan-assembler-times {\mvpkudum\M} 12 } } */
/* { dg-final { scan-assembler-not {\mstb\M} } } */
/* { dg-final { scan-assembler-not {\msth\M} } } */
+/* { dg-final { scan-assembler-not {\mrlwinm\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr96933-2.c b/gcc/testsuite/gcc.target/powerpc/pr96933-2.c
index cef8fbd..9fa1512 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr96933-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr96933-2.c
@@ -13,3 +13,4 @@
/* { dg-final { scan-assembler-times {\mxxpermdi\M} 4 } } */
/* { dg-final { scan-assembler-not {\mstb\M} } } */
/* { dg-final { scan-assembler-not {\msth\M} } } */
+/* { dg-final { scan-assembler-not {\mrlwinm\M} } } */