aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2015-04-17 22:05:12 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2015-04-17 22:05:12 +0000
commit67e6c405298dcb1539e7b1670018cf41bbdec6b6 (patch)
tree7f4f848d7e27ca403568e9bd53c5e2b11dc77fc7
parent46f120ca7bc8b4a49c0d5a596b85aeca4a254698 (diff)
downloadgcc-67e6c405298dcb1539e7b1670018cf41bbdec6b6.zip
gcc-67e6c405298dcb1539e7b1670018cf41bbdec6b6.tar.gz
gcc-67e6c405298dcb1539e7b1670018cf41bbdec6b6.tar.bz2
re PR target/65787 (Miscompile due to bad vector swap optimization for little endian)
[gcc] 2015-04-17 Bill Schmidt <wschmidt@linux.vnet.ibm.com> PR target/65787 * config/rs6000/rs6000.c (rtx_is_swappable_p): Ensure that a subsequent SH_NONE operand does not overwrite an existing *special value. (adjust_extract): Handle case where a vec_extract operation is wrapped in a PARALLEL. [gcc/testsuite] 2015-04-17 Bill Schmidt <wschmidt@linux.vnet.ibm.com> PR target/65787 * gcc.target/powerpc/pr65787.c: New. From-SVN: r222205
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/rs6000/rs6000.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr65787.c21
4 files changed, 45 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 99f2d08..5da0cd2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2015-04-17 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR target/65787
+ * config/rs6000/rs6000.c (rtx_is_swappable_p): Ensure that a
+ subsequent SH_NONE operand does not overwrite an existing *special
+ value.
+ (adjust_extract): Handle case where a vec_extract operation is
+ wrapped in a PARALLEL.
+
2015-04-17 H.J. Lu <hongjiu.lu@intel.com>
PR target/65780
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a96a774..10aa40b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -34285,10 +34285,11 @@ rtx_is_swappable_p (rtx op, unsigned int *special)
{
unsigned int special_op = SH_NONE;
ok &= rtx_is_swappable_p (XEXP (op, i), &special_op);
+ if (special_op == SH_NONE)
+ continue;
/* Ensure we never have two kinds of special handling
for the same insn. */
- if (*special != SH_NONE && special_op != SH_NONE
- && *special != special_op)
+ if (*special != SH_NONE && *special != special_op)
return 0;
*special = special_op;
}
@@ -34297,10 +34298,11 @@ rtx_is_swappable_p (rtx op, unsigned int *special)
{
unsigned int special_op = SH_NONE;
ok &= rtx_is_swappable_p (XVECEXP (op, i, j), &special_op);
+ if (special_op == SH_NONE)
+ continue;
/* Ensure we never have two kinds of special handling
for the same insn. */
- if (*special != SH_NONE && special_op != SH_NONE
- && *special != special_op)
+ if (*special != SH_NONE && *special != special_op)
return 0;
*special = special_op;
}
@@ -34603,7 +34605,10 @@ permute_store (rtx_insn *insn)
static void
adjust_extract (rtx_insn *insn)
{
- rtx src = SET_SRC (PATTERN (insn));
+ rtx pattern = PATTERN (insn);
+ if (GET_CODE (pattern) == PARALLEL)
+ pattern = XVECEXP (pattern, 0, 0);
+ rtx src = SET_SRC (pattern);
/* The vec_select may be wrapped in a vec_duplicate for a splat, so
account for that. */
rtx sel = GET_CODE (src) == VEC_DUPLICATE ? XEXP (src, 0) : src;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cec5fa1..ee4f05f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-17 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR target/65787
+ * gcc.target/powerpc/pr65787.c: New.
+
2015-04-17 Jakub Jelinek <jakub@redhat.com>
PR target/65689
diff --git a/gcc/testsuite/gcc.target/powerpc/pr65787.c b/gcc/testsuite/gcc.target/powerpc/pr65787.c
new file mode 100644
index 0000000..c819be9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr65787.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -O3" } */
+/* { dg-final { scan-assembler "xxsldwi \[0-9\]*,\[0-9\]*,\[0-9\]*,3" } } */
+/* { dg-final { scan-assembler-not "xxpermdi" } } */
+
+/* This test verifies that a vector extract operand properly has its
+ lane changed by the swap optimization. Element 2 of LE corresponds
+ to element 1 of BE. When doublewords are swapped, this becomes
+ element 3 of BE, so we need to shift the vector left by 3 words
+ to be able to extract the correct value from BE element zero. */
+
+typedef float v4f32 __attribute__ ((__vector_size__ (16)));
+
+void foo (float);
+extern v4f32 x, y;
+
+int main() {
+ v4f32 z = x + y;
+ foo (z[2]);
+}