[Bug tree-optimization/89679] [7/8/9 Regression] wrong code with -Og -frerun-cse-after-loop -fno-tree-fre

2019-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89679

--- Comment #4 from Jakub Jelinek  ---
The other variant would be perhaps more in line with the PR70574 change where
we don't add REG_EQUAL notes with paradoxical subregs in it, by:
--- gcc/expmed.c.jj 2019-01-10 11:43:14.387377695 +0100
+++ gcc/expmed.c2019-03-12 17:38:55.286511666 +0100
@@ -3356,13 +3356,20 @@ expand_mult_const (machine_mode mode, rt
  tem = gen_lowpart (nmode, op0);
}

- insn = get_last_insn ();
- wide_int wval_so_far
-   = wi::uhwi (val_so_far,
-   GET_MODE_PRECISION (as_a  (nmode)));
- rtx c = immed_wide_int_const (wval_so_far, nmode);
- set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c),
-   accum_inner);
+ /* Don't add a REG_EQUAL note if tem is a paradoxical SUBREG.
+In that case, only the low bits of accum would be guaranteed to
+be equal to the content of the REG_EQUAL note, the upper bits
+can be anything.  */
+ if (!paradoxical_subreg_p (tem))
+   {
+ insn = get_last_insn ();
+ wide_int wval_so_far
+   = wi::uhwi (val_so_far,
+   GET_MODE_PRECISION (as_a  (nmode)));
+ rtx c = immed_wide_int_const (wval_so_far, nmode);
+ set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c),
+   accum_inner);
+   }
}
 }

[Bug tree-optimization/89679] [7/8/9 Regression] wrong code with -Og -frerun-cse-after-loop -fno-tree-fre

2019-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89679

Jakub Jelinek  changed:

   What|Removed |Added

 CC||ebotcazou at gcc dot gnu.org,
   ||law at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek  ---
If I change inside of the debugger that 0x in REG_EQUAL note to
constm1_rtx, then the testcase is not miscompiled.
The REG_EQUAL note is initially added by expand_mult_const:
  if (SCALAR_INT_MODE_P (mode))
{
  /* Write a REG_EQUAL note on the last insn so that we can cse
 multiplication sequences.  Note that if ACCUM is a SUBREG,
 we've set the inner register and must properly indicate that.  */
  tem = op0, nmode = mode;
  accum_inner = accum;
  if (GET_CODE (accum) == SUBREG)
{
  accum_inner = SUBREG_REG (accum);
  nmode = GET_MODE (accum_inner);
  tem = gen_lowpart (nmode, op0);
}

  insn = get_last_insn ();
  wide_int wval_so_far
= wi::uhwi (val_so_far,
GET_MODE_PRECISION (as_a  (nmode)));
  rtx c = immed_wide_int_const (wval_so_far, nmode);
  set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c),
accum_inner);
}
As accum is a (subreg:HI (reg:SI 140) 0), it emits a REG_EQUAL note with
paradoxical subreg in it:
(insn 17 16 18 2 (set (reg:SI 140)
(plus:SI (subreg:SI (reg:HI 138) 0)
(subreg:SI (reg:HI 136) 0))) "pr89679.c":16:3 -1
 (expr_list:REG_EQUAL (mult:SI (subreg:SI (reg:HI 136) 0)
(const_int 257 [0x101]))
(nil)))
the note is already quite questionable, because the SImode register is not
necessarily equal to that, the high 16 bits can be anything.
If it is not valid, then we either must make sure not to emit a REG_EQUAL note
in that case or emit it on some insn that sets a HImode reg rather than SImode.
Note we emit that that way for quite a long time, I think since
https://gcc.gnu.org/ml/gcc-patches/2000-12/msg00837.html

This is related to the https://gcc.gnu.org/ml/gcc-patches/2016-04/msg00418.html
change, though in this case we already have such a REG_EQUAL note that before
the change can be at least determined to have a paradoxical subreg in it and so
REG_EQUAL note consumers could take that into account.
But if we simplify it into a CONST_INT or whatever else that doesn't have the
paradoxical subreg in there anymore, this info is lost.

We could e.g. do:
--- gcc/fwprop.c.jj 2019-01-01 12:37:21.190908780 +0100
+++ gcc/fwprop.c2019-03-12 17:24:14.623863160 +0100
@@ -1327,7 +1327,12 @@ forward_propagate_and_simplify (df_ref u
 {
   rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX);
   if (DF_REF_FLAGS (use) & DF_REF_IN_NOTE)
-   loc =  (note, 0);
+   {
+ loc =  (note, 0);
+ /* Don't simplify a paradoxical SUBREG in a REG_EQUAL note.  */
+ if (paradoxical_subreg_p (DF_REF_REG (use)))
+   return false;
+   }
   else
loc = _SRC (use_set);

and thus not really simplify paradoxical subregs in REG_EQUAL notes, the notes
will be then removed if we DCE the setters of corresponding pseudos.

Thoughts on this?

[Bug tree-optimization/89679] [7/8/9 Regression] wrong code with -Og -frerun-cse-after-loop -fno-tree-fre

2019-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89679

--- Comment #2 from Jakub Jelinek  ---
The first thing which looks invalid to me is when fwprop1 adds a bogus
REG_EQUAL note:
(insn 17 6 19 2 (set (reg:SI 140)
(const_int -1 [0x])) "pr89679.c":16:3 494
{*movsi_internal1}
 (expr_list:REG_DEAD (reg:HI 138 [ c ])
(expr_list:REG_DEAD (reg:HI 136 [ c ])
(expr_list:REG_EQUAL (const_int 65535 [0x])
(nil)

SImode -1 is certainly not equal to 0x.

[Bug tree-optimization/89679] [7/8/9 Regression] wrong code with -Og -frerun-cse-after-loop -fno-tree-fre

2019-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89679

Jakub Jelinek  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-03-12
 CC||jakub at gcc dot gnu.org
   Target Milestone|--- |7.5
Summary|wrong code with -Og |[7/8/9 Regression] wrong
   |-frerun-cse-after-loop  |code with -Og
   |-fno-tree-fre   |-frerun-cse-after-loop
   ||-fno-tree-fre
 Ever confirmed|0   |1

--- Comment #1 from Jakub Jelinek  ---
Started with r205060.