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.
---
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!