summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-31 01:02:47 +0000
committerwschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-31 01:02:47 +0000
commitb21e01beafa0af192b437e184d62634b25c96596 (patch)
treed546465b3429dfc52021e9aeee424d468077a316
parentf1a166be39c247d78f0675eddb5537b2b15ee207 (diff)
downloadgcc-b21e01beafa0af192b437e184d62634b25c96596.tar.gz
[gcc]
2015-08-30 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * config/rs6000/rs6000.c (swap_web_entry): Enlarge special_handling bitfield. (special_handling_values): Add SH_XXPERMDI and SH_CONCAT. (rtx_is_swappable_p): Add handling for vec_select/vec_concat form that represents a general xxpermdi. (insn_is_swappable_p): Add handling for vec_concat of two doublewords, which maps to a specific xxpermdi. (adjust_xxpermdi): New function. (adjust_concat): Likewise. (handle_special_swappables): Call adjust_xxpermdi and adjust_concat. (dump_swap_insn_table): Handle SH_XXPERMDI and SH_CONCAT. [gcc/testsuite] 2015-08-30 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * gcc.target/powerpc/swaps-p8-19.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227331 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/rs6000/rs6000.c86
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/swaps-p8-19.c20
4 files changed, 123 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9150a6e7692..f91964d1221 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2015-08-30 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (swap_web_entry): Enlarge
+ special_handling bitfield.
+ (special_handling_values): Add SH_XXPERMDI and SH_CONCAT.
+ (rtx_is_swappable_p): Add handling for vec_select/vec_concat form
+ that represents a general xxpermdi.
+ (insn_is_swappable_p): Add handling for vec_concat of two
+ doublewords, which maps to a specific xxpermdi.
+ (adjust_xxpermdi): New function.
+ (adjust_concat): Likewise.
+ (handle_special_swappables): Call adjust_xxpermdi and
+ adjust_concat.
+ (dump_swap_insn_table): Handle SH_XXPERMDI and SH_CONCAT.
+
2015-08-30 Rich Felker <dalias@libc.org>
* config.gcc (supported_defaults): Handle sh[123456ble]*-*-*
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 93fdece9a32..500effa7331 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -34986,7 +34986,7 @@ class swap_web_entry : public web_entry_base
/* A nonzero value indicates what kind of special handling for this
insn is required if doublewords are swapped. Undefined if
is_swappable is not set. */
- unsigned int special_handling : 3;
+ unsigned int special_handling : 4;
/* Set if the web represented by this entry cannot be optimized. */
unsigned int web_not_optimizable : 1;
/* Set if this insn should be deleted. */
@@ -35000,7 +35000,9 @@ enum special_handling_values {
SH_NOSWAP_LD,
SH_NOSWAP_ST,
SH_EXTRACT,
- SH_SPLAT
+ SH_SPLAT,
+ SH_XXPERMDI,
+ SH_CONCAT
};
/* Union INSN with all insns containing definitions that reach USE.
@@ -35192,6 +35194,20 @@ rtx_is_swappable_p (rtx op, unsigned int *special)
*special = SH_EXTRACT;
return 1;
}
+ /* An XXPERMDI is ok if we adjust the lanes. Note that if the
+ XXPERMDI is a swap operation, it will be identified by
+ insn_is_swap_p and therefore we won't get here. */
+ else if (GET_CODE (XEXP (op, 0)) == VEC_CONCAT
+ && (GET_MODE (XEXP (op, 0)) == V4DFmode
+ || GET_MODE (XEXP (op, 0)) == V4DImode)
+ && GET_CODE ((parallel = XEXP (op, 1))) == PARALLEL
+ && XVECLEN (parallel, 0) == 2
+ && GET_CODE (XVECEXP (parallel, 0, 0)) == CONST_INT
+ && GET_CODE (XVECEXP (parallel, 0, 1)) == CONST_INT)
+ {
+ *special = SH_XXPERMDI;
+ return 1;
+ }
else
return 0;
@@ -35369,6 +35385,17 @@ insn_is_swappable_p (swap_web_entry *insn_entry, rtx insn,
return 1;
}
+ /* A concatenation of two doublewords is ok if we reverse the
+ order of the inputs. */
+ if (GET_CODE (body) == SET
+ && GET_CODE (SET_SRC (body)) == VEC_CONCAT
+ && (GET_MODE (SET_SRC (body)) == V2DFmode
+ || GET_MODE (SET_SRC (body)) == V2DImode))
+ {
+ *special = SH_CONCAT;
+ return 1;
+ }
+
/* Otherwise check the operands for vector lane violations. */
return rtx_is_swappable_p (body, special);
}
@@ -35658,6 +35685,49 @@ adjust_splat (rtx_insn *insn)
fprintf (dump_file, "Changing lane for splat %d\n", INSN_UID (insn));
}
+/* Given OP that contains an XXPERMDI operation (that is not a doubleword
+ swap), reverse the order of the source operands and adjust the indices
+ of the source lanes to account for doubleword reversal. */
+static void
+adjust_xxpermdi (rtx_insn *insn)
+{
+ rtx set = PATTERN (insn);
+ rtx select = XEXP (set, 1);
+ rtx concat = XEXP (select, 0);
+ rtx src0 = XEXP (concat, 0);
+ XEXP (concat, 0) = XEXP (concat, 1);
+ XEXP (concat, 1) = src0;
+ rtx parallel = XEXP (select, 1);
+ int lane0 = INTVAL (XVECEXP (parallel, 0, 0));
+ int lane1 = INTVAL (XVECEXP (parallel, 0, 1));
+ int new_lane0 = 3 - lane1;
+ int new_lane1 = 3 - lane0;
+ XVECEXP (parallel, 0, 0) = GEN_INT (new_lane0);
+ XVECEXP (parallel, 0, 1) = GEN_INT (new_lane1);
+ INSN_CODE (insn) = -1; /* Force re-recognition. */
+ df_insn_rescan (insn);
+
+ if (dump_file)
+ fprintf (dump_file, "Changing lanes for xxpermdi %d\n", INSN_UID (insn));
+}
+
+/* Given OP that contains a VEC_CONCAT operation of two doublewords,
+ reverse the order of those inputs. */
+static void
+adjust_concat (rtx_insn *insn)
+{
+ rtx set = PATTERN (insn);
+ rtx concat = XEXP (set, 1);
+ rtx src0 = XEXP (concat, 0);
+ XEXP (concat, 0) = XEXP (concat, 1);
+ XEXP (concat, 1) = src0;
+ INSN_CODE (insn) = -1; /* Force re-recognition. */
+ df_insn_rescan (insn);
+
+ if (dump_file)
+ fprintf (dump_file, "Reversing inputs for concat %d\n", INSN_UID (insn));
+}
+
/* The insn described by INSN_ENTRY[I] can be swapped, but only
with special handling. Take care of that here. */
static void
@@ -35704,6 +35774,14 @@ handle_special_swappables (swap_web_entry *insn_entry, unsigned i)
/* Change the lane on a direct-splat operation. */
adjust_splat (insn);
break;
+ case SH_XXPERMDI:
+ /* Change the lanes on an XXPERMDI operation. */
+ adjust_xxpermdi (insn);
+ break;
+ case SH_CONCAT:
+ /* Reverse the order of a concatenation operation. */
+ adjust_concat (insn);
+ break;
}
}
@@ -35776,6 +35854,10 @@ dump_swap_insn_table (swap_web_entry *insn_entry)
fputs ("special:extract ", dump_file);
else if (insn_entry[i].special_handling == SH_SPLAT)
fputs ("special:splat ", dump_file);
+ else if (insn_entry[i].special_handling == SH_XXPERMDI)
+ fputs ("special:xxpermdi ", dump_file);
+ else if (insn_entry[i].special_handling == SH_CONCAT)
+ fputs ("special:concat ", dump_file);
}
if (insn_entry[i].web_not_optimizable)
fputs ("unoptimizable ", dump_file);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1d8373d7876..8869251bb14 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2015-08-30 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/swaps-p8-19.c: New test.
+
2015-08-29 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/67367
diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-19.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-19.c
new file mode 100644
index 00000000000..6dffbb9b892
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-19.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-O2 -ftree-vectorize -mcpu=power8 -ffast-math -fvect-cost-model=unlimited" } */
+
+/* This tests special handling for various uses of xxpermdi, other than
+ to perform doubleword swaps. */
+
+void foo (_Complex double *self, _Complex double *a, _Complex double *b,
+ int a1, int a2)
+{
+ int i, j;
+ for (i = 0; i < a1; ++i)
+ for (j = 0; j < a2; ++j)
+ self[i] = self[i] + a[i,j] * b[j];
+}
+
+/* { dg-final { scan-assembler-times "xxpermdi .*,.*,.*,0" 1 } } */
+/* { dg-final { scan-assembler-times "xxpermdi .*,.*,.*,1" 1 } } */
+/* { dg-final { scan-assembler-times "xxpermdi .*,.*,.*,2" 1 } } */
+/* { dg-final { scan-assembler-times "xxpermdi .*,.*,.*,3" 1 } } */