aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorXionghu Luo <luoxhu@linux.ibm.com>2021-06-08 21:48:12 -0500
committerXionghu Luo <luoxhu@linux.ibm.com>2021-06-08 21:51:16 -0500
commitf700e4b0ee3ef53b48975cf89be26b9177e3a3f3 (patch)
treec11da331145e90e06ea2fda268dd9e7e5f761dc0 /gcc
parent87f9ac937d6cfd81cbbe0a43518ba10781888d7c (diff)
downloadgcc-f700e4b0ee3ef53b48975cf89be26b9177e3a3f3.zip
gcc-f700e4b0ee3ef53b48975cf89be26b9177e3a3f3.tar.gz
gcc-f700e4b0ee3ef53b48975cf89be26b9177e3a3f3.tar.bz2
rs6000: Support doubleword swaps removal in rot64 load store [PR100085]
On P8LE, extra rot64+rot64 load or store instructions are generated in float128 to vector __int128 conversion. This patch teaches pass swaps to also handle such pattens to remove extra swap instructions. (insn 7 6 8 2 (set (subreg:V1TI (reg:KF 123) 0) (rotate:V1TI (mem/u/c:V1TI (reg/f:DI 121) [0 S16 A128]) (const_int 64 [0x40]))) {*vsx_le_permute_v1ti}) (insn 8 7 9 2 (set (subreg:V1TI (reg:KF 122) 0) (rotate:V1TI (subreg:V1TI (reg:KF 123) 0) (const_int 64 [0x40]))) {*vsx_le_permute_v1ti}) => (insn 22 6 23 2 (set (subreg:V1TI (reg:KF 123) 0) (mem/u/c:V1TI (and:DI (reg/f:DI 121) (const_int -16 [0xfffffffffffffff0])) [0 S16 A128]))) (insn 23 22 25 2 (set (subreg:V1TI (reg:KF 122) 0) (subreg:V1TI (reg:KF 123) 0))) gcc/ChangeLog: 2021-06-09 Xionghu Luo <luoxhu@linux.ibm.com> * config/rs6000/rs6000-p8swap.c (pattern_is_rotate64): New. (insn_is_load_p): Use pattern_is_rotate64. (insn_is_swap_p): Likewise. (quad_aligned_load_p): Likewise. (const_load_sequence_p): Likewise. (replace_swapped_aligned_load): Likewise. (recombine_lvx_pattern): Likewise. (recombine_stvx_pattern): Likewise. gcc/testsuite/ChangeLog: 2021-06-09 Xionghu Luo <luoxhu@linux.ibm.com> * gcc.target/powerpc/float128-call.c: Adjust. * gcc.target/powerpc/pr100085.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/rs6000/rs6000-p8swap.c35
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-call.c4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr100085.c23
3 files changed, 55 insertions, 7 deletions
diff --git a/gcc/config/rs6000/rs6000-p8swap.c b/gcc/config/rs6000/rs6000-p8swap.c
index ad2b302..21cbcb2 100644
--- a/gcc/config/rs6000/rs6000-p8swap.c
+++ b/gcc/config/rs6000/rs6000-p8swap.c
@@ -250,6 +250,21 @@ union_uses (swap_web_entry *insn_entry, rtx insn, df_ref def)
}
}
+/* Return 1 iff PAT (a SINGLE_SET) is a rotate 64 bit expression; else return
+ 0. */
+
+static bool
+pattern_is_rotate64 (rtx pat)
+{
+ rtx rot = SET_SRC (pat);
+
+ if (GET_CODE (rot) == ROTATE && CONST_INT_P (XEXP (rot, 1))
+ && INTVAL (XEXP (rot, 1)) == 64)
+ return true;
+
+ return false;
+}
+
/* Return 1 iff INSN is a load insn, including permuting loads that
represent an lvxd2x instruction; else return 0. */
static unsigned int
@@ -266,6 +281,9 @@ insn_is_load_p (rtx insn)
&& MEM_P (XEXP (SET_SRC (body), 0)))
return 1;
+ if (pattern_is_rotate64 (body) && MEM_P (XEXP (SET_SRC (body), 0)))
+ return 1;
+
return 0;
}
@@ -305,6 +323,8 @@ insn_is_swap_p (rtx insn)
if (GET_CODE (body) != SET)
return 0;
rtx rhs = SET_SRC (body);
+ if (pattern_is_rotate64 (body))
+ return 1;
if (GET_CODE (rhs) != VEC_SELECT)
return 0;
rtx parallel = XEXP (rhs, 1);
@@ -392,7 +412,8 @@ quad_aligned_load_p (swap_web_entry *insn_entry, rtx_insn *insn)
false. */
rtx body = PATTERN (def_insn);
if (GET_CODE (body) != SET
- || GET_CODE (SET_SRC (body)) != VEC_SELECT
+ || !(GET_CODE (SET_SRC (body)) == VEC_SELECT
+ || pattern_is_rotate64 (body))
|| !MEM_P (XEXP (SET_SRC (body), 0)))
return false;
@@ -531,7 +552,8 @@ const_load_sequence_p (swap_web_entry *insn_entry, rtx insn)
false. */
rtx body = PATTERN (def_insn);
if (GET_CODE (body) != SET
- || GET_CODE (SET_SRC (body)) != VEC_SELECT
+ || !(GET_CODE (SET_SRC (body)) == VEC_SELECT
+ || pattern_is_rotate64 (body))
|| !MEM_P (XEXP (SET_SRC (body), 0)))
return false;
@@ -1732,7 +1754,8 @@ replace_swapped_aligned_load (swap_web_entry *insn_entry, rtx swap_insn)
swap (indicated by code VEC_SELECT). */
rtx body = PATTERN (def_insn);
gcc_assert ((GET_CODE (body) == SET)
- && (GET_CODE (SET_SRC (body)) == VEC_SELECT)
+ && (GET_CODE (SET_SRC (body)) == VEC_SELECT
+ || pattern_is_rotate64 (body))
&& MEM_P (XEXP (SET_SRC (body), 0)));
rtx src_exp = XEXP (SET_SRC (body), 0);
@@ -2150,7 +2173,8 @@ recombine_lvx_pattern (rtx_insn *insn, del_info *to_delete)
{
rtx body = PATTERN (insn);
gcc_assert (GET_CODE (body) == SET
- && GET_CODE (SET_SRC (body)) == VEC_SELECT
+ && (GET_CODE (SET_SRC (body)) == VEC_SELECT
+ || pattern_is_rotate64 (body))
&& MEM_P (XEXP (SET_SRC (body), 0)));
rtx mem = XEXP (SET_SRC (body), 0);
@@ -2227,7 +2251,8 @@ recombine_stvx_pattern (rtx_insn *insn, del_info *to_delete)
rtx body = PATTERN (insn);
gcc_assert (GET_CODE (body) == SET
&& MEM_P (SET_DEST (body))
- && GET_CODE (SET_SRC (body)) == VEC_SELECT);
+ && (GET_CODE (SET_SRC (body)) == VEC_SELECT
+ || pattern_is_rotate64 (body)));
rtx mem = SET_DEST (body);
rtx base_reg = XEXP (mem, 0);
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-call.c b/gcc/testsuite/gcc.target/powerpc/float128-call.c
index 5895416..a1f09df 100644
--- a/gcc/testsuite/gcc.target/powerpc/float128-call.c
+++ b/gcc/testsuite/gcc.target/powerpc/float128-call.c
@@ -21,5 +21,5 @@
TYPE one (void) { return ONE; }
void store (TYPE a, TYPE *p) { *p = a; }
-/* { dg-final { scan-assembler "lxvd2x 34" } } */
-/* { dg-final { scan-assembler "stxvd2x 34" } } */
+/* { dg-final { scan-assembler "lvx 2" } } */
+/* { dg-final { scan-assembler "stvx 2" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr100085.c b/gcc/testsuite/gcc.target/powerpc/pr100085.c
new file mode 100644
index 0000000..7d8b147
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr100085.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power8" } */
+
+typedef __vector unsigned __int128 vui128_t;
+
+typedef union
+{
+ __float128 vf1;
+ vui128_t vx1;
+} __VF_128;
+
+vui128_t
+vec_xfer_bin128_2_vui128t (__float128 f128)
+{
+ __VF_128 vunion;
+ vunion.vf1 = f128;
+ return (vunion.vx1);
+}
+
+/* { dg-final { scan-assembler-not {\mxxpermdi\M} } } */
+/* { dg-final { scan-assembler-not {\mstxvd2x\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvd2x\M} } } */
+