Bug 25227 - struct whos size is > 64bit is always on the stack
Summary: struct whos size is > 64bit is always on the stack
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.2.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks: argument, return
  Show dependency treegraph
 
Reported: 2005-12-02 18:13 UTC by Benjamin LaHaise
Modified: 2024-06-19 10:49 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-12-02 18:26:38


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Benjamin LaHaise 2005-12-02 18:13:51 UTC
The following test program spills res onto the stack when the value res.result, which is already in a register, should be passed in a register to 
foo();

/* compile with: gcc -fomit-frame-pointer -S */
struct rw_res {
        long result;
        long pos_update;
};

struct file {
        long f_pos;
};

struct rw_res vfs_read(long pos);
long foo(long bar);

long sys_read(struct file *file)
{
        struct rw_res res;
        res = vfs_read(file->f_pos);
        return foo(res.result);
}
Comment 1 Andrew Pinski 2005-12-02 18:26:38 UTC
Confirmed,  Even though it is returned on the registers:
(call_insn 13 12 14 (set (parallel:BLK [
                (expr_list:REG_DEP_TRUE (reg:DI 0 ax)
                    (const_int 0 [0x0]))
                (expr_list:REG_DEP_TRUE (reg:DI 1 dx)
                    (const_int 8 [0x8]))
            ])
        (call (mem:QI (symbol_ref:DI ("vfs_read") [flags 0x41] <function_decl 0x2aaaab162e00 vfs_read>) [0 S1 A8])
            (const_int 0 [0x0]))) -1 (nil)
    (nil)
    (expr_list:REG_DEP_TRUE (use (reg:DI 5 di))
        (nil)))

we store the struct directly to the stack right after that:
(insn 16 15 17 (set (mem/s/c:DI (plus:DI (reg/f:DI 54 virtual-stack-vars)
                (const_int -32 [0xffffffffffffffe0])) [4 S8 A128])
        (reg:DI 61)) -1 (nil)
    (nil))

(insn 17 16 18 (set (mem/s/c:DI (plus:DI (reg/f:DI 54 virtual-stack-vars)
                (const_int -24 [0xffffffffffffffe8])) [4 S8 A64])
        (reg:DI 62)) -1 (nil)
    (nil))
and then we load it and store it again:
(insn 18 17 19 (set (reg:DI 63)
        (mem/s/c:DI (plus:DI (reg/f:DI 54 virtual-stack-vars)
                (const_int -32 [0xffffffffffffffe0])) [4 S8 A128])) -1 (nil)
    (nil))

(insn 19 18 20 (set (mem/s/c:DI (plus:DI (reg/f:DI 54 virtual-stack-vars)
                (const_int -16 [0xfffffffffffffff0])) [4 D.1642+0 S8 A64])
        (reg:DI 63)) -1 (nil)
    (nil))

(insn 20 19 21 (set (reg:DI 64)
        (mem/s/c:DI (plus:DI (reg/f:DI 54 virtual-stack-vars)
                (const_int -24 [0xffffffffffffffe8])) [4 S8 A64])) -1 (nil)
    (nil))

(insn 21 20 0 (set (mem/s/c:DI (plus:DI (reg/f:DI 54 virtual-stack-vars)
                (const_int -8 [0xfffffffffffffff8])) [4 D.1642+8 S8 A64])
        (reg:DI 64)) -1 (nil)
    (nil))


This is a mess.
Comment 2 Richard Biener 2005-12-02 21:33:15 UTC
It looks like not a single RTL optimizer triggering.  It's bad from expand on, and I guess having all mems around from the start is not making it easy.