On Wed, Dec 10, 2025 at 9:30 PM Alexandre Oliva <[email protected]> wrote:
>
>
> gcc.target/i386/lea-3.c fails on ia32 with PIE enabled by default.
> There are two reasons for that:
>
> - setting up the PIC register requires one addl instruction, and the
> testcase wants none
>
> - the expected lea-combining peephole doesn't get applied for two
> reasons:
>
> -- the second insn of the pair that could be turned into a single lea
> doesn't clobber CC, but the existing peephole2 requires an add with
> such a clobber
>
> -- the first and second insns set different regs, and the existing
> peephole2 requires them to be the same
>
> Add extra peephole2s for when the second insn doesn't clobber CC, and
> for when the first set reg is different, but it dies at the second
> insn.
>
> Adjust lea-3.c to run with -fno-PIE, and add lea-4.c with -fPIE.
>
> The last of the newly-added peephole2s, that enables lea-4.c to pass,
> also hits during an i686-linux-gnu bootstrap (without PIE enabled),
> while building shared libraries for the target. I haven't been able
> to exercise the other 2, but I haven't tried very hard, and I see no
> why they couldn't possibly hit, so I left them in.
>
> Regstrapped on x86_64-linux-gnu, also tested on i686-linux-gnu and with
> gcc-15. Ok to install?
>
>
> for gcc/ChangeLog
>
> * config/i386/i386.md (lea peephole2): Add 3 new variants.
>
> for gcc/testsuite/ChangeLog
>
> * gcc.target/i386/lea-3.c: Add -fno-PIE.
> * gcc.target/i386/lea-4.c: New, with -fPIE.
OK. There are probably more pairs involving insns w/ and w/o clobber,
but I guess the ones you add are the most relevant.
Thanks,
Uros.
> ---
> gcc/config/i386/i386.md | 42
> +++++++++++++++++++++++++++++++++
> gcc/testsuite/gcc.target/i386/lea-3.c | 2 +-
> gcc/testsuite/gcc.target/i386/lea-4.c | 16 +++++++++++++
> 3 files changed, 59 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/gcc.target/i386/lea-4.c
>
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index df7135f84d478..b5d838934251c 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -6452,6 +6452,48 @@ (define_peephole2
> [(set (match_dup 0) (plus:SWI48 (plus:SWI48 (match_dup 0)
> (match_dup 1))
> (match_dup 2)))])
> +
> +(define_peephole2
> + [(parallel [(set (match_operand:SWI48 0 "register_operand")
> + (plus:SWI48 (match_dup 0)
> + (match_operand 1 "register_operand")))
> + (clobber (reg:CC FLAGS_REG))])
> + (set (match_dup 0)
> + (plus:SWI48 (match_dup 0)
> + (match_operand 2 "x86_64_immediate_operand")))]
> + "!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun)"
> + [(set (match_dup 0) (plus:SWI48 (plus:SWI48 (match_dup 0)
> + (match_dup 1))
> + (match_dup 2)))])
> +
> +(define_peephole2
> + [(parallel [(set (match_operand:SWI48 0 "register_operand")
> + (plus:SWI48 (match_dup 0)
> + (match_operand 1 "register_operand")))
> + (clobber (reg:CC FLAGS_REG))])
> + (parallel [(set (match_operand:SWI48 3 "register_operand")
> + (plus:SWI48 (match_dup 0)
> + (match_operand 2 "x86_64_immediate_operand")))
> + (clobber (reg:CC FLAGS_REG))])]
> + "(!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
> + && peep2_reg_dead_p (2, operands[0])"
> + [(set (match_dup 3) (plus:SWI48 (plus:SWI48 (match_dup 0)
> + (match_dup 1))
> + (match_dup 2)))])
> +
> +(define_peephole2
> + [(parallel [(set (match_operand:SWI48 0 "register_operand")
> + (plus:SWI48 (match_dup 0)
> + (match_operand 1 "register_operand")))
> + (clobber (reg:CC FLAGS_REG))])
> + (set (match_operand:SWI48 3 "register_operand")
> + (plus:SWI48 (match_dup 0)
> + (match_operand 2 "x86_64_immediate_operand")))]
> + "(!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
> + && peep2_reg_dead_p (2, operands[0])"
> + [(set (match_dup 3) (plus:SWI48 (plus:SWI48 (match_dup 0)
> + (match_dup 1))
> + (match_dup 2)))])
>
> ;; Add instructions
>
> diff --git a/gcc/testsuite/gcc.target/i386/lea-3.c
> b/gcc/testsuite/gcc.target/i386/lea-3.c
> index 84e66b00fc25e..ce50531f93545 100644
> --- a/gcc/testsuite/gcc.target/i386/lea-3.c
> +++ b/gcc/testsuite/gcc.target/i386/lea-3.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2" } */
> +/* { dg-options "-O2 -fno-PIE" } */
>
> int m;
>
> diff --git a/gcc/testsuite/gcc.target/i386/lea-4.c
> b/gcc/testsuite/gcc.target/i386/lea-4.c
> new file mode 100644
> index 0000000000000..7bb2cec6d8538
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/lea-4.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fPIE" } */
> +/* Same as lea-3.c, but with -fPIE. On ia32, that requires setting up the
> PIC
> + register, which requires an addl instruction. */
> +
> +int m;
> +
> +int foo(int y)
> +{
> + return (m+y-1)/y;
> +}
> +
> +/* { dg-final { scan-assembler "leal" } } */
> +/* { dg-final { scan-assembler-not "addl" { target lp64 } } } */
> +/* { dg-final { scan-assembler-times "addl" 1 { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "subl" } } */
>
> --
> Alexandre Oliva, happy hacker https://blog.lx.oliva.nom.br/
> Free Software Activist FSFLA co-founder GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity.
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive!