diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-08 17:21:17 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-08 17:21:17 +0000 |
commit | 3ac399da09d26173741fdd87e8ee40654ad35c6d (patch) | |
tree | f47617c05c49b8453a2dd2c38ceccc147ce33913 | |
parent | a5f0da96ac1554f56d064c5ae89a80833bd01888 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fwprop.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/avx2-pr70574.c | 26 |
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 (); +} |