summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-08 17:21:17 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-08 17:21:17 +0000
commit3ac399da09d26173741fdd87e8ee40654ad35c6d (patch)
treef47617c05c49b8453a2dd2c38ceccc147ce33913
parenta5f0da96ac1554f56d064c5ae89a80833bd01888 (diff)
downloadgcc-3ac399da09d26173741fdd87e8ee40654ad35c6d.tar.gz
PR rtl-optimization/70574
* fwprop.c (forward_propagate_and_simplify): Don't add REG_EQUAL note if DF_REF_REG (use) is a paradoxical subreg. (try_fwprop_subst): Don't add REG_EQUAL note if there are any paradoxical subregs within *loc. * gcc.target/i386/avx2-pr70574.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234833 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/fwprop.c32
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-pr70574.c26
4 files changed, 66 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 15e3d22d535..b9b36de74a5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2016-04-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/70574
+ * fwprop.c (forward_propagate_and_simplify): Don't add
+ REG_EQUAL note if DF_REF_REG (use) is a paradoxical subreg.
+ (try_fwprop_subst): Don't add REG_EQUAL note if there are any
+ paradoxical subregs within *loc.
+
2016-04-08 Thomas Schwinge <thomas@codesourcery.com>
* config/arc/arc.h (LINK_COMMAND_SPEC): Use gt to ignore
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index c4587d7bf77..d8cb9fa3bbb 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -999,10 +999,27 @@ try_fwprop_subst (df_ref use, rtx *loc, rtx new_rtx, rtx_insn *def_insn,
making a new one if one does not already exist. */
if (set_reg_equal)
{
- if (dump_file)
- fprintf (dump_file, " Setting REG_EQUAL note\n");
+ /* If there are any paradoxical SUBREGs, don't add REG_EQUAL note,
+ because the bits in there can be anything and so might not
+ match the REG_EQUAL note content. See PR70574. */
+ subrtx_var_iterator::array_type array;
+ FOR_EACH_SUBRTX_VAR (iter, array, *loc, NONCONST)
+ {
+ rtx x = *iter;
+ if (SUBREG_P (x) && paradoxical_subreg_p (x))
+ {
+ set_reg_equal = false;
+ break;
+ }
+ }
- note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (new_rtx));
+ if (set_reg_equal)
+ {
+ if (dump_file)
+ fprintf (dump_file, " Setting REG_EQUAL note\n");
+
+ note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (new_rtx));
+ }
}
}
@@ -1300,14 +1317,19 @@ forward_propagate_and_simplify (df_ref use, rtx_insn *def_insn, rtx def_set)
that isn't mentioned in USE_SET, as the note would be invalid
otherwise. We also don't want to install a note if we are merely
propagating a pseudo since verifying that this pseudo isn't dead
- is a pain; moreover such a note won't help anything. */
+ is a pain; moreover such a note won't help anything.
+ If the use is a paradoxical subreg, make sure we don't add a
+ REG_EQUAL note for it, because it is not equivalent, it is one
+ possible value for it, but we can't rely on it holding that value.
+ See PR70574. */
set_reg_equal = (note == NULL_RTX
&& REG_P (SET_DEST (use_set))
&& !REG_P (src)
&& !(GET_CODE (src) == SUBREG
&& REG_P (SUBREG_REG (src)))
&& !reg_mentioned_p (SET_DEST (use_set),
- SET_SRC (use_set)));
+ SET_SRC (use_set))
+ && !paradoxical_subreg_p (DF_REF_REG (use)));
}
if (GET_MODE (*loc) == VOIDmode)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 65c35e0c091..e1f87b396f1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-04-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/70574
+ * gcc.target/i386/avx2-pr70574.c: New test.
+
2016-04-08 Maxim Ostapenko <m.ostapenko@samsung.com>
PR sanitizer/70541
diff --git a/gcc/testsuite/gcc.target/i386/avx2-pr70574.c b/gcc/testsuite/gcc.target/i386/avx2-pr70574.c
new file mode 100644
index 00000000000..c9867ddf9b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx2-pr70574.c
@@ -0,0 +1,26 @@
+/* PR rtl-optimization/70574 */
+/* { dg-do run { target lp64 } } */
+/* { dg-require-effective-target avx2 } */
+/* { dg-options "-O -frerun-cse-after-loop -fno-tree-ccp -mcmodel=medium -mavx2" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+
+#include "avx2-check.h"
+
+typedef char A __attribute__((vector_size (32)));
+typedef short B __attribute__((vector_size (32)));
+
+int
+foo (int x, __int128 y, __int128 z, A w)
+{
+ y <<= 64;
+ w *= (A) { 0, -1, z, 0, ~y };
+ return w[0] + ((B) { x, 0, y, 0, -1 } | 1)[4];
+}
+
+static void
+avx2_test ()
+{
+ int x = foo (0, 0, 0, (A) {});
+ if (x != -1)
+ __builtin_abort ();
+}