public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] rtl-optimization/113255 - avoid re-associating REG_POINTER MINUS
       [not found] <20240201142121.B149B38582BB@sourceware.org>
@ 2024-02-02 14:40 ` Jeff Law
  2024-02-05  8:15   ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Jeff Law @ 2024-02-02 14:40 UTC (permalink / raw)
  To: Richard Biener, gcc-patches



On 2/1/24 07:20, Richard Biener wrote:
> The following avoids re-associating
> 
>   (minus:DI (reg/f:DI 119)
>      (minus:DI (reg/f:DI 120)
>          (reg/f:DI 114)))
> 
> into
> 
>   (minus:DI (plus:DI (reg/f:DI 114)
>          (reg/f:DI 119))
>      (reg/f:DI 120))
> 
> as that possibly confuses the REG_POINTER heuristics of RTL
> alias analysis.  This happens to miscompile the PRs testcase
> during DSE which expands addresses via CSELIB which eventually
> simplifies what it substituted to.  The original code does
> the innocent ptr - (ptr2 - ptr2'), bias a pointer by the
> difference of two other pointers.
> 
> --
> 
> This is what I propose for the PR for branches, I have not made much
> progress with fixing the fallout on the RTL alias analysis change
> on trunk, so this is the alternative if we decide to revert that.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu on the gcc-13
> branch, bootstrapped after reverting of the previous fix on
> x86_64-unknown-linux-gnu on trunk, testing is still ongoing there.
> 
> OK?  Any preference for trunk?
> 
> Thanks,
> Richard.
> 
> 	PR rtl-optimization/113255
> 	* simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
> 	Do not re-associate a MINUS with a REG_POINTER op0.
Nasty little set of problems.  I don't think we ever pondered that we 
could have multiple REGNO_POINTER_FLAG objects in the same expression, 
but clearly that can happen once you introduce a 3rd term in the expression.

I don't mind avoiding the reassociation, but it feels like we're 
papering over problems in alias.cc.  Conceptually it seems like if we 
have two objects with REG_POINTER set, then we can't know which one is 
the real base.  So your patch in the PR wasn't that bad.

Alternately, just stop using REG_POINTER for alias analysis?   It looks 
fundamentally flawed to me in that context.  In fact, one might argue 
that the only legitimate use would be to indicate to the target that we 
know a pointer points into an object.  Some targets (the PA) need this 
because x + y is not the same as y + x when used as a memory address.

If we wanted to be a bit more surgical, drop REG_POINTER from just the 
MINUS handling in alias.cc?

Jeff

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] rtl-optimization/113255 - avoid re-associating REG_POINTER MINUS
  2024-02-02 14:40 ` [PATCH 2/2] rtl-optimization/113255 - avoid re-associating REG_POINTER MINUS Jeff Law
@ 2024-02-05  8:15   ` Richard Biener
  2024-02-05 15:43     ` Jeff Law
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Biener @ 2024-02-05  8:15 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

On Fri, 2 Feb 2024, Jeff Law wrote:

> 
> 
> On 2/1/24 07:20, Richard Biener wrote:
> > The following avoids re-associating
> > 
> >   (minus:DI (reg/f:DI 119)
> >      (minus:DI (reg/f:DI 120)
> >          (reg/f:DI 114)))
> > 
> > into
> > 
> >   (minus:DI (plus:DI (reg/f:DI 114)
> >          (reg/f:DI 119))
> >      (reg/f:DI 120))
> > 
> > as that possibly confuses the REG_POINTER heuristics of RTL
> > alias analysis.  This happens to miscompile the PRs testcase
> > during DSE which expands addresses via CSELIB which eventually
> > simplifies what it substituted to.  The original code does
> > the innocent ptr - (ptr2 - ptr2'), bias a pointer by the
> > difference of two other pointers.
> > 
> > --
> > 
> > This is what I propose for the PR for branches, I have not made much
> > progress with fixing the fallout on the RTL alias analysis change
> > on trunk, so this is the alternative if we decide to revert that.
> > 
> > Bootstrapped and tested on x86_64-unknown-linux-gnu on the gcc-13
> > branch, bootstrapped after reverting of the previous fix on
> > x86_64-unknown-linux-gnu on trunk, testing is still ongoing there.
> > 
> > OK?  Any preference for trunk?
> > 
> > Thanks,
> > Richard.
> > 
> >  PR rtl-optimization/113255
> >  * simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
> >  Do not re-associate a MINUS with a REG_POINTER op0.
> Nasty little set of problems.  I don't think we ever pondered that we could
> have multiple REGNO_POINTER_FLAG objects in the same expression, but clearly
> that can happen once you introduce a 3rd term in the expression.
> 
> I don't mind avoiding the reassociation, but it feels like we're papering over
> problems in alias.cc.  Conceptually it seems like if we have two objects with
> REG_POINTER set, then we can't know which one is the real base.  So your patch
> in the PR wasn't that bad.

It wasn't bad, it's the only correct fix.  The question is what we do
for branches (or whether we do anything there) and whether we just accept
that that fix causes some optimization regressions.

> Alternately, just stop using REG_POINTER for alias analysis?   It looks
> fundamentally flawed to me in that context.  In fact, one might argue that the
> only legitimate use would be to indicate to the target that we know a pointer
> points into an object.  Some targets (the PA) need this because x + y is not
> the same as y + x when used as a memory address.
> 
> If we wanted to be a bit more surgical, drop REG_POINTER from just the MINUS
> handling in alias.cc?

The problem is that REG_POINTER is just used as a heuristic
(and compile-time optimization) as to which of a binary operator
operands we use a base of (preferrably).  find_base_{term,value}
happily look at operands that are not REG_POINTER (that are
not REG_P), since for the case in question, even w/o re-assoc
there would be no way to say the inner MINUS is not a pointer
(it's a REG flag).

The heuristics don't help much when passes like DSE use CSELIB
and combine operations like above, we then get to see that
the way find_base_{term,value} perform pointer analysis is
fundamentally flawed.  Any tweaking there has the chance to
make other cases run into wrong base discoveries.

I'll take it that we need to live with the regressions for GCC 14
and the wrong-code bug in GCC 13 and earlier.

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] rtl-optimization/113255 - avoid re-associating REG_POINTER MINUS
  2024-02-05  8:15   ` Richard Biener
@ 2024-02-05 15:43     ` Jeff Law
  2024-02-06  8:59       ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Jeff Law @ 2024-02-05 15:43 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches



On 2/5/24 01:15, Richard Biener wrote:

>>>
>>>   PR rtl-optimization/113255
>>>   * simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
>>>   Do not re-associate a MINUS with a REG_POINTER op0.
>> Nasty little set of problems.  I don't think we ever pondered that we could
>> have multiple REGNO_POINTER_FLAG objects in the same expression, but clearly
>> that can happen once you introduce a 3rd term in the expression.
>>
>> I don't mind avoiding the reassociation, but it feels like we're papering over
>> problems in alias.cc.  Conceptually it seems like if we have two objects with
>> REG_POINTER set, then we can't know which one is the real base.  So your patch
>> in the PR wasn't that bad.
> 
> It wasn't bad, it's the only correct fix.  The question is what we do
> for branches (or whether we do anything there) and whether we just accept
> that that fix causes some optimization regressions.
For the branches, I'd go whatever you feel the safest change is.  While 
it looks like some of this is fundamentally broken, it can't be *that* 
bad since it's just rearing its ugly head now.

I could even make a case that going with the patch from the PR for the 
branches is reasonable.  It's attacking at least part of the root problem.

> 
>> Alternately, just stop using REG_POINTER for alias analysis?   It looks
>> fundamentally flawed to me in that context.  In fact, one might argue that the
>> only legitimate use would be to indicate to the target that we know a pointer
>> points into an object.  Some targets (the PA) need this because x + y is not
>> the same as y + x when used as a memory address.
>>
>> If we wanted to be a bit more surgical, drop REG_POINTER from just the MINUS
>> handling in alias.cc?
> 
> The problem is that REG_POINTER is just used as a heuristic
> (and compile-time optimization) as to which of a binary operator
> operands we use a base of (preferrably).  find_base_{term,value}
> happily look at operands that are not REG_POINTER (that are
> not REG_P), since for the case in question, even w/o re-assoc
> there would be no way to say the inner MINUS is not a pointer
> (it's a REG flag).
> 
> The heuristics don't help much when passes like DSE use CSELIB
> and combine operations like above, we then get to see that
> the way find_base_{term,value} perform pointer analysis is
> fundamentally flawed.  Any tweaking there has the chance to
> make other cases run into wrong base discoveries.
> 
Exactly.  So maybe I'm missing something -- it sounds like we both agree 
that using REG_POINTER in the aliasing code is just fundamentally broken 
in the modern world (and perhaps has been for a long time).  So we 
"just" need to excise that code from alias.cc.




> I'll take it that we need to live with the regressions for GCC 14
> and the wrong-code bug in GCC 13 and earlier.
I'm not sure I agree with this statement.  Or maybe I thought the patch 
in the PR was more effective than it really is.  At some level we ought 
to be able to cut out the short-cuts enabled by REG_POINTER.  That runs 
the risk of perturbing more code, but it seems to me that's a risk we 
might need to take.

jeff

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] rtl-optimization/113255 - avoid re-associating REG_POINTER MINUS
  2024-02-05 15:43     ` Jeff Law
@ 2024-02-06  8:59       ` Richard Biener
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Biener @ 2024-02-06  8:59 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

On Mon, 5 Feb 2024, Jeff Law wrote:

> 
> 
> On 2/5/24 01:15, Richard Biener wrote:
> 
> >>>
> >>>   PR rtl-optimization/113255
> >>>   * simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
> >>>   Do not re-associate a MINUS with a REG_POINTER op0.
> >> Nasty little set of problems.  I don't think we ever pondered that we could
> >> have multiple REGNO_POINTER_FLAG objects in the same expression, but
> >> clearly
> >> that can happen once you introduce a 3rd term in the expression.
> >>
> >> I don't mind avoiding the reassociation, but it feels like we're papering
> >> over
> >> problems in alias.cc.  Conceptually it seems like if we have two objects
> >> with
> >> REG_POINTER set, then we can't know which one is the real base.  So your
> >> patch
> >> in the PR wasn't that bad.
> > 
> > It wasn't bad, it's the only correct fix.  The question is what we do
> > for branches (or whether we do anything there) and whether we just accept
> > that that fix causes some optimization regressions.
> For the branches, I'd go whatever you feel the safest change is.  While it
> looks like some of this is fundamentally broken, it can't be *that* bad since
> it's just rearing its ugly head now.

It did in the past as well where we worked around by tweaking either
code generation or heuristics.

> I could even make a case that going with the patch from the PR for the
> branches is reasonable.  It's attacking at least part of the root problem.
> 
> > 
> >> Alternately, just stop using REG_POINTER for alias analysis?   It looks
> >> fundamentally flawed to me in that context.  In fact, one might argue that
> >> the
> >> only legitimate use would be to indicate to the target that we know a
> >> pointer
> >> points into an object.  Some targets (the PA) need this because x + y is
> >> not
> >> the same as y + x when used as a memory address.
> >>
> >> If we wanted to be a bit more surgical, drop REG_POINTER from just the
> >> MINUS
> >> handling in alias.cc?
> > 
> > The problem is that REG_POINTER is just used as a heuristic
> > (and compile-time optimization) as to which of a binary operator
> > operands we use a base of (preferrably).  find_base_{term,value}
> > happily look at operands that are not REG_POINTER (that are
> > not REG_P), since for the case in question, even w/o re-assoc
> > there would be no way to say the inner MINUS is not a pointer
> > (it's a REG flag).
> > 
> > The heuristics don't help much when passes like DSE use CSELIB
> > and combine operations like above, we then get to see that
> > the way find_base_{term,value} perform pointer analysis is
> > fundamentally flawed.  Any tweaking there has the chance to
> > make other cases run into wrong base discoveries.
> > 
> Exactly.  So maybe I'm missing something -- it sounds like we both agree that
> using REG_POINTER in the aliasing code is just fundamentally broken in the
> modern world (and perhaps has been for a long time).  So we "just" need to
> excise that code from alias.cc.

Btw, it's not so much REG_POINTER that is problematic - it's that
find_base_{term,value} for binary operators doesn't merge the
"points-to solution" for both operands and that if it doesn't
find a "base" in the part of the IL it sees it assumes the points-to
set is empty.  That is, it combines "is not a pointer" and "I have
no idea" in the NULL return value.  The fix that's now installed on
trunk "solves" this lack of merging by never handling any case that
would require merging (optimistically treating CONST_INT as known
not pointer).

I don't think proper PTA analysis on RTL will yield anything useful
and we're better off tracking the guarantees which it tries to
handle with the ADDRESS base values for stack, spill and argument
space when we create MEMs (and annotate MEMs).  But I have a hard time
deciphering RTL details which isn't really my main area of expertise ...
We do already tag some MEMs (like spills with their special MEM_ATTRs),
but argument setup seems lacking in this regard, and that's the
difficult to understand part since it involves three different
unique_base_value (based on STACK_POINTER_REGNUM, ARG_POINTER_REGNUM
and FRAME_POINTER_REGNUM) and the base of a MEM seems to vary based
on elimination state :/

> > I'll take it that we need to live with the regressions for GCC 14
> > and the wrong-code bug in GCC 13 and earlier.
> I'm not sure I agree with this statement.  Or maybe I thought the patch in the
> PR was more effective than it really is.  At some level we ought to be able to
> cut out the short-cuts enabled by REG_POINTER.  That runs the risk of
> perturbing more code, but it seems to me that's a risk we might need to take.

REG_POINTER just determines which operand we prefer, so it's a
heuristic for the case when multiple bases are involved in the computation 
of the final value.

Richard.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/2] rtl-optimization/113255 - avoid re-associating REG_POINTER MINUS
@ 2024-02-01 14:20 Richard Biener
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Biener @ 2024-02-01 14:20 UTC (permalink / raw)
  To: gcc-patches

The following avoids re-associating

 (minus:DI (reg/f:DI 119)
    (minus:DI (reg/f:DI 120)
        (reg/f:DI 114)))

into

 (minus:DI (plus:DI (reg/f:DI 114)
        (reg/f:DI 119))
    (reg/f:DI 120))

as that possibly confuses the REG_POINTER heuristics of RTL
alias analysis.  This happens to miscompile the PRs testcase
during DSE which expands addresses via CSELIB which eventually
simplifies what it substituted to.  The original code does
the innocent ptr - (ptr2 - ptr2'), bias a pointer by the
difference of two other pointers.

--

This is what I propose for the PR for branches, I have not made much
progress with fixing the fallout on the RTL alias analysis change
on trunk, so this is the alternative if we decide to revert that.

Bootstrapped and tested on x86_64-unknown-linux-gnu on the gcc-13
branch, bootstrapped after reverting of the previous fix on
x86_64-unknown-linux-gnu on trunk, testing is still ongoing there.

OK?  Any preference for trunk?

Thanks,
Richard.

	PR rtl-optimization/113255
	* simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
	Do not re-associate a MINUS with a REG_POINTER op0.
---
 gcc/simplify-rtx.cc | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index ee75079917f..0108d0aa3bd 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -3195,11 +3195,15 @@ simplify_context::simplify_binary_operation_1 (rtx_code code,
          canonicalize (minus A (plus B C)) to (minus (minus A B) C).
 	 Don't use the associative law for floating point.
 	 The inaccuracy makes it nonassociative,
-	 and subtle programs can break if operations are associated.  */
+	 and subtle programs can break if operations are associated.
+	 Don't use the associative law when subtracting a MINUS from
+	 a REG_POINTER as that can trick find_base_term into discovering
+	 the wrong base.  */
 
       if (INTEGRAL_MODE_P (mode)
 	  && (plus_minus_operand_p (op0)
-	      || plus_minus_operand_p (op1))
+	      || ((!REG_P (op0) || !REG_POINTER (op0))
+		  && plus_minus_operand_p (op1)))
 	  && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
 	return tem;
 
-- 
2.35.3

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-02-06  9:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20240201142121.B149B38582BB@sourceware.org>
2024-02-02 14:40 ` [PATCH 2/2] rtl-optimization/113255 - avoid re-associating REG_POINTER MINUS Jeff Law
2024-02-05  8:15   ` Richard Biener
2024-02-05 15:43     ` Jeff Law
2024-02-06  8:59       ` Richard Biener
2024-02-01 14:20 Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).