[x86] PR target/106122: Don't update %esp via the stack with -Oz.

Message ID 008301d88cd5$2936ce90$7ba46bb0$@nextmovesoftware.com
State Committed
Commit 17419b61edd350147b0cc10c3da0b8461e51a42c
Headers
Series [x86] PR target/106122: Don't update %esp via the stack with -Oz. |

Commit Message

Roger Sayle June 30, 2022, 11 p.m. UTC
  When optimizing for size with -Oz, setting a register can be minimized by
pushing an immediate value to the stack and popping it to the destination.
Alas the one general register that shouldn't be updated via the stack is
the stack pointer itself, where "pop %esp" can't be represented in GCC's
RTL ("use of a register mentioned in pre_inc, pre_dec, post_inc or
post_dec is not permitted within the same instruction").  This patch
fixes PR target/106122 by explicitly checking for SP_REG in the
problematic peephole2.

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?


2022-06-30  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
        PR target/106122
        * config/i386/i386.md (peephole2): Avoid generating pop %esp
        when optimizing for size.

gcc/testsuite/ChangeLog
        PR target/106122
        * gcc.target/i386/pr106122.c: New test case.


Thanks in advance,
Roger
--
  

Comments

Uros Bizjak July 1, 2022, 6:03 a.m. UTC | #1
On Fri, Jul 1, 2022 at 1:00 AM Roger Sayle <roger@nextmovesoftware.com> wrote:
>
>
> When optimizing for size with -Oz, setting a register can be minimized by
> pushing an immediate value to the stack and popping it to the destination.
> Alas the one general register that shouldn't be updated via the stack is
> the stack pointer itself, where "pop %esp" can't be represented in GCC's
> RTL ("use of a register mentioned in pre_inc, pre_dec, post_inc or
> post_dec is not permitted within the same instruction").  This patch
> fixes PR target/106122 by explicitly checking for SP_REG in the
> problematic peephole2.
>
> 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?
>
>
> 2022-06-30  Roger Sayle  <roger@nextmovesoftware.com>
>
> gcc/ChangeLog
>         PR target/106122
>         * config/i386/i386.md (peephole2): Avoid generating pop %esp
>         when optimizing for size.
>
> gcc/testsuite/ChangeLog
>         PR target/106122
>         * gcc.target/i386/pr106122.c: New test case.

OK for mainline and backport.

Thanks,
Uros.

>
>
> Thanks in advance,
> Roger
> --
>
  

Patch

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 125a3b4..3b6f362 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2588,7 +2588,8 @@ 
   "optimize_insn_for_size_p () && optimize_size > 1
    && operands[1] != const0_rtx
    && IN_RANGE (INTVAL (operands[1]), -128, 127)
-   && !ix86_red_zone_used"
+   && !ix86_red_zone_used
+   && REGNO (operands[0]) != SP_REG"
   [(set (match_dup 2) (match_dup 1))
    (set (match_dup 0) (match_dup 3))]
 {
diff --git a/gcc/testsuite/gcc.target/i386/pr106122.c b/gcc/testsuite/gcc.target/i386/pr106122.c
new file mode 100644
index 0000000..7d24ed3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr106122.c
@@ -0,0 +1,15 @@ 
+/* PR middle-end/106122 */
+/* { dg-do compile } */
+/* { dg-options "-Oz" } */
+
+register volatile int a __asm__("%esp");
+void foo (void *);
+void bar (void *);
+
+void
+baz (void)
+{
+  foo (__builtin_return_address (0));
+  a = 0;
+  bar (__builtin_return_address (0));
+}