public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
@ 2023-04-27 3:06 Michael Meissner
0 siblings, 0 replies; 8+ messages in thread
From: Michael Meissner @ 2023-04-27 3:06 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8b9ffd91171fcb5fbb565ca434013a145b65055f
commit 8b9ffd91171fcb5fbb565ca434013a145b65055f
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Wed Apr 26 23:05:48 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 ++++++++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 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 c21571a03cf..2a5a9b45e34 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>"
--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} } } */
--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} } } */
--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} } } */
--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} } } */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
@ 2023-04-29 3:51 Michael Meissner
0 siblings, 0 replies; 8+ messages in thread
From: Michael Meissner @ 2023-04-29 3:51 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:7c7742d904f6d629bba309a7e854d28d3d0d0d30
commit 7c7742d904f6d629bba309a7e854d28d3d0d0d30
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Fri Apr 28 23:51:29 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-28 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 | 50 ++++++++++++++++++++++
| 41 ++++++++++++++++++
| 40 +++++++++++++++++
| 40 +++++++++++++++++
| 41 ++++++++++++++++++
6 files changed, 215 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 8fc56bff892..559a7034367 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -4113,6 +4113,56 @@
(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"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (<fp_int_extend>:DI (match_dup 5)))
+ (set (match_dup 0)
+ (float:SFDF (match_dup 4)))]
+{
+ operands[5] = rs6000_adjust_vec_address (operands[0], operands[1],
+ operands[2], operands[3],
+ SImode);
+}
+ [(set_attr "type" "fpload")
+ (set_attr "length" "8")])
+
+;; 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"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (zero_extend:DI (match_dup 5)))
+ (set (match_dup 0)
+ (float:SFDF (match_dup 4)))]
+{
+ 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")])
+
;; Fold extracting a V8HI element with a constant element with sign extension
;; to either DImode or SImode.
;; Reg: Ele: Addr: need scratch
--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..a537dfe2350
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-char-2.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -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. This tests whether the ISA 3.0 LXSIBZX
+ instruction is generated. */
+
+#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} } } */
--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..95805325e9e
--- /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} } } */
--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..3cf9bafd4f3
--- /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} } } */
--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..533a80d3d52
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-short-4.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -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. This tests whether the ISA 3.0 LXSIHZX
+ instruction is generated. */
+
+#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} } } */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
@ 2023-04-28 19:18 Michael Meissner
0 siblings, 0 replies; 8+ messages in thread
From: Michael Meissner @ 2023-04-28 19:18 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8263791e479a09df1fe580fe3406729fbad9df8d
commit 8263791e479a09df1fe580fe3406729fbad9df8d
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Fri Apr 28 15:17:55 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-28 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 | 62 ++++++++++++++++++++--
| 41 ++++++++++++++
| 40 ++++++++++++++
| 40 ++++++++++++++
| 41 ++++++++++++++
6 files changed, 224 insertions(+), 3 deletions(-)
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 e33675781ce..dbd76530c84 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -4023,10 +4023,10 @@
;; Fold extracting a V8HI/V4SI element with a constant element with zero
;; extension to either DImode or SImode.
(define_insn_and_split "*vsx_extract_<VSX_EXTRACT_I2:mode>_load_to_u<GPR:mode>"
- [(set (match_operand:GPR 0 "register_operand" "=r,v")
+ [(set (match_operand:GPR 0 "register_operand" "=f,v")
(zero_extend:GPR
(vec_select:<VEC_base>
- (match_operand:VSX_EXTRACT_I2 1 "non_altivec_memory_operand" "m,Q")
+ (match_operand:VSX_EXTRACT_I2 1 "non_altivec_memory_operand" "Q,Q")
(parallel [(match_operand:QI 2 "const_int_operand" "n,n")]))))
(clobber (match_scratch:DI 3 "=&b,&b"))]
"VECTOR_MEM_VSX_P (<VSX_EXTRACT_I2:MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
@@ -4039,10 +4039,66 @@
operands[2], operands[3],
<VSX_EXTRACT_I2:VEC_base>mode);
}
- [(set_attr "type" "load,fpload")
+ [(set_attr "type" "fpload")
(set_attr "length" "8")
(set_attr "isa" "*,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")
+ (any_float:SFDF
+ (vec_select:SI
+ (match_operand:V4SI 1 "non_altivec_memory_operand" "Q")
+ (parallel [(match_operand:QI 2 "const_0_to_3_operand" "n")]))))
+ (clobber (match_scratch:DI 3 "=&b"))
+ (clobber (match_scratch:DI 4 "=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" "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")
+ (unsigned_float:SFDF
+ (vec_select:<VSX_EXTRACT_I2:VEC_base>
+ (match_operand:VSX_EXTRACT_I2 1 "non_altivec_memory_operand" "Q")
+ (parallel [(match_operand:QI 2 "const_int_operand" "n")]))))
+ (clobber (match_scratch:DI 3 "=&b"))
+ (clobber (match_scratch:DI 4 "=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" "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>"
--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..a537dfe2350
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-char-2.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -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. This tests whether the ISA 3.0 LXSIBZX
+ instruction is generated. */
+
+#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} } } */
--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..95805325e9e
--- /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} } } */
--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..3cf9bafd4f3
--- /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} } } */
--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..533a80d3d52
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-short-4.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -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. This tests whether the ISA 3.0 LXSIHZX
+ instruction is generated. */
+
+#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} } } */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
@ 2023-04-28 18:58 Michael Meissner
0 siblings, 0 replies; 8+ messages in thread
From: Michael Meissner @ 2023-04-28 18:58 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:a89f22ecfa457ef044e79c41d0fd4fcabb09846e
commit a89f22ecfa457ef044e79c41d0fd4fcabb09846e
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Fri Apr 28 14:58:22 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-28 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 ++++++++++++++++++++++
| 41 ++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 41 ++++++++++++++++
6 files changed, 221 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 e33675781ce..bf07d62606a 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -4043,6 +4043,62 @@
(set_attr "length" "8")
(set_attr "isa" "*,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")
+ (any_float:SFDF
+ (vec_select:SI
+ (match_operand:V4SI 1 "non_altivec_memory_operand" "Q")
+ (parallel [(match_operand:QI 2 "const_0_to_3_operand" "n")]))))
+ (clobber (match_scratch:DI 3 "=&b"))
+ (clobber (match_scratch:DI 4 "=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" "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>"
--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..a537dfe2350
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-char-2.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -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. This tests whether the ISA 3.0 LXSIBZX
+ instruction is generated. */
+
+#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} } } */
--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..95805325e9e
--- /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} } } */
--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..3cf9bafd4f3
--- /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} } } */
--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..533a80d3d52
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-short-4.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -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. This tests whether the ISA 3.0 LXSIHZX
+ instruction is generated. */
+
+#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} } } */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
@ 2023-04-28 6:36 Michael Meissner
0 siblings, 0 replies; 8+ messages in thread
From: Michael Meissner @ 2023-04-28 6:36 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:76997a7dfbba86841f20dd2bcb69443f341924eb
commit 76997a7dfbba86841f20dd2bcb69443f341924eb
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Fri Apr 28 02:36:06 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-28 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 ++++++++++++++++++++++
| 41 ++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 41 ++++++++++++++++
6 files changed, 221 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 838caaab9ec..7fa64dca29a 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -4043,6 +4043,62 @@
(set_attr "length" "8")
(set_attr "isa" "*,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>"
--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..a537dfe2350
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-char-2.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -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. This tests whether the ISA 3.0 LXSIBZX
+ instruction is generated. */
+
+#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} } } */
--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..95805325e9e
--- /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} } } */
--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..3cf9bafd4f3
--- /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} } } */
--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..533a80d3d52
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-extract-mem-short-4.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -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. This tests whether the ISA 3.0 LXSIHZX
+ instruction is generated. */
+
+#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} } } */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
@ 2023-04-28 3:43 Michael Meissner
0 siblings, 0 replies; 8+ messages in thread
From: Michael Meissner @ 2023-04-28 3:43 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:0e7d826ea61b3b964a8ed88ea835a2dc74dc6aab
commit 0e7d826ea61b3b964a8ed88ea835a2dc74dc6aab
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Thu Apr 27 23:43:18 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-27 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 ++++++++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 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 838caaab9ec..7fa64dca29a 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -4043,6 +4043,62 @@
(set_attr "length" "8")
(set_attr "isa" "*,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>"
--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} } } */
--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} } } */
--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} } } */
--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} } } */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
@ 2023-04-26 23:59 Michael Meissner
0 siblings, 0 replies; 8+ messages in thread
From: Michael Meissner @ 2023-04-26 23:59 UTC (permalink / raw)
To: gcc-cvs
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 ++++++++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 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>"
--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} } } */
--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} } } */
--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} } } */
--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} } } */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point
@ 2023-04-26 23:43 Michael Meissner
0 siblings, 0 replies; 8+ messages in thread
From: Michael Meissner @ 2023-04-26 23:43 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:4d463368653156e2ba63f9ebe26c3e4bdd1d0141
commit 4d463368653156e2ba63f9ebe26c3e4bdd1d0141
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Wed Apr 26 19:42:17 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 ++++++++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 40 ++++++++++++++++
| 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..1807c192d08 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 (V4SImode) && TARGET_DIRECT_MOVE_64BIT"
+ "#"
+ "&& 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>"
--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} } } */
--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} } } */
--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} } } */
--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} } } */
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-04-29 3:51 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-27 3:06 [gcc(refs/users/meissner/heads/work119)] Allow constant element vec_extract to be converted to floating point Michael Meissner
-- 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-26 23:59 Michael Meissner
2023-04-26 23:43 Michael Meissner
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).