mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
x86: improve lea peepholes
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. 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.
This commit is contained in:
committed by
Alexandre Oliva
parent
7a54d49061
commit
0ff1ea6a6a
@@ -6452,6 +6452,48 @@
|
||||
[(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
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-options "-O2 -fno-PIE" } */
|
||||
|
||||
int m;
|
||||
|
||||
|
||||
16
gcc/testsuite/gcc.target/i386/lea-4.c
Normal file
16
gcc/testsuite/gcc.target/i386/lea-4.c
Normal file
@@ -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" } } */
|
||||
Reference in New Issue
Block a user