rs6000.c (swap_web_entry): Enlarge special_handling bitfield.
[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. From-SVN: r227331
This commit is contained in:
parent
5ba02681ad
commit
babb13f5cc
|
@ -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]*-*-*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 } } */
|
Loading…
Reference in New Issue