ssa problem
Ulrich Drepper
drepper@redhat.com
Sun May 7 00:32:00 GMT 2000
The current mainline gcc has a problem with the conversion from SSA on
x86. When the code appended below is compiled with
gcc -O3 -fssa -march=i686 -o u u.c
the return value is 4 and not 3. The problem is that the increment
performed by the va_arg() use is moved before the memory access.
Here's the part of the dump after conversion to SSA:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(note 47 51 15 [bb 1] NOTE_INSN_BASIC_BLOCK)
(note 15 47 17 ("u.c") 9)
(insn 17 15 19 (set (reg:SI 29)
(reg:SI 31)) 41 {*movsi_1} (nil)
(nil))
(insn 19 17 21 (parallel[
(set (reg:SI 32)
(plus:SI (reg:SI 31)
(const_int 4 [0x4])))
(clobber (reg:CC 17 flags))
] ) 189 {*addsi_1} (nil)
(nil))
(insn 21 19 22 (set (reg/v:SI 28)
(mem:SI (reg:SI 29) 3)) 41 {*movsi_1} (nil)
(nil))
(note 22 21 24 NOTE_INSN_LOOP_CONT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note the use of res:SI 29. Now after converting back from SSA:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(note 47 29 15 [bb 1] NOTE_INSN_BASIC_BLOCK)
(note 15 47 17 ("u.c") 9)
(insn 17 15 19 (set (reg:SI 31)
(reg:SI 31)) 41 {*movsi_1} (nil)
(nil))
(insn 19 17 21 (parallel[
(set (reg:SI 31)
(plus:SI (reg:SI 31)
(const_int 4 [0x4])))
(clobber (reg:CC 17 flags))
] ) 189 {*addsi_1} (nil)
(nil))
(insn 21 19 22 (set (reg/v:SI 28)
(mem:SI (reg:SI 31) 3)) 41 {*movsi_1} (nil)
(nil))
(note 22 21 24 NOTE_INSN_LOOP_CONT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The move in insn 17 is converted into a nop and insn 21 uses now
reg:SI 31 even though this register is modified in insn 19.
--
---------------. drepper at gnu.org ,-. 1325 Chesapeake Terrace
Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA
Red Hat `--' drepper at redhat.com `------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdarg.h>
int
bar (int a, va_list ap)
{
int b;
do
b = va_arg (ap, int);
while (b > 10);
return a + b;
}
int
foo (int a, ...)
{
va_list ap;
va_start (ap, a);
return bar (a, ap);
}
int
main ()
{
return foo (1, 2, 3);
}
More information about the Gcc-bugs
mailing list