This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/32285] New: [4.1 Regression] Miscompilation with pure _Complex returning call inside another fn's argument list
- From: "jakub at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 11 Jun 2007 15:37:35 -0000
- Subject: [Bug middle-end/32285] New: [4.1 Regression] Miscompilation with pure _Complex returning call inside another fn's argument list
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
extern void abort (void);
_Complex v = 3.0 + 1.0iF;
void
foo (_Complex z, int *x)
{
if (z != v)
abort ();
}
_Complex bar (_Complex z) __attribute__ ((pure));
_Complex
bar (_Complex z)
{
return v;
}
int
baz (void)
{
int a, i;
for (i = 0; i < 6; i++)
foo (bar (1.0iF * i), &a);
return 0;
}
int
main ()
{
baz ();
return 0;
}
is miscompiled at -O1 -m32 or -O2 -m32.
This was fixed in 4.2 and on the trunk with PR25505 changes (the tree-nrv.c
change most importantly), NRV in this case is really a wrong thing to do,
as target is _Complex at virtual-outgoing-regs, but those are also used
for the call. Furthermore GCC then incorrectly computes where the region
actually was:
(insn 26 25 27 2 (set (mem/i:DF (plus:SI (reg/f:SI 56 virtual-outgoing-args)
(const_int 4 [0x4])) [0 S8 A32])
(float_extend:DF (reg:SF 69))) -1 (nil)
(nil))
(insn 27 26 28 2 (set (mem/i:DF (plus:SI (reg/f:SI 56 virtual-outgoing-args)
(const_int 12 [0xc])) [0 S8 A32])
(reg:DF 68)) -1 (nil)
(nil))
(insn 28 27 29 2 (set (mem:SI (reg/f:SI 56 virtual-outgoing-args) [0 S4 A32])
(reg/f:SI 56 virtual-outgoing-args)) -1 (nil)
(nil))
(call_insn 29 28 30 2 (parallel [
(call (mem:QI (symbol_ref:SI ("bar") [flags 0x3] <function_decl
0x2aaaaea20400 bar>) [0 S1 A8])
(const_int 20 [0x14]))
(set (reg/f:SI 7 sp)
(plus:SI (reg/f:SI 7 sp)
(const_int 4 [0x4])))
]) -1 (nil)
(expr_list:REG_EH_REGION (const_int 0 [0x0])
(nil))
(nil))
(insn 30 29 31 2 (parallel [
(set (reg/f:SI 7 sp)
(plus:SI (reg/f:SI 7 sp)
(const_int -4 [0xfffffffffffffffc])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 31 30 32 2 (set (reg:DF 70)
(mem/c/i:DF (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -32 [0xffffffffffffffe0])) [2 S8 A64])) -1 (nil)
(nil))
(insn 32 31 33 2 (set (mem:DF (plus:SI (reg/f:SI 56 virtual-outgoing-args)
(const_int 4 [0x4])) [0 S8 A8])
(reg:DF 70)) -1 (nil)
(nil))
(insn 33 32 34 2 (set (reg:DF 71)
(mem/c/i:DF (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -24 [0xffffffffffffffe8])) [2 S8 A64])) -1 (nil)
(nil))
(insn 34 33 35 2 (set (mem:DF (plus:SI (reg/f:SI 56 virtual-outgoing-args)
(const_int 12 [0xc])) [0 S8 A8])
(reg:DF 71)) -1 (nil)
(nil))
So, it stores the return value to %esp (== %ebp - 68 at that point) and
loads from %ebp - 40.
--
Summary: [4.1 Regression] Miscompilation with pure _Complex
returning call inside another fn's argument list
Product: gcc
Version: 4.1.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: jakub at gcc dot gnu dot org
GCC target triplet: i686-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32285