aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i386/i386.md42
-rw-r--r--gcc/testsuite/gcc.target/i386/lea-3.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/lea-4.c16
3 files changed, 59 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index df7135f..b5d8389 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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
diff --git a/gcc/testsuite/gcc.target/i386/lea-3.c b/gcc/testsuite/gcc.target/i386/lea-3.c
index 84e66b0..ce50531 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 0000000..7bb2cec
--- /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" } } */