[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-01 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

Jakub Jelinek  changed:

   What|Removed |Added

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

--- Comment #4 from Jakub Jelinek  ---
I think this boils down whether it is valid to have REG_EQUAL note on a REG_INC
insn or not.
The documentation says:
"This note is only valid on an insn that sets only one register"
but REG_INC insns actually set two registers, the result and
increment/decrement some other register.
The combiner has code to count the autoincs before/after transformation and
punts if they disagree, but because of the REG_EQUAL note the:
1498  /* Temporarily replace the set's source with the
1499 contents of the REG_EQUAL note.  The insn will
1500 be deleted or recognized by try_combine.  */
...
code just replaces the
(insn 7 29 8 2 (set (reg:TI 95 [ D.3590 ])
(mem/u/c:TI (post_inc:DI (reg/f:DI 106)) [0  S16 A128]))
"pr94873.c":11:48 58 {*movti_aarch64}
 (expr_list:REG_INC (reg/f:DI 106)
(expr_list:REG_EQUAL (const_wide_int 0x0f4409395252b9560)
(nil
insn so that it is
(insn 7 29 8 2 (set (reg:TI 95 [ D.3590 ])
(const_wide_int 0x0f4409395252b9560)) "pr94873.c":11:48 58
{*movti_aarch64}
 (expr_list:REG_INC (reg/f:DI 106)
(expr_list:REG_EQUAL (const_wide_int 0x0f4409395252b9560)
(nil
and when counting auto_inc on that, we don't find anything, so happily drop the
 auto-inc side-effect.

So, if REG_EQUAL is invalid on REG_INC insns, the auto-inc pass should throw
away those notes from insns which it optimizes, if it is not invalid, combiner
needs to ignore REG_EQUAL notes on REG_INC insns or something similar (or count
the auto-inc effects on the original vs. replacement and if they disagree,
punt).

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-01 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

Jeffrey A. Law  changed:

   What|Removed |Added

 CC||law at redhat dot com

--- Comment #5 from Jeffrey A. Law  ---
I can't see how a REG_EQUAL note on an insn with multiple outputs can possibly
work -- we wouldn't know what output the REG_EQUAL note refers to.  And we have
to consider an embedded side effect as having an output.

Or to think of it another way, any embedded side effect can be implemented with
a parallel at which point it's painfully obvious the insn has multiple outputs
and a REG_EQUAL note would be inappropriate.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-01 Thread rsandifo at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

rsandifo at gcc dot gnu.org  changed:

   What|Removed |Added

 CC||rsandifo at gcc dot gnu.org

--- Comment #6 from rsandifo at gcc dot gnu.org  
---
(In reply to Jeffrey A. Law from comment #5)
> I can't see how a REG_EQUAL note on an insn with multiple outputs can
> possibly work -- we wouldn't know what output the REG_EQUAL note refers to. 
> And we have to consider an embedded side effect as having an output.
> 
> Or to think of it another way, any embedded side effect can be implemented
> with a parallel at which point it's painfully obvious the insn has multiple
> outputs and a REG_EQUAL note would be inappropriate.

Yeah, I can see that argument, but to play devil's advocate:

I think the requirement for having a single REG SET_DEST makes
sense because the REG_EQUAL note would be genuinely ambiguous if
there were multiple REG SET_DESTs.  But in the case of a REG_INC
insn with a single REG SET_DEST, there's no ambiguity about which
register is meant.

I guess there's also the problem that stack pushes don't need a
REG_INC note, so anything we do can't just be keyed off REG_INC.
The only sure way to check whether a register is set as a side-effect
is to look at the complete pattern (like dse.c:check_for_inc_dec).

So I think there's the argument that optimisers have to be wary
of this in the same way that they need to be wary of folding:

   (set (reg X)
(and (mem (pre_inc (reg Y)))
 (reg Z)))

into

   (set (reg X) (const_int 0))

when Z can be proven to be zero.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-01 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #7 from Segher Boessenkool  ---
REG_EQ* is documented as only being allowed on insns that set only one
register.  If you want to change that, you'll have to check *all* code
that consumes this, see if they rely on that fact or not, and if so,
change that.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-01 Thread rsandifo at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #8 from rsandifo at gcc dot gnu.org  
---
(In reply to Segher Boessenkool from comment #7)
> REG_EQ* is documented as only being allowed on insns that set only one
> register.  If you want to change that, you'll have to check *all* code
> that consumes this, see if they rely on that fact or not, and if so,
> change that.

But the point is that the word "set" is ambiguous.  Does it mean
set by a SET or set by any means?  I think it can be read both ways.
After all, a CLOBBER is a form of set too, but that's clearly meant
to be excluded.  

Either way will need auditing.  If we say that this kind of REG_EQUAL
is wrong, we'd in theory need to audit everything that adds REG_EQUAL
notes to make sure it has an appropriate check, or doesn't need one.

I'm also not sure if we really are concerned about multiple registers
in this particular case, or whether it's more the case that we don't
want REG_EQUAL notes on insns with side effects.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-04 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #9 from Segher Boessenkool  ---
"clobber" is a red herring; it is impossible to make a REG_EQ* note for
a clobber, a clobber does not set a new value (that is the whole point
of a clobber).

I think we could allow auto-modify, sure, just as long as it stays clear
what lhs the REG_EQ* note is talking about; and, as you say, everything
needs to be audited for it :-/

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-04 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #10 from Segher Boessenkool  ---
Oh, and ideally, we would replace the whole REG_EQ* stuff with a more
powerful interface that is to-the-side, not embedded in the instruction
stream.  For known exact values, nonzero_bits, known ranges, the works.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-04 Thread rsandifo at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #11 from rsandifo at gcc dot gnu.org  
---
(In reply to Segher Boessenkool from comment #9)
> "clobber" is a red herring; it is impossible to make a REG_EQ* note for
> a clobber, a clobber does not set a new value (that is the whole point
> of a clobber).

It's not possible to attach a REG_EQ* note to an auto-inc-dec
either though (that was my point).  So a clobber doesn't seem
any less of a red herring than the auto-inc-dec itself.  Both
set registers in the sense of changing them, and neither can
be described by a REG_EQ* note.

> I think we could allow auto-modify, sure, just as long as it stays clear
> what lhs the REG_EQ* note is talking about; and, as you say, everything
> needs to be audited for it :-/

Yeah.  But to be clear: I don't think this is more obviously
a change from the status quo than going in the other direction
would be.  The point is that the status quo is ambiguous:
the documentation can be read either way, and the
implementation isn't consistent (hence the bug).

So it's a question of how we resolve the ambiguity.
If we want passes to be able to assume without checking
that insns with REG_EQ* notes don't also include auto
inc-dec, we'll need to audit places that create the notes,
or that update insns with existing notes.

I think it comes down to what the REG_EQ* notes are supposed
to achieve (conceptually, ignoring documentation and the
current implementation for now).  The "weak" guarantee is
that the SET_DEST has the specified value after the
instruction.  The "strong" guarantee extends the weak guarantee
by saying that the SET_SRC of the definition can be replaced
by the REG_EQ* note without changing behaviour.

Having auto-inc-dec in the SET_SRC of the definition is
OK for the weak guarantee but not the strong guarantee.
But the same would be true of any SET_SRC with side effects.
So to frame the question in a different way: let's assume
there's a target-specific intrinsic that has side effects
that can be described using unspec_volatile, and that the
intrinsic also sets a register.  Normally this would be
described as:

  (set (reg X) (unspec_volatile ...))

But if, in a particular context, the target could predict
what the value of X was, could it attach a REG_EQ* note
to say that?  It would then be valid to simplify later
uses of X, even though the definition of X can't change.

IMO this is easier to answer for REG_EQUIV.  That mostly
exists to allow the RA to rematerialise a value instead
of reloading it.  So it's all about replacing the uses
of the register rather than about replacing the definition.
(I'm not saying that the RA would handle a REG_EQUIV note
on the above unspec_volatile correctly -- haven't checked
either way -- but in principle it could.)

The weak guarantee makes life harder for consumers of the
notes that want the strong guarantee, since they then have
to check for side effects themselves.  The weak guarantee
is easy for producers of the notes and for consumers that
only care about users of the register.

The strong guarantee makes life harder for producers of the
notes, or for optimisations that modify insns with existing
notes.  The strong guarantee is easy for consumers of the notes
because it's more conservative.

The weak guarantee potentially allows more optimisation
than the strong guarantee.

I don't think there's much in it.  But I guess I personally
prefer the weak guarantee for the "more optimisation" reason.
There's also a very tenuous analogy with REG_RETURNED,
which is explicitly for saying what the return value is,
rather than saying how the definition can be rewritten.

But whichever we go for, I think it should be a decision
about side effects vs. no side effects, with auto inc-dec
being just one of several potential side effects.  I don't
see any reason why the auto-inc-dec case would be different
from the unspec_volatile case.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-04 Thread rsandifo at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

rsandifo at gcc dot gnu.org  changed:

   What|Removed |Added

 CC||ebotcazou at gcc dot gnu.org

--- Comment #12 from rsandifo at gcc dot gnu.org  
---
Just noticed that Eric wasn't on cc: (although he might have
preferred that it stay that way).

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-04 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #13 from Eric Botcazou  ---
Since Richard kindly invited me to the party, I feel entitled to voice my
personal opinion :-) which is apparently aligned with Richard's.  I think that
we should allow REG_EQUAL notes for insns with exactly one SET of a register,
the contents of the note being the value present in this register after the
execution of the insn at run time, and disregarding side effects.

IMO that's the spirit of the current implementation and thus also probably the
most straightforward way out.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-04 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #14 from Segher Boessenkool  ---
So, hrm, we could in principle attach a REG_EQ* note to any single_set
instruction?

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-05 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #15 from Eric Botcazou  ---
> So, hrm, we could in principle attach a REG_EQ* note to any single_set
> instruction?

Yes, I think that's what is currently implemented modulo bugs, although of
course we do not create a REG_EQUAL note for every single_set insn in practice.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-05 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #16 from Jakub Jelinek  ---
Ok, so what we do about this bug then if it ought to be combine.c that needs
changing?  For REG_EQUAL notes in combine_instructions check for the
auto-incdec side-effects in the pattern (I'd hope we don't have them in
REG_EQUAL notes content) and if there are any, punt?  At least for backporting
that seems like the right solution, and given that it seems try_combine also
punts on these if we remove or add any in the patterns, it seems in line with
what the rest of combiner does.  Or, shall it e.g. queue the side-effects in
some new argument to try_combine and if the combination would succeed, add the
side-effect as yet another instruction (if it can match and is cheaper than
what we have previously)?

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-05 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #17 from Eric Botcazou  ---
> Ok, so what we do about this bug then if it ought to be combine.c that needs
> changing?  For REG_EQUAL notes in combine_instructions check for the
> auto-incdec side-effects in the pattern (I'd hope we don't have them in
> REG_EQUAL notes content) and if there are any, punt?  At least for
> backporting that seems like the right solution, and given that it seems
> try_combine also punts on these if we remove or add any in the patterns, it
> seems in line with what the rest of combiner does.

At least the fix for the branches seems to be clear: do not do the temporary
replacement in combine_instructions if the SET_SRC has side effects; there are
a bunch of similar side_effects_p tests in the combiner.

> Or, shall it e.g. queue the side-effects in some new argument to try_combine
> and if the combination would succeed, add the side-effect as yet another 
> instruction (if it can match and is cheaper than what we have previously)?

That seems overkill to me, even on the mainline, but others might disagree.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-05 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #18 from Jakub Jelinek  ---
Created attachment 48451
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48451&action=edit
gcc11-pr94873.patch

Untested patch then.

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-05 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #19 from Segher Boessenkool  ---
(In reply to Jakub Jelinek from comment #18)
> Created attachment 48451 [details]
> gcc11-pr94873.patch
> 
> Untested patch then.

This one-liner is pre-approved.  Thank you!

[Bug rtl-optimization/94873] [8/9/10/11 Regression] wrong code with -O -fno-merge-constants -fno-split-wide-types -fno-tree-fre

2020-05-06 Thread cvs-commit at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94873

--- Comment #20 from CVS Commits  ---
The master branch has been updated by Jakub Jelinek :

https://gcc.gnu.org/g:f14848aea70066777faf201c0b6eb3c5520bfab9

commit r11-127-gf14848aea70066777faf201c0b6eb3c5520bfab9
Author: Jakub Jelinek 
Date:   Wed May 6 09:31:19 2020 +0200

combine: Don't replace SET_SRC with REG_EQUAL note content if SET_SRC has
side-effects [PR94873]

There were some discussions about whether REG_EQUAL notes are valid on
insns with a single
set which contains auto-inc-dec side-effects in the SET_SRC and the
majority thinks that
it should be valid.  So, this patch fixes the combiner to punt in that
case, because otherwise
the auto-inc-dec side-effects from the SET_SRC are lost.

2020-05-06  Jakub Jelinek  

PR rtl-optimization/94873
* combine.c (combine_instructions): Don't optimize using REG_EQUAL
note if SET_SRC (set) has side-effects.

* gcc.dg/pr94873.c: New test.