public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Michael Meissner <meissner@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
Date: Wed, 26 Apr 2023 23:59:38 +0000 (GMT)	[thread overview]
Message-ID: <20230426235938.036393858D3C@sourceware.org> (raw)

https://gcc.gnu.org/g:fd4678813d4e738ac876fed4eaa4ecd51c854568

commit fd4678813d4e738ac876fed4eaa4ecd51c854568
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Wed Apr 26 19:59:20 2023 -0400

    Allow constant element vec_extract to be converted to floating point
    
    This patch allows vec_extract of the following types to be converted to
    floating point by loading the value directly to the vector register, and then
    doing the conversion instead of loading the value to a GPR and then doing a
    direct move:
    
            vector int
            vector unsigned int
            vector unsigned short
            vector unsigned char
    
    2023-04-26   Michael Meissner  <meissner@linux.ibm.com>
    
    gcc/
    
            * config/rs6000/rs6000.md (fp_int_extend): New code attribute.
            * config/rs6000/vsx.md (vsx_extract_v4si_load_to_<uns><mode>): New
            * insn.
            * vsx_extract_<VSX_EXTRACT_I2:mode>_load_to_uns<SFDF:mode>: New insn.
    
    gcc/testsuite/
    
            * gcc.target/powerpc/vec-extract-mem-char-2.c: New file.
            * gcc.target/powerpc/vec-extract-mem-int-4.c: New file.
            * gcc.target/powerpc/vec-extract-mem-int_5.c: New file.
            * gcc.target/powerpc/vec-extract-mem-short-4.c: New file.

Diff:
---
 gcc/config/rs6000/rs6000.md                        |  3 ++
 gcc/config/rs6000/vsx.md                           | 56 ++++++++++++++++++++++
 .../gcc.target/powerpc/vec-extract-mem-char-2.c    | 40 ++++++++++++++++
 .../gcc.target/powerpc/vec-extract-mem-int-4.c     | 40 ++++++++++++++++
 .../gcc.target/powerpc/vec-extract-mem-int-5.c     | 40 ++++++++++++++++
 .../gcc.target/powerpc/vec-extract-mem-short-4.c   | 40 ++++++++++++++++
 6 files changed, 219 insertions(+)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 7d6c94aee5b..b1e3750f528 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -664,6 +664,9 @@
 		       (float		"")
 		       (unsigned_float	"uns")])
 
+(define_code_attr fp_int_extend [(float          "sign_extend")
+				 (unsigned_float "zero_extend")])
+
 ; Various instructions that come in SI and DI forms.
 ; A generic w/d attribute, for things like cmpw/cmpd.
 (define_mode_attr wd [(QI    "b")
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 4a93523090a..bbc049dc44f 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -4045,6 +4045,62 @@
    (set_attr "length" "*,*,8,*,8")
    (set_attr "isa" "*,*,*,p9v,p9v")])
 
+;; Fold extracting a V4SI element with a constant element with either sign or
+;; zero extension to SFmode or DFmode into LFIWAX/LFIWZX and FCFID.
+(define_insn_and_split "*vsx_extract_v4si_load_to_<uns><mode>"
+  [(set (match_operand:SFDF 0 "register_operand" "=wa,wa")
+	(any_float:SFDF
+	 (vec_select:SI
+	  (match_operand:V4SI 1 "memory_operand" "Z,Q")
+	  (parallel [(match_operand:QI 2 "const_0_to_3_operand" "O,n")]))))
+   (clobber (match_scratch:DI 3 "=X,&b"))
+   (clobber (match_scratch:DI 4 "=wa,wa"))]
+  "VECTOR_MEM_VSX_P (V4SImode) && TARGET_DIRECT_MOVE_64BIT"
+  "#"
+  "&& 1"
+  [(set (match_dup 4)
+	(<fp_int_extend>:DI (match_dup 5)))
+   (set (match_dup 0)
+	(float:SFDF (match_dup 4)))]
+{
+  if (GET_CODE (operands[4]) == SCRATCH)
+    operands[4] = gen_reg_rtx (DImode);
+  
+  operands[5] = rs6000_adjust_vec_address (operands[0], operands[1],
+					   operands[2], operands[3],
+					   SImode);
+}
+  [(set_attr "type" "fpload")
+   (set_attr "length" "8,12")])
+
+;; Fold extracting a V8HI/V16QI element with a constant element with zero
+;; extension to SFmode or DFmode into LXSIBZX/LXSIHZX and FCFID
+(define_insn_and_split "*vsx_extract_<VSX_EXTRACT_I2:mode>_load_to_uns<SFDF:mode>"
+  [(set (match_operand:SFDF 0 "register_operand" "=wa,wa")
+	(unsigned_float:SFDF
+	 (vec_select:<VSX_EXTRACT_I2:VEC_base>
+	  (match_operand:VSX_EXTRACT_I2 1 "memory_operand" "Z,Q")
+	  (parallel [(match_operand:QI 2 "const_int_operand" "O,n")]))))
+   (clobber (match_scratch:DI 3 "=X,&b"))
+   (clobber (match_scratch:DI 4 "=v,v"))]
+  "VECTOR_MEM_VSX_P (<VSX_EXTRACT_I2:MODE>mode) && TARGET_P9_VECTOR"
+  "#"
+  "&& 1"
+  [(set (match_dup 4)
+	(zero_extend:DI (match_dup 5)))
+   (set (match_dup 0)
+	(float:SFDF (match_dup 4)))]
+{
+  if (GET_CODE (operands[4]) == SCRATCH)
+    operands[4] = gen_reg_rtx (DImode);
+  
+  operands[5] = rs6000_adjust_vec_address (operands[0], operands[1],
+					   operands[2], operands[3],
+					   <VSX_EXTRACT_I2:VEC_base>mode);
+}
+  [(set_attr "type" "fpload")
+   (set_attr "length" "8,12")])
+
 ;; Fold extracting a V8HI element with a constant element with sign extension
 ;; to either DImode or SImode.
 (define_insn_and_split "*vsx_extract_v8hi_load_to_s<mode>"
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-char-2.c b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-char-2.c
new file mode 100644
index 00000000000..fd6b6d03699
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-char-2.c
@@ -0,0 +1,40 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
+
+/* Test to verify that the vec_extract with constant element numbers can load
+   QImode and convert it to unsigned floating point, by loading the value
+   directly to a vector register, rather than loading up a GPR and transfering
+   the result to a vector register..  */
+
+#include <altivec.h>
+
+double
+extract_dbl_uns_v16qi_0 (vector unsigned char *p)
+{
+  return vec_extract (*p, 0);	/* lxsibzx, fcfid/xscvsxddp.  */
+}
+
+double
+extract_dbl_uns_v16qi_1 (vector unsigned char *p)
+{
+  return vec_extract (*p, 1);	/* lxsibzx, fcfid/xscvsxddp.  */
+}
+
+float
+extract_flt_uns_v16qi_element_0_index_4 (vector unsigned char *p)
+{
+  return vec_extract (p[4], 0);	/* lxsibzx, fcfids/xscvsxdsp.  */
+}
+
+float
+extract_flt_uns_v16qi_element_3_index_4 (vector unsigned char *p)
+{
+  return vec_extract (p[4], 3);	/* lxsibzx, fcfids/xscvsxdsp.  */
+}
+
+/* { dg-final { scan-assembler-times {\mlxsibzx\M}            4 } } */
+/* { dg-final { scan-assembler-times {\mfcfid\M|\mxscvsxddp}  2 } } */
+/* { dg-final { scan-assembler-times {\mfcfids\M|\mxscvsxdsp} 2 } } */
+/* { dg-final { scan-assembler-not   {\mlbzx?\M}                } } */
+/* { dg-final { scan-assembler-not   {\mmtvsr}                  } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-int-4.c b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-int-4.c
new file mode 100644
index 00000000000..79f634b33b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-int-4.c
@@ -0,0 +1,40 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
+
+/* Test to verify that the vec_extract with constant element numbers can load
+   SImode and convert it to unsigned floating point, by loading the value
+   directly to a vector register, rather than loading up a GPR and transfering
+   the result to a vector register..  */
+
+#include <altivec.h>
+
+double
+extract_dbl_uns_v4si_0 (vector unsigned int *p)
+{
+  return vec_extract (*p, 0);	/* lfiwzx/lxsiwzx, fcfid/xscvsxddp.  */
+}
+
+double
+extract_dbl_uns_v4si_1 (vector unsigned int *p)
+{
+  return vec_extract (*p, 1);	/* lfiwzx/lxsiwzx, fcfid/xscvsxddp.  */
+}
+
+float
+extract_flt_uns_v4si_element_0_index_4 (vector unsigned int *p)
+{
+  return vec_extract (p[4], 0);	/* lfiwzx/lxsiwzx, fcfids/xscvsxdsp.  */
+}
+
+float
+extract_flt_uns_v4si_element_3_index_4 (vector unsigned int *p)
+{
+  return vec_extract (p[4], 3);	/* lfiwzx/lxsiwzx, fcfids/xscvsxdsp.  */
+}
+
+/* { dg-final { scan-assembler-times {\mlfiwzx\M|\mlxsiwzx\M}   4 } } */
+/* { dg-final { scan-assembler-times {\mfcfid\M|\mxscvsxddp\M}  2 } } */
+/* { dg-final { scan-assembler-times {\mfcfids\M|\mxscvsxdsp\M} 2 } } */
+/* { dg-final { scan-assembler-not   {\mlw[az]x?\M}               } } */
+/* { dg-final { scan-assembler-not   {\mmtvsr}                    } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-int-5.c b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-int-5.c
new file mode 100644
index 00000000000..d51d26482c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-int-5.c
@@ -0,0 +1,40 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
+
+/* Test to verify that the vec_extract with constant element numbers can load
+   SImode and convert it to signed floating point, by loading the value
+   directly to a vector register, rather than loading up a GPR and transfering
+   the result to a vector register..  */
+
+#include <altivec.h>
+
+double
+extract_dbl_sign_v4si_0 (vector int *p)
+{
+  return vec_extract (*p, 0);	/* lfiwzx/lxsiwzx, fcfid/xscvsxddp.  */
+}
+
+double
+extract_dbl_sign_v4si_1 (vector int *p)
+{
+  return vec_extract (*p, 1);	/* lfiwzx/lxsiwzx, fcfid/xscvsxddp.  */
+}
+
+float
+extract_flt_sign_v4si_element_0_index_4 (vector int *p)
+{
+  return vec_extract (p[4], 0);	/* lfiwzx/lxsiwzx, fcfids/xscvsxdsp.  */
+}
+
+float
+extract_flt_sign_v4si_element_3_index_4 (vector int *p)
+{
+  return vec_extract (p[4], 3);	/* lfiwzx/lxsiwzx, fcfids/xscvsxdsp.  */
+}
+
+/* { dg-final { scan-assembler-times {\mlfiwax\M|\mlxsiwax\M}   4 } } */
+/* { dg-final { scan-assembler-times {\mfcfid\M|\mxscvsxddp\M}  2 } } */
+/* { dg-final { scan-assembler-times {\mfcfids\M|\mxscvsxdsp\M} 2 } } */
+/* { dg-final { scan-assembler-not   {\mlw[az]x?\M}               } } */
+/* { dg-final { scan-assembler-not   {\mmtvsr}                    } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-short-4.c b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-short-4.c
new file mode 100644
index 00000000000..24ad6fd3a7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-short-4.c
@@ -0,0 +1,40 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
+
+/* Test to verify that the vec_extract with constant element numbers can load
+   HImode and convert it to unsigned floating point, by loading the value
+   directly to a vector register, rather than loading up a GPR and transfering
+   the result to a vector register..  */
+
+#include <altivec.h>
+
+double
+extract_dbl_uns_v8hi_0 (vector unsigned short *p)
+{
+  return vec_extract (*p, 0);	/* lxsihzx, fcfid/xscvsxddp.  */
+}
+
+double
+extract_dbl_uns_v8hi_1 (vector unsigned short *p)
+{
+  return vec_extract (*p, 1);	/* lxsihzx, fcfid/xscvsxddp.  */
+}
+
+float
+extract_flt_uns_v8hi_element_0_index_4 (vector unsigned short *p)
+{
+  return vec_extract (p[4], 0);	/* lxsihzx, fcfids/xscvsxdsp.  */
+}
+
+float
+extract_flt_uns_v8hi_element_3_index_4 (vector unsigned short *p)
+{
+  return vec_extract (p[4], 3);	/* lxsihzx, fcfids/xscvsxdsp.  */
+}
+
+/* { dg-final { scan-assembler-times {\mlxsihzx\M}              4 } } */
+/* { dg-final { scan-assembler-times {\mfcfid\M|\mxscvsxddp\M}  2 } } */
+/* { dg-final { scan-assembler-times {\mfcfids\M|\mxscvsxdsp\M} 2 } } */
+/* { dg-final { scan-assembler-not   {\mlh[az]x?\M}               } } */
+/* { dg-final { scan-assembler-not   {\mmtvsr}                    } } */

             reply	other threads:[~2023-04-26 23:59 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-26 23:59 Michael Meissner [this message]
  -- strict thread matches above, loose matches on Subject: below --
2023-04-29  3:51 Michael Meissner
2023-04-28 19:18 Michael Meissner
2023-04-28 18:58 Michael Meissner
2023-04-28  6:36 Michael Meissner
2023-04-28  3:43 Michael Meissner
2023-04-27  3:06 Michael Meissner
2023-04-26 23:43 Michael Meissner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230426235938.036393858D3C@sourceware.org \
    --to=meissner@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).