public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR tree-opt/113673: Avoid load merging from potentially trapping additions.
@ 2024-04-28  9:11 Roger Sayle
  2024-05-02  9:26 ` Richard Biener
  0 siblings, 1 reply; 4+ messages in thread
From: Roger Sayle @ 2024-04-28  9:11 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1509 bytes --]


This patch fixes PR tree-optimization/113673, a P2 ice-on-valid regression
caused by load merging of (ptr[0]<<8)+ptr[1] when -ftrapv has been
specified.  When the operator is | or ^ this is safe, but for addition
of signed integer types, a trap may be generated/required, so merging this
idiom into a single non-trapping instruction is inappropriate, confusing
the compiler by transforming a basic block with an exception edge into one
without.  One fix is to be more selective for PLUS_EXPR than for
BIT_IOR_EXPR or BIT_XOR_EXPR in gimple-ssa-store-merging.cc's
find_bswap_or_nop_1 function.

An alternate solution might be to notice that in this idiom the addition
can't overflow, but that this detail wasn't apparent when exception edges
were added to the CFG.  In which case, it's safe to remove (or mark for
removal) the problematic exceptional edge.  Unfortunately updating the
CFG is a part of the compiler that I'm less familiar with.

This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}
with no new failures.  Ok for mainline?


2024-04-28  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
        PR tree-optimization/113673
        * gimple-ssa-store-merging.cc (find_bswap_or_nop_1) <case
PLUS_EXPR>:
        Don't perform load merging if a signed addition may trap.

gcc/testsuite/ChangeLog
        PR tree-optimization/113673
        * g++.dg/pr113673.C: New test case.


Thanks in advance,
Roger
--


[-- Attachment #2: patchlm.txt --]
[-- Type: text/plain, Size: 1195 bytes --]

diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc
index cb0cb5f..41a1066 100644
--- a/gcc/gimple-ssa-store-merging.cc
+++ b/gcc/gimple-ssa-store-merging.cc
@@ -776,9 +776,16 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
 
       switch (code)
 	{
+	case PLUS_EXPR:
+	  /* Don't perform load merging if this addition can trap.  */
+	  if (cfun->can_throw_non_call_exceptions
+	      && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+	      && TYPE_OVERFLOW_TRAPS (TREE_TYPE (rhs1)))
+	    return NULL;
+	  /* Fallthru.  */
+
 	case BIT_IOR_EXPR:
 	case BIT_XOR_EXPR:
-	case PLUS_EXPR:
 	  source_stmt1 = find_bswap_or_nop_1 (rhs1_stmt, &n1, limit - 1);
 
 	  if (!source_stmt1)
diff --git a/gcc/testsuite/g++.dg/pr113673.C b/gcc/testsuite/g++.dg/pr113673.C
new file mode 100644
index 0000000..1148977
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr113673.C
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fnon-call-exceptions -ftrapv" } */
+
+struct s { ~s(); };
+void
+h (unsigned char *data, int c)
+{
+  s a1;
+  while (c)
+    {
+      int m = *data++ << 8;
+      m += *data++;
+    }
+}

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

* Re: [PATCH] PR tree-opt/113673: Avoid load merging from potentially trapping additions.
  2024-04-28  9:11 [PATCH] PR tree-opt/113673: Avoid load merging from potentially trapping additions Roger Sayle
@ 2024-05-02  9:26 ` Richard Biener
  2024-06-21 20:51   ` [PATCH v2] PR tree-opt/113673: Avoid load merging when potentially trapping Roger Sayle
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Biener @ 2024-05-02  9:26 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches

On Sun, Apr 28, 2024 at 11:11 AM Roger Sayle <roger@nextmovesoftware.com> wrote:
>
>
> This patch fixes PR tree-optimization/113673, a P2 ice-on-valid regression
> caused by load merging of (ptr[0]<<8)+ptr[1] when -ftrapv has been
> specified.  When the operator is | or ^ this is safe, but for addition
> of signed integer types, a trap may be generated/required, so merging this
> idiom into a single non-trapping instruction is inappropriate, confusing
> the compiler by transforming a basic block with an exception edge into one
> without.  One fix is to be more selective for PLUS_EXPR than for
> BIT_IOR_EXPR or BIT_XOR_EXPR in gimple-ssa-store-merging.cc's
> find_bswap_or_nop_1 function.
>
> An alternate solution might be to notice that in this idiom the addition
> can't overflow, but that this detail wasn't apparent when exception edges
> were added to the CFG.  In which case, it's safe to remove (or mark for
> removal) the problematic exceptional edge.  Unfortunately updating the
> CFG is a part of the compiler that I'm less familiar with.
>
> This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> and make -k check, both with and without --target_board=unix{-m32}
> with no new failures.  Ok for mainline?

Instead of

+       case PLUS_EXPR:
+         /* Don't perform load merging if this addition can trap.  */
+         if (cfun->can_throw_non_call_exceptions
+             && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+             && TYPE_OVERFLOW_TRAPS (TREE_TYPE (rhs1)))
+           return NULL;

please check stmt_can_throw_internal (cfun, stmt) - the find_bswap_or_no_load
call in the function suffers from the same issue, so this should probably
be checked before that call even.

Thanks,
Richard.

>
> 2024-04-28  Roger Sayle  <roger@nextmovesoftware.com>
>
> gcc/ChangeLog
>         PR tree-optimization/113673
>         * gimple-ssa-store-merging.cc (find_bswap_or_nop_1) <case
> PLUS_EXPR>:
>         Don't perform load merging if a signed addition may trap.
>
> gcc/testsuite/ChangeLog
>         PR tree-optimization/113673
>         * g++.dg/pr113673.C: New test case.
>
>
> Thanks in advance,
> Roger
> --
>

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

* [PATCH v2] PR tree-opt/113673: Avoid load merging when potentially trapping.
  2024-05-02  9:26 ` Richard Biener
@ 2024-06-21 20:51   ` Roger Sayle
  2024-06-24 12:21     ` Richard Biener
  0 siblings, 1 reply; 4+ messages in thread
From: Roger Sayle @ 2024-06-21 20:51 UTC (permalink / raw)
  To: gcc-patches; +Cc: 'Richard Biener'

[-- Attachment #1: Type: text/plain, Size: 4357 bytes --]


Hi Richard,
Thanks for the review and apologies for taking so long to get back to this.
This revision implements your suggestions from early May, as found at
https://gcc.gnu.org/pipermail/gcc-patches/2024-May/650405.html

This patch fixes PR tree-optimization/113673, a P2 ice-on-valid regression
caused by load merging of (ptr[0]<<8)+ptr[1] when -ftrapv has been
specified.  When the operator is | or ^ this is safe, but for addition
of signed integer types, a trap may be generated/required, so merging this
idiom into a single non-trapping instruction is inappropriate, confusing
the compiler by transforming a basic block with an exception edge into one
without.

This revision implements Richard Biener's feedback to add an early check
for stmt_can_throw_internal (cfun, stmt) to prevent transforming in the
presence of any statement that could trap, not just overflow on addition.
The one other tweak included in this patch is to mark the local function
find_bswap_or_nop_load as static ensuring that it isn't called from outside
this file, and guaranteeing that it is dominated by stmt_can_throw_internal
checking.

This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}
with no new failures.  Ok for mainline?


2024-06-21  Roger Sayle  <roger@nextmovesoftware.com>
            Richard Biener  <rguenther@suse.de>

gcc/ChangeLog
        PR tree-optimization/113673
        * gimple-ssa-store-merging.cc (find_bswap_or_nop_load): Make static.
        (find_bswap_or_nop_1): Avoid transformations (load merging) when
        stmt_can_throw_internal indicates that a statement can trap.

gcc/testsuite/ChangeLog
        PR tree-optimization/113673
        * g++.dg/pr113673.C: New test case.

Thanks in advance,
Roger
--

> -----Original Message-----
> From: Richard Biener <richard.guenther@gmail.com>
> Sent: 02 May 2024 10:27
> Subject: Re: [PATCH] PR tree-opt/113673: Avoid load merging from potentially
> trapping additions.
> 
> On Sun, Apr 28, 2024 at 11:11 AM Roger Sayle <roger@nextmovesoftware.com>
> wrote:
> >
> > This patch fixes PR tree-optimization/113673, a P2 ice-on-valid
> > regression caused by load merging of (ptr[0]<<8)+ptr[1] when -ftrapv
> > has been specified.  When the operator is | or ^ this is safe, but for
> > addition of signed integer types, a trap may be generated/required, so
> > merging this idiom into a single non-trapping instruction is
> > inappropriate, confusing the compiler by transforming a basic block
> > with an exception edge into one without.  One fix is to be more
> > selective for PLUS_EXPR than for BIT_IOR_EXPR or BIT_XOR_EXPR in
> > gimple-ssa-store-merging.cc's
> > find_bswap_or_nop_1 function.
> >
> > An alternate solution might be to notice that in this idiom the
> > addition can't overflow, but that this detail wasn't apparent when
> > exception edges were added to the CFG.  In which case, it's safe to
> > remove (or mark for
> > removal) the problematic exceptional edge.  Unfortunately updating the
> > CFG is a part of the compiler that I'm less familiar with.
> >
> > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> > and make -k check, both with and without --target_board=unix{-m32}
> > with no new failures.  Ok for mainline?
> 
> Instead of
> 
> +       case PLUS_EXPR:
> +         /* Don't perform load merging if this addition can trap.  */
> +         if (cfun->can_throw_non_call_exceptions
> +             && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
> +             && TYPE_OVERFLOW_TRAPS (TREE_TYPE (rhs1)))
> +           return NULL;
> 
> please check stmt_can_throw_internal (cfun, stmt) - the find_bswap_or_no_load
> call in the function suffers from the same issue, so this should probably be
> checked before that call even.
> 
> Thanks,
> Richard.
> 
> >
> > 2024-04-28  Roger Sayle  <roger@nextmovesoftware.com>
> >
> > gcc/ChangeLog
> >         PR tree-optimization/113673
> >         * gimple-ssa-store-merging.cc (find_bswap_or_nop_1) <case
> > PLUS_EXPR>:
> >         Don't perform load merging if a signed addition may trap.
> >
> > gcc/testsuite/ChangeLog
> >         PR tree-optimization/113673
> >         * g++.dg/pr113673.C: New test case.
> >


[-- Attachment #2: patchlm2.txt --]
[-- Type: text/plain, Size: 1442 bytes --]

diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc
index cb0cb5f..7dba4a7 100644
--- a/gcc/gimple-ssa-store-merging.cc
+++ b/gcc/gimple-ssa-store-merging.cc
@@ -363,7 +363,7 @@ init_symbolic_number (struct symbolic_number *n, tree src)
    the answer. If so, REF is that memory source and the base of the memory area
    accessed and the offset of the access from that base are recorded in N.  */
 
-bool
+static bool
 find_bswap_or_nop_load (gimple *stmt, tree ref, struct symbolic_number *n)
 {
   /* Leaf node is an array or component ref. Memorize its base and
@@ -610,7 +610,9 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
   gimple *rhs1_stmt, *rhs2_stmt, *source_stmt1;
   enum gimple_rhs_class rhs_class;
 
-  if (!limit || !is_gimple_assign (stmt))
+  if (!limit
+      || !is_gimple_assign (stmt)
+      || stmt_can_throw_internal (cfun, stmt))
     return NULL;
 
   rhs1 = gimple_assign_rhs1 (stmt);
diff --git a/gcc/testsuite/g++.dg/pr113673.C b/gcc/testsuite/g++.dg/pr113673.C
new file mode 100644
index 0000000..1148977
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr113673.C
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fnon-call-exceptions -ftrapv" } */
+
+struct s { ~s(); };
+void
+h (unsigned char *data, int c)
+{
+  s a1;
+  while (c)
+    {
+      int m = *data++ << 8;
+      m += *data++;
+    }
+}

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

* Re: [PATCH v2] PR tree-opt/113673: Avoid load merging when potentially trapping.
  2024-06-21 20:51   ` [PATCH v2] PR tree-opt/113673: Avoid load merging when potentially trapping Roger Sayle
@ 2024-06-24 12:21     ` Richard Biener
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Biener @ 2024-06-24 12:21 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches

On Fri, Jun 21, 2024 at 10:51 PM Roger Sayle <roger@nextmovesoftware.com> wrote:
>
>
> Hi Richard,
> Thanks for the review and apologies for taking so long to get back to this.
> This revision implements your suggestions from early May, as found at
> https://gcc.gnu.org/pipermail/gcc-patches/2024-May/650405.html
>
> This patch fixes PR tree-optimization/113673, a P2 ice-on-valid regression
> caused by load merging of (ptr[0]<<8)+ptr[1] when -ftrapv has been
> specified.  When the operator is | or ^ this is safe, but for addition
> of signed integer types, a trap may be generated/required, so merging this
> idiom into a single non-trapping instruction is inappropriate, confusing
> the compiler by transforming a basic block with an exception edge into one
> without.
>
> This revision implements Richard Biener's feedback to add an early check
> for stmt_can_throw_internal (cfun, stmt) to prevent transforming in the
> presence of any statement that could trap, not just overflow on addition.
> The one other tweak included in this patch is to mark the local function
> find_bswap_or_nop_load as static ensuring that it isn't called from outside
> this file, and guaranteeing that it is dominated by stmt_can_throw_internal
> checking.
>
> This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> and make -k check, both with and without --target_board=unix{-m32}
> with no new failures.  Ok for mainline?

OK.

Thanks,
Richard.

>
> 2024-06-21  Roger Sayle  <roger@nextmovesoftware.com>
>             Richard Biener  <rguenther@suse.de>
>
> gcc/ChangeLog
>         PR tree-optimization/113673
>         * gimple-ssa-store-merging.cc (find_bswap_or_nop_load): Make static.
>         (find_bswap_or_nop_1): Avoid transformations (load merging) when
>         stmt_can_throw_internal indicates that a statement can trap.
>
> gcc/testsuite/ChangeLog
>         PR tree-optimization/113673
>         * g++.dg/pr113673.C: New test case.
>
> Thanks in advance,
> Roger
> --
>
> > -----Original Message-----
> > From: Richard Biener <richard.guenther@gmail.com>
> > Sent: 02 May 2024 10:27
> > Subject: Re: [PATCH] PR tree-opt/113673: Avoid load merging from potentially
> > trapping additions.
> >
> > On Sun, Apr 28, 2024 at 11:11 AM Roger Sayle <roger@nextmovesoftware.com>
> > wrote:
> > >
> > > This patch fixes PR tree-optimization/113673, a P2 ice-on-valid
> > > regression caused by load merging of (ptr[0]<<8)+ptr[1] when -ftrapv
> > > has been specified.  When the operator is | or ^ this is safe, but for
> > > addition of signed integer types, a trap may be generated/required, so
> > > merging this idiom into a single non-trapping instruction is
> > > inappropriate, confusing the compiler by transforming a basic block
> > > with an exception edge into one without.  One fix is to be more
> > > selective for PLUS_EXPR than for BIT_IOR_EXPR or BIT_XOR_EXPR in
> > > gimple-ssa-store-merging.cc's
> > > find_bswap_or_nop_1 function.
> > >
> > > An alternate solution might be to notice that in this idiom the
> > > addition can't overflow, but that this detail wasn't apparent when
> > > exception edges were added to the CFG.  In which case, it's safe to
> > > remove (or mark for
> > > removal) the problematic exceptional edge.  Unfortunately updating the
> > > CFG is a part of the compiler that I'm less familiar with.
> > >
> > > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> > > and make -k check, both with and without --target_board=unix{-m32}
> > > with no new failures.  Ok for mainline?
> >
> > Instead of
> >
> > +       case PLUS_EXPR:
> > +         /* Don't perform load merging if this addition can trap.  */
> > +         if (cfun->can_throw_non_call_exceptions
> > +             && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
> > +             && TYPE_OVERFLOW_TRAPS (TREE_TYPE (rhs1)))
> > +           return NULL;
> >
> > please check stmt_can_throw_internal (cfun, stmt) - the find_bswap_or_no_load
> > call in the function suffers from the same issue, so this should probably be
> > checked before that call even.
> >
> > Thanks,
> > Richard.
> >
> > >
> > > 2024-04-28  Roger Sayle  <roger@nextmovesoftware.com>
> > >
> > > gcc/ChangeLog
> > >         PR tree-optimization/113673
> > >         * gimple-ssa-store-merging.cc (find_bswap_or_nop_1) <case
> > > PLUS_EXPR>:
> > >         Don't perform load merging if a signed addition may trap.
> > >
> > > gcc/testsuite/ChangeLog
> > >         PR tree-optimization/113673
> > >         * g++.dg/pr113673.C: New test case.
> > >
>

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

end of thread, other threads:[~2024-06-24 12:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-28  9:11 [PATCH] PR tree-opt/113673: Avoid load merging from potentially trapping additions Roger Sayle
2024-05-02  9:26 ` Richard Biener
2024-06-21 20:51   ` [PATCH v2] PR tree-opt/113673: Avoid load merging when potentially trapping Roger Sayle
2024-06-24 12:21     ` 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).