aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2005-11-03 00:21:22 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2005-11-02 23:21:22 +0000
commitfb530c72edd80bfdb02dd3a2f17e8df61b097859 (patch)
tree7f731b36993fc10c20e0e13a28c632c571fde33b /gcc
parentd98ad4101fa724d2d7f7364405f31fd3e8090371 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/config/i386/i386.md58
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/i386-lea.c14
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];
+}