]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: Skip unnecessary vector extract for certain elements.
authorHaochen Gui <guihaoc@gcc.gnu.org>
Wed, 16 Aug 2023 06:29:36 +0000 (14:29 +0800)
committerHaochen Gui <guihaoc@gcc.gnu.org>
Wed, 16 Aug 2023 06:54:20 +0000 (14:54 +0800)
If the extracted element index is:
  - for byte, 7 on BE while 8 on LE;
  - for half word, 3 on BE while 4 on LE;

the element to be stored is already in the corresponding place for
stxsi[hb]x. We don't need a redundant vector extraction at all.

gcc/
PR target/110429
* config/rs6000/vsx.md (*vsx_extract_<mode>_store_p9): Skip vector
extract when the element is 7 on BE while 8 on LE for byte or 3 on
BE while 4 on LE for halfword.

gcc/testsuite/
PR target/110429
* gcc.target/powerpc/pr110429.c: New.

gcc/config/rs6000/vsx.md
gcc/testsuite/gcc.target/powerpc/pr110429.c [new file with mode: 0644]

index e4192c008fb9d3b3528d9001d2525e6bd904bec5..19abfeb565a6fe201b0ff431ca5c23575a22e80e 100644 (file)
                    (parallel [(match_dup 2)])))
              (clobber (match_dup 4))])
    (set (match_dup 0)
-       (match_dup 3))])
+       (match_dup 3))]
+{
+  if (which_alternative == 0
+      && ((<MODE>mode == V16QImode
+          && INTVAL (operands[2]) == (BYTES_BIG_ENDIAN ? 7 : 8))
+         || (<MODE>mode == V8HImode
+             && INTVAL (operands[2]) == (BYTES_BIG_ENDIAN ? 3 : 4))))
+    {
+      enum machine_mode dest_mode = GET_MODE (operands[0]);
+      emit_move_insn (operands[0],
+                     gen_rtx_REG (dest_mode, REGNO (operands[3])));
+      DONE;
+    }
+})
+
 
 ;; Extract from word 0, 2, 3 (BE order).
 (define_insn_and_split "*vsx_extract_v4si_w023"
diff --git a/gcc/testsuite/gcc.target/powerpc/pr110429.c b/gcc/testsuite/gcc.target/powerpc/pr110429.c
new file mode 100644 (file)
index 0000000..d0ea3e5
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -O2" } */
+/* { dg-require-effective-target has_arch_ppc64 } */
+
+#include <altivec.h>
+
+#ifdef __BIG_ENDIAN__
+#define DWORD0_FIRST_SHORT 3
+#define DWORD0_FIRST_CHAR 7
+#else
+#define DWORD0_FIRST_SHORT 4
+#define DWORD0_FIRST_CHAR 8
+#endif
+
+void vec_extract_short (vector short v, short* p)
+{
+   *p = vec_extract(v, DWORD0_FIRST_SHORT);
+}
+
+void vec_extract_char (vector char v, char* p)
+{
+   *p = vec_extract(v, DWORD0_FIRST_CHAR);
+}
+
+/* { dg-final { scan-assembler-times {\mstxsi[hb]x\M} 2 } } */
+/* { dg-final { scan-assembler-not {\mvextractu[hb]\M} } } */