public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/42574]  New: Address of global variable is calculated multiple times; CSE doesn't work properly
@ 2010-01-01 17:28 sliao at google dot com
  2010-01-01 20:16 ` [Bug middle-end/42574] " steven at gcc dot gnu dot org
                   ` (21 more replies)
  0 siblings, 22 replies; 23+ messages in thread
From: sliao at google dot com @ 2010-01-01 17:28 UTC (permalink / raw)
  To: gcc-bugs

The following code  (by Alex Vod.)

struct A {
 char a[400];
 float* c;
};
struct A glob;
void func();
void func1(float*);
int func2(float*, int*);
void func3(float*);

void test(int *p) {
 func1(glob.c);
 if (func2(glob.c, p)) {
   func();
 }
 func3(glob.c);
}

is compiled by gcc 4.2.1 to 56 bytes and 4.4.0 to 64 bytes. The problem is that
it calculates address glob.c *twice*, but there is no need to - it doesn't
change as glob is a global variable.
gcc 4.2.1 output:
       push    {r4, r5, r6, lr}
       ldr     r3, .L5
       ldr     r2, .L5+4
.LPIC0:
       add     r3, pc
       ldr     r5, [r3, r2]
       mov     r6, #200
       lsl     r6, r6, #1
       mov     r4, r0
       ldr     r0, [r5, r6]
       bl      func1
       ldr     r0, [r5, r6]
       mov     r1, r4
       bl      func2
       cmp     r0, #0
       beq     .L2
       bl      func
.L2:
       ldr     r0, [r5, r6]
       bl      func3
       @ sp needed for prologue
       pop     {r4, r5, r6, pc}

gcc 4.4.0 output:
       push    {r3, r4, r5, r6, r7, lr}
       ldr     r4, .L5
       ldr     r3, .L5+4
.LPIC0:
       add     r4, pc
       ldr     r6, [r4, r3]
       mov     r5, #200
       lsl     r5, r5, #1
       mov     r7, r0
       ldr     r0, [r6, r5]
       bl      func1
       ldr     r0, [r6, r5]
       mov     r1, r7
       bl      func2
       cmp     r0, #0
       beq     .L2
       bl      func
.L2:
       ldr     r3, .L5+4
       @ sp needed for prologue
       ldr     r2, [r4, r3]
       mov     r3, #200   // this is the calculation of glob.c address
       lsl     r3, r3, #1    // it is redundant, as r5 already contains #400
       ldr     r0, [r2, r3]
       bl      func3
       pop     {r3, r4, r5, r6, r7, pc}

I believe gcc 4.2.1 works correctly due to RTL CSE pass.
Before CSE:

;; Start of basic block 4, registers live: (nil)
(code_label 34 33 35 4 2 "" [1 uses])
(note 35 34 37 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
(insn 37 35 38 4 (set (reg:SI 113) // put attention to this insn
       (unspec:SI [
               (symbol_ref:SI ("glob") <var_decl 0xf7d5a000 glob>)
           ] 3)) 148 {pic_load_addr_thumb} (nil)
   (nil))
(insn 38 37 39 4 (set (reg/f:SI 112)   // put attention to this insn
       (mem/u/c:SI (plus:SI (reg:SI 103)
               (reg:SI 113)) [0 S4 A32])) 146 {*thumb_movsi_insn} (nil)
   (expr_list:REG_EQUAL (symbol_ref:SI ("glob") <var_decl 0xf7d5a000 glob>)
       (nil)))
(insn 39 38 40 4 (set (reg:SI 114)             // put attention to this insn
       (const_int 400 [0x190])) 146 {*thumb_movsi_insn} (nil)
   (nil))
(insn 40 39 41 4 (set (reg:SI 115 [ glob.c ])
       (mem/s/f/c:SI (plus:SI (reg/f:SI 112)
               (reg:SI 114)) [5 glob.c+0 S4 A32])) 146 {*thumb_movsi_insn}
(nil)
   (nil))
(insn 41 40 42 4 (set (reg:SI 0 r0 [ glob.c ])
       (reg:SI 115 [ glob.c ])) 146 {*thumb_movsi_insn} (nil)
   (nil))
(call_insn 42 41 43 4 (parallel [
           (call (mem:SI (symbol_ref:SI ("func3") [flags 0x41] <function_decl
0xf7d5c100 func3>) [0 S4 A32])
               (const_int 0 [0x0]))
           (use (const_int 0 [0x0]))
           (clobber (reg:SI 14 lr))
       ]) 231 {*call_insn} (nil)
   (nil)
   (expr_list:REG_DEP_TRUE (use (reg:SI 0 r0 [ glob.c ]))
       (nil)))
;; End of basic block 4, registers live:

after CSE:

;; Start of basic block 4, registers live: (nil)
(code_label 34 33 35 4 2 "" [1 uses])
(note 35 34 40 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
(insn 40 35 41 4 (set (reg:SI 115 [ glob.c ]) // all mentioned instructions
were removed
       (mem/s/f/c:SI (plus:SI (reg/f:SI 104)
               (reg:SI 106)) [5 glob.c+0 S4 A32])) 146 {*thumb_movsi_insn}
(nil)
   (nil))
(insn 41 40 42 4 (set (reg:SI 0 r0 [ glob.c ])
       (reg:SI 115 [ glob.c ])) 146 {*thumb_movsi_insn} (nil)
   (nil))
(call_insn 42 41 43 4 (parallel [
           (call (mem:SI (symbol_ref:SI ("func3") [flags 0x41] <function_decl
0xf7d5c100 func3>) [0 S
4 A32])
               (const_int 0 [0x0]))
           (use (const_int 0 [0x0]))
           (clobber (reg:SI 14 lr))
       ]) 231 {*call_insn} (nil)
   (nil)
   (expr_list:REG_DEP_TRUE (use (reg:SI 0 r0 [ glob.c ]))
       (nil)))
;; End of basic block 4, registers live:

For some reason, this CSE pass doesn't work in gcc 4.3.1 or gcc-4.4.0


-- 
           Summary: Address of global variable is calculated multiple times;
                    CSE doesn't work properly
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: sliao at google dot com
 GCC build triplet: i686-linux
  GCC host triplet: i686-linux
GCC target triplet: arm-eabi


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


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2010-07-27 21:11 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-01-01 17:28 [Bug middle-end/42574] New: Address of global variable is calculated multiple times; CSE doesn't work properly sliao at google dot com
2010-01-01 20:16 ` [Bug middle-end/42574] " steven at gcc dot gnu dot org
2010-01-01 20:35 ` [Bug middle-end/42574] [4.3/4.4/4.5 Regression] Address of global variable is calculated multiple times (missed CSE) steven at gcc dot gnu dot org
2010-01-01 20:36 ` rguenth at gcc dot gnu dot org
2010-01-01 20:39 ` rguenth at gcc dot gnu dot org
2010-01-01 20:44 ` steven at gcc dot gnu dot org
2010-01-01 21:00 ` steven at gcc dot gnu dot org
2010-01-02  0:12 ` steven at gcc dot gnu dot org
2010-01-02 14:08 ` steven at gcc dot gnu dot org
2010-01-02 14:08 ` steven at gcc dot gnu dot org
2010-01-02 14:10 ` steven at gcc dot gnu dot org
2010-01-02 16:17 ` rguenth at gcc dot gnu dot org
2010-02-08 12:15 ` steven at gcc dot gnu dot org
2010-04-14 20:50 ` [Bug middle-end/42574] [4.3/4.4/4.5/4.6 " steven at gcc dot gnu dot org
2010-05-22 18:34 ` rguenth at gcc dot gnu dot org
2010-06-08 15:24 ` mkuvyrkov at gcc dot gnu dot org
2010-07-27 19:35 ` mkuvyrkov at gcc dot gnu dot org
2010-07-27 19:38 ` mkuvyrkov at gcc dot gnu dot org
2010-07-27 19:42 ` mkuvyrkov at gcc dot gnu dot org
2010-07-27 19:45 ` mkuvyrkov at gcc dot gnu dot org
2010-07-27 19:48 ` mkuvyrkov at gcc dot gnu dot org
2010-07-27 21:07 ` mkuvyrkov at gcc dot gnu dot org
2010-07-27 21:11 ` mkuvyrkov at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).