Incorrect code generation while passing address of char parameter

Shekhar Divekar shekhar@cradle.com
Tue Feb 20 12:40:00 GMT 2007


Hi,

I am working on GCC 3.3.1 port. The architecture mostly based
on RISC architecture.

Here is the problem.

After compiling following code
------------------------------
void g(char *a);

f(char c)
{
     g(&c);
}
-----------------------------

The in the generated RTL (file.c.00.rtl)
I see incorrect code generated for loading 'c.

Here is my analysis for code generation in function.c
Initially last byte from parm reg is picked using
ashift, ashiftrt.

----------------
(insn 4 0 5 0x0 (set (reg/v:SI 71)
         (ashift:SI (subreg:SI (reg:QI 72) 0)
             (const_int 24 [0x18]))) -1 (nil)
     (nil))

(insn 5 4 6 0x0 (set (reg/v:SI 71)
         (ashiftrt:SI (reg/v:SI 71)
             (const_int 24 [0x18]))) -1 (nil)
     (nil))
----------------

Later when 'c' is found addressable(TREE_ADDRESSABLE),
we try to 'put_var_into_stack'. As the decl_mode
and promoted_mode are different, we can't use addressof,
and 'put_reg_into_stack' is done. Here references to
var are replaced by a stack slot.

----------------
(insn 4 0 5 0x0 (set (mem/f:QI (plus:SI (reg/f:SI 66 virtual-stack-vars)
                 (const_int -1 [0xffffffff])) [0 S1 A8])
         (ashift:SI (subreg:SI (reg:QI 72) 0)
             (const_int 24 [0x18]))) -1 (nil)
     (nil))

(insn 5 4 6 0x0 (set (mem/f:QI (plus:SI (reg/f:SI 66 virtual-stack-vars)
                 (const_int -1 [0xffffffff])) [0 S1 A8])
         (ashiftrt:SI (mem/f:QI (plus:SI (reg/f:SI 66 virtual-stack-vars)
                     (const_int -1 [0xffffffff])) [0 S1 A8])
             (const_int 24 [0x18]))) -1 (nil)
     (nil))

(insn 6 5 0 0x0 (set (mem/f:QI (plus:SI (reg/f:SI 66 virtual-stack-vars)
                 (const_int -1 [0xffffffff])) [0 S1 A8])
         (mem/f:QI (plus:SI (reg/f:SI 66 virtual-stack-vars)
                 (const_int -1 [0xffffffff])) [0 S1 A8])) -1 (nil)
     (nil))
----------------

This requires 'schedule_fixup_var_refs'. So temps are introduced
along with save/restore from stack. At the time of restoring from
stack again conversion to QI is done, and code starts looking like

----------------
(insn 4 0 7 0x0 (set (reg:SI 73)
         (ashift:SI (subreg:SI (reg:QI 72) 0)
             (const_int 24 [0x18]))) -1 (nil)
     (nil))

(insn 7 4 9 0x0 (set (mem/f:QI (plus:SI (reg/f:SI 66 virtual-stack-vars)
                 (const_int -1 [0xffffffff])) [0 S1 A8])
         (subreg:QI (reg:SI 73) 0)) -1 (nil)
     (nil))

(insn 9 7 10 0x0 (set (reg:QI 76)
         (mem/f:QI (plus:SI (reg/f:SI 66 virtual-stack-vars)
                 (const_int -1 [0xffffffff])) [0 S1 A8])) -1 (nil)
     (nil))

(insn 10 9 11 0x0 (set (reg:SI 75)
         (ashift:SI (subreg:SI (reg:QI 76) 0)
             (const_int 24 [0x18]))) -1 (nil)
     (nil))

(insn 11 10 5 0x0 (set (reg:SI 75)
         (ashiftrt:SI (reg:SI 75)
             (const_int 24 [0x18]))) -1 (nil)
     (nil))

(insn 5 11 8 0x0 (set (reg:SI 74)
         (ashiftrt:SI (reg:SI 75)
             (const_int 24 [0x18]))) -1 (nil)
     (nil))

(insn 8 5 13 0x0 (set (mem/f:QI (plus:SI (reg/f:SI 66 virtual-stack-vars)
                 (const_int -1 [0xffffffff])) [0 S1 A8])
         (subreg:QI (reg:SI 74) 0)) -1 (nil)
     (nil))
----------------

If you see insn 11 & 5, It has effective ashiftrt of > 32, and hence
combine removes all the conversion & hence incorrect code is generated.

I tried looking at latest 3.3.x & 3.4.x, I found the code in function.c
looks relatively undisturbed. This makes me think that there might be
something in "machine description"

Can someone provide any help/pointers?

~s




More information about the Gcc mailing list