diff options
author | Jan Hubicka <jh@suse.cz> | 2005-11-03 00:21:22 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2005-11-02 23:21:22 +0000 |
commit | fb530c72edd80bfdb02dd3a2f17e8df61b097859 (patch) | |
tree | 7f731b36993fc10c20e0e13a28c632c571fde33b /gcc | |
parent | d98ad4101fa724d2d7f7364405f31fd3e8090371 (diff) | |
download | gcc-fb530c72edd80bfdb02dd3a2f17e8df61b097859.zip gcc-fb530c72edd80bfdb02dd3a2f17e8df61b097859.tar.gz gcc-fb530c72edd80bfdb02dd3a2f17e8df61b097859.tar.bz2 |
re PR target/23303 (4.1 generates sall + addl instead of leal)
PR target/23303
* i386.md: Add peep2 for simplyfing array accesses.
* gcc.dg/i386-lea.c: New test
From-SVN: r106406
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 58 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/i386-lea.c | 14 |
4 files changed, 82 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5965473..afca62b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2005-11-02 Jan Hubicka <jh@suse.cz> + + PR target/23303 + * i386.md: Add peep2 for simplyfing array accesses. + 2005-11-02 Ulrich Weigand <uweigand@de.ibm.com> PR target/24615 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 3e417b5..19d874b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -19785,6 +19785,64 @@ if (!rtx_equal_p (operands[0], operands[1])) emit_move_insn (operands[0], operands[1]); }) + +;; After splitting up read-modify operations, array accesses with memory +;; operands might end up in form: +;; sall $2, %eax +;; movl 4(%esp), %edx +;; addl %edx, %eax +;; instead of pre-splitting: +;; sall $2, %eax +;; addl 4(%esp), %eax +;; Turn it into: +;; movl 4(%esp), %edx +;; leal (%edx,%eax,4), %eax + +(define_peephole2 + [(parallel [(set (match_operand 0 "register_operand" "") + (ashift (match_operand 1 "register_operand" "") + (match_operand 2 "const_int_operand" ""))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_operand 3 "register_operand") + (match_operand 4 "x86_64_general_operand" "")) + (parallel [(set (match_operand 5 "register_operand" "") + (plus (match_operand 6 "register_operand" "") + (match_operand 7 "register_operand" ""))) + (clobber (reg:CC FLAGS_REG))])] + "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3 + /* Validate MODE for lea. */ + && ((!TARGET_PARTIAL_REG_STALL + && (GET_MODE (operands[0]) == QImode + || GET_MODE (operands[0]) == HImode)) + || GET_MODE (operands[0]) == SImode + || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) + /* We reorder load and the shift. */ + && !rtx_equal_p (operands[1], operands[3]) + && !reg_overlap_mentioned_p (operands[0], operands[4]) + /* Last PLUS must consist of operand 0 and 3. */ + && !rtx_equal_p (operands[0], operands[3]) + && (rtx_equal_p (operands[3], operands[6]) + || rtx_equal_p (operands[3], operands[7])) + && (rtx_equal_p (operands[0], operands[6]) + || rtx_equal_p (operands[0], operands[7])) + /* The intermediate operand 0 must die or be same as output. */ + && (rtx_equal_p (operands[0], operands[5]) + || peep2_reg_dead_p (3, operands[0]))" + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 0) (match_dup 1))] +{ + enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode; + int scale = 1 << INTVAL (operands[2]); + rtx index = gen_lowpart (Pmode, operands[1]); + rtx base = gen_lowpart (Pmode, operands[3]); + rtx dest = gen_lowpart (mode, operands[5]); + + operands[1] = gen_rtx_PLUS (Pmode, base, + gen_rtx_MULT (Pmode, index, GEN_INT (scale))); + if (mode != Pmode) + operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); + operands[0] = dest; +}) ;; Call-value patterns last so that the wildcard operand does not ;; disrupt insn-recog's switch tables. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5fee48f..058fcb3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-11-02 Jan Hubicka <jh@suse.cz> + + PR target/23303 + * gcc.dg/i386-lea.c: New test + 2005-11-02 Ulrich Weigand <uweigand@de.ibm.com> PR target/24615 diff --git a/gcc/testsuite/gcc.dg/i386-lea.c b/gcc/testsuite/gcc.dg/i386-lea.c new file mode 100644 index 0000000..61d9955 --- /dev/null +++ b/gcc/testsuite/gcc.dg/i386-lea.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-O2 -march=i686" } */ +/* { dg-final { scan-assembler "leal" } } */ +typedef struct { + char **visbuf; + char **allbuf; +} TScreen; + +void +VTallocbuf(TScreen *screen, unsigned long savelines) +{ + screen->visbuf = &screen->allbuf[savelines]; +} |