This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/23303] [4.1 Regression] 4.1 generates sall + addl instead of leal



------- Comment #5 from hubicka at ucw dot cz  2005-10-31 20:25 -------
Subject: Re:  [4.1 Regression] 4.1 generates sall + addl instead of leal

> 
> 
> ------- Comment #4 from mmitchel at gcc dot gnu dot org  2005-10-31 04:45 -------
> Jan, what's your analysis on this PR?
Hmm,
I am still not sure if it matters too much, but since there are actually
dupes of this problem, I think we can simply add peep2 fixing this
particular common case.

I am testing attached patch.


/* { dg-do assemble { 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];
}
2005-10-31  Jan Hubicka  <jh@suse.cz>
        PR target/23303
        * i386.md: Add peep2 for simplyfing array accesses.
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 106275)
+++ config/i386/i386.md (working copy)
@@ -19785,6 +19785,58 @@
   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])
+ /* 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))]
+{
+  int scale = 1 << INTVAL (operands[2]);
+  rtx index = gen_lowpart (Pmode, operands[1]);
+  rtx base = gen_lowpart (Pmode, operands[3]);
+  rtx dest = gen_lowpart (Pmode, operands[5]);
+
+  operands[1] = gen_rtx_PLUS (Pmode, base, gen_rtx_MULT (Pmode, index, GEN_INT
(scale)));
+  operands[0] = dest;
+})

 ;; Call-value patterns last so that the wildcard operand does not
 ;; disrupt insn-recog's switch tables.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23303


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]