public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32
@ 2002-12-06 13:16 bangerth
0 siblings, 0 replies; 5+ messages in thread
From: bangerth @ 2002-12-06 13:16 UTC (permalink / raw)
To: gcc-bugs, gcc-prs, nobody, torek
Synopsis: gcc 2.95.3: argument destroyed under -O2 on IA32
State-Changed-From-To: open->feedback
State-Changed-By: bangerth
State-Changed-When: Fri Dec 6 13:16:07 2002
State-Changed-Why:
gcc2.95 is a rather old release and is no longer maintained
Could you possibly check, whether the same problem happens
with newer versions of gcc? I tried to play a little with
your testcase, but was not able to reproduce it.
Thanks
Wolfgang
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=7690
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32
@ 2003-03-12 18:47 neroden
0 siblings, 0 replies; 5+ messages in thread
From: neroden @ 2003-03-12 18:47 UTC (permalink / raw)
To: gcc-bugs, gcc-prs, nobody, torek
Synopsis: gcc 2.95.3: argument destroyed under -O2 on IA32
State-Changed-From-To: feedback->closed
State-Changed-By: neroden
State-Changed-When: Wed Mar 12 18:47:07 2003
State-Changed-Why:
Unreproducible, no feedback 3 mo.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=7690
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32
@ 2002-08-23 0:06 Chris Torek
0 siblings, 0 replies; 5+ messages in thread
From: Chris Torek @ 2002-08-23 0:06 UTC (permalink / raw)
To: nobody; +Cc: gcc-prs
The following reply was made to PR optimization/7690; it has been noted by GNATS.
From: Chris Torek <torek@bsdi.com>
To: gcc-gnats@gcc.gnu.org
Cc: torek@bsdi.com
Subject: Re: optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32
Date: Thu, 22 Aug 2002 19:04:27 -0600
Followup: the following patch appears to fix the problem.
(The patch is certainly safe, but might not be the right
way to go about this. Someone who understands the intent
of the code, and whether reg/v really means what I suggest,
and so on, should decide such things.)
Chris
Index: regmove.c
===================================================================
RCS file: /master/usr.bin/egcs/D/gcc/regmove.c,v
retrieving revision 1.1.1.2
diff -c -2 -r1.1.1.2 regmove.c
*** regmove.c 1999/12/09 18:08:07 1.1.1.2
--- regmove.c 2002/08/23 00:12:50
***************
*** 702,705 ****
--- 702,712 ----
return;
+ /* torek: if the insn at "set" sets a "volatile" pseudo-reg, that means
+ it is the name of a variable in the source; if we change its size
+ here, later passes may think it really is that large and wipe out
+ adjacent variables. */
+ if (MEM_VOLATILE_P (SET_DEST (set)))
+ return;
+
/* Do not use a SUBREG to truncate from one mode to another if truncation
is not a nop. */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32
@ 2002-08-22 18:06 Chris Torek
0 siblings, 0 replies; 5+ messages in thread
From: Chris Torek @ 2002-08-22 18:06 UTC (permalink / raw)
To: nobody; +Cc: gcc-prs
The following reply was made to PR optimization/7690; it has been noted by GNATS.
From: Chris Torek <torek@elf.eng.bsdi.com>
To: gcc-gnats@gcc.gnu.org, torek@bsdi.com
Cc:
Subject: Re: optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32
Date: Thu, 22 Aug 2002 17:54:31 -0600 (MDT)
Various addenda/notes... (does mailing a reply even work?)
By brutally whacking on the source code, I discovered that the
culprit can be stopped in regmove.c. Forcing that to pretend that
-fexpensive-optimizations is off generates correct assembly. I do
not know whether the ultimate problem is in this file or elsewhere,
however. (So, let's take a look at the RTL...)
With "#define flag_expensive_optimizations 0" and -dN, the
regmove dump file reads:
;; Function bug
(note 2 0 70 "" NOTE_INSN_DELETED)
;; Start of basic block 0, registers live: 6 [bp] 7 [sp] 16 []
(note 70 2 4 [bb 0] NOTE_INSN_BASIC_BLOCK)
(insn 4 70 6 (set (reg/v:SI 22)
(mem/f:SI (reg:SI 16 %argp) 0)) 48 {movsi+2} (nil)
(expr_list:REG_EQUIV (mem/f:SI (reg:SI 16 %argp) 0)
(nil)))
(insn 6 4 8 (set (reg/v:SI 23)
(mem/f:SI (plus:SI (reg:SI 16 %argp)
(const_int 4 [0x4])) 0)) 48 {movsi+2} (nil)
(expr_list:REG_EQUIV (mem/f:SI (plus:SI (reg:SI 16 %argp)
(const_int 4 [0x4])) 0)
(nil)))
(note 8 6 10 "" NOTE_INSN_DELETED)
(note 10 8 30 "" NOTE_INSN_DELETED)
(insn 30 10 11 (set (reg/v:SI 27)
(mem/f:SI (plus:SI (reg:SI 16 %argp)
(const_int 12 [0xc])) 0)) 48 {movsi+2} (nil)
(nil))
(note 11 30 12 "" NOTE_INSN_FUNCTION_BEG)
(note 12 11 14 "" NOTE_INSN_DELETED)
(note 14 12 17 0 NOTE_INSN_BLOCK_BEG)
(insn 17 14 19 (set (reg:SI 7 %esp)
(plus:SI (reg:SI 7 %esp)
(const_int -4 [0xfffffffc]))) 205 {addsi3+1} (nil)
(nil))
(insn 19 17 21 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)) 0)
(mem/f:SI (plus:SI (reg:SI 16 %argp)
(const_int 8 [0x8])) 0)) 45 {movsi-1} (nil)
(nil))
(insn 21 19 23 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)) 0)
(reg/v:SI 23)) 44 {movsi-2} (insn_list 6 (nil))
(nil))
(insn 23 21 25 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)) 0)
(reg/v:SI 22)) 44 {movsi-2} (insn_list 4 (nil))
(nil))
(call_insn 25 23 27 (set (reg:DI 0 %eax)
(call (mem:QI (symbol_ref:SI ("f1")) 0)
(const_int 16 [0x10]))) -1 (nil)
(nil)
(nil))
(insn 27 25 33 (set (reg/v:DI 26)
(reg:DI 0 %eax)) 79 {movdi+1} (insn_list 25 (nil))
(expr_list:REG_DEAD (reg:DI 0 %eax)
(nil)))
(insn 33 27 35 (set (reg:SI 29)
(subreg:SI (reg/v:DI 26) 0)) 48 {movsi+2} (insn_list 27 (nil))
(nil))
(note 35 33 36 "" NOTE_INSN_DELETED)
(insn 36 35 41 (set (mem/f:SI (plus:SI (reg/v:SI 22)
(reg:SI 29)) 0)
(reg/v:SI 27)) 48 {movsi+2} (insn_list 30 (insn_list 33 (nil)))
(expr_list:REG_DEAD (reg/v:SI 27)
(expr_list:REG_DEAD (reg:SI 29)
(expr_list:REG_DEAD (reg/v:SI 22)
(nil)))))
(insn 41 36 43 (set (reg:SI 7 %esp)
(plus:SI (reg:SI 7 %esp)
(const_int -12 [0xfffffff4]))) 205 {addsi3+1} (nil)
(nil))
(insn 43 41 44 (set (reg:SI 32)
(const_int 0 [0x0])) 48 {movsi+2} (nil)
(expr_list:REG_EQUAL (const_int 0 [0x0])
(nil)))
(insn 44 43 46 (set (reg:DI 33)
(zero_extend:DI (reg/v:SI 23))) 98 {zero_extendsidi2} (nil)
(expr_list:REG_DEAD (reg/v:SI 23)
(nil)))
(insn 46 44 47 (set (reg:SI 7 %esp)
(plus:SI (reg:SI 7 %esp)
(const_int 16 [0x10]))) 205 {addsi3+1} (nil)
(nil))
(insn:QI 47 46 48 (set (cc0)
(compare (subreg:SI (reg/v:DI 26) 1)
(subreg:SI (reg:DI 33) 1))) 12 {cmpsi_1} (insn_list 44 (nil))
(nil))
(jump_insn 48 47 71 (set (pc)
(if_then_else (gtu (cc0)
(const_int 0 [0x0]))
(label_ref 60)
(pc))) 349 {bleu+1} (nil)
(nil))
;; End of basic block 0
;; Start of basic block 1, registers live: 6 [bp] 7 [sp] 26 32 33
(note 71 48 49 [bb 1] NOTE_INSN_BASIC_BLOCK)
(insn:QI 49 71 50 (set (cc0)
(compare (subreg:SI (reg/v:DI 26) 1)
(subreg:SI (reg:DI 33) 1))) 12 {cmpsi_1} (nil)
(nil))
(jump_insn 50 49 72 (set (pc)
(if_then_else (ne (cc0)
(const_int 0 [0x0]))
(label_ref 57)
(pc))) 349 {bleu+1} (nil)
(nil))
;; End of basic block 1
;; Start of basic block 2, registers live: 6 [bp] 7 [sp] 26 32 33
(note 72 50 51 [bb 2] NOTE_INSN_BASIC_BLOCK)
(insn:QI 51 72 52 (set (cc0)
(compare (subreg:SI (reg/v:DI 26) 0)
(subreg:SI (reg:DI 33) 0))) 12 {cmpsi_1} (nil)
(expr_list:REG_DEAD (reg/v:DI 26)
(expr_list:REG_DEAD (reg:DI 33)
(nil))))
(jump_insn 52 51 57 (set (pc)
(if_then_else (gtu (cc0)
(const_int 0 [0x0]))
(label_ref 60)
(pc))) 349 {bleu+1} (nil)
(nil))
;; End of basic block 2
;; Start of basic block 3, registers live: 6 [bp] 7 [sp]
(code_label 57 52 73 4 "" [num uses: 1])
(note 73 57 59 [bb 3] NOTE_INSN_BASIC_BLOCK)
(insn 59 73 60 (set (reg:SI 32)
(const_int 1 [0x1])) 48 {movsi+2} (nil)
(expr_list:REG_EQUAL (const_int 1 [0x1])
(nil)))
;; End of basic block 3
;; Start of basic block 4, registers live: 6 [bp] 7 [sp] 32
(code_label 60 59 74 3 "" [num uses: 2])
(note 74 60 62 [bb 4] NOTE_INSN_BASIC_BLOCK)
(insn 62 74 64 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)) 0)
(reg:SI 32)) 44 {movsi-2} (nil)
(expr_list:REG_DEAD (reg:SI 32)
(nil)))
(call_insn 64 62 66 (call (mem:QI (symbol_ref:SI ("f2")) 0)
(const_int 16 [0x10])) -1 (nil)
(nil)
(nil))
;; End of basic block 4
(note 66 64 0 0 NOTE_INSN_BLOCK_END)
Without this clumsy #define, so that the parameter at 16(%ebp) does
get clobbered, the regmove dump file reads instead (diffs marked by
hand):
;; Function bug
+ Starting forward pass...
(note 2 0 70 "" NOTE_INSN_DELETED)
;; Start of basic block 0, registers live: 6 [bp] 7 [sp] 16 []
(note 70 2 4 [bb 0] NOTE_INSN_BASIC_BLOCK)
(insn 4 70 6 (set (reg/v:SI 22)
(mem/f:SI (reg:SI 16 %argp) 0)) 48 {movsi+2} (nil)
(expr_list:REG_EQUIV (mem/f:SI (reg:SI 16 %argp) 0)
(nil)))
! (insn 6 4 8 (set (reg/v:DI 23)
! (zero_extend:DI (mem/f:SI (plus:SI (reg:SI 16 %argp)
! (const_int 4 [0x4])) 0))) 98 {zero_extendsidi2} (nil)
(expr_list:REG_EQUIV (mem/f:SI (plus:SI (reg:SI 16 %argp)
(const_int 4 [0x4])) 0)
(nil)))
(note 8 6 10 "" NOTE_INSN_DELETED)
(note 10 8 30 "" NOTE_INSN_DELETED)
(insn 30 10 11 (set (reg/v:SI 27)
(mem/f:SI (plus:SI (reg:SI 16 %argp)
(const_int 12 [0xc])) 0)) 48 {movsi+2} (nil)
(nil))
(note 11 30 12 "" NOTE_INSN_FUNCTION_BEG)
(note 12 11 14 "" NOTE_INSN_DELETED)
(note 14 12 17 0 NOTE_INSN_BLOCK_BEG)
(insn 17 14 19 (set (reg:SI 7 %esp)
(plus:SI (reg:SI 7 %esp)
(const_int -4 [0xfffffffc]))) 205 {addsi3+1} (nil)
(nil))
(insn 19 17 21 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)) 0)
(mem/f:SI (plus:SI (reg:SI 16 %argp)
(const_int 8 [0x8])) 0)) 45 {movsi-1} (nil)
(nil))
(insn 21 19 23 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)) 0)
! (subreg:SI (reg/v:DI 23) 0)) 44 {movsi-2} (insn_list 6 (nil))
(nil))
(insn 23 21 25 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)) 0)
(reg/v:SI 22)) 44 {movsi-2} (insn_list 4 (nil))
(nil))
(call_insn 25 23 27 (set (reg:DI 0 %eax)
(call (mem:QI (symbol_ref:SI ("f1")) 0)
(const_int 16 [0x10]))) -1 (nil)
(nil)
(nil))
(insn 27 25 33 (set (reg/v:DI 26)
(reg:DI 0 %eax)) 79 {movdi+1} (insn_list 25 (nil))
(expr_list:REG_DEAD (reg:DI 0 %eax)
(nil)))
(insn 33 27 35 (set (reg:SI 29)
(subreg:SI (reg/v:DI 26) 0)) 48 {movsi+2} (insn_list 27 (nil))
(nil))
(note 35 33 36 "" NOTE_INSN_DELETED)
(insn 36 35 41 (set (mem/f:SI (plus:SI (reg/v:SI 22)
(reg:SI 29)) 0)
(reg/v:SI 27)) 48 {movsi+2} (insn_list 30 (insn_list 33 (nil)))
(expr_list:REG_DEAD (reg/v:SI 27)
(expr_list:REG_DEAD (reg:SI 29)
(expr_list:REG_DEAD (reg/v:SI 22)
(nil)))))
(insn 41 36 43 (set (reg:SI 7 %esp)
(plus:SI (reg:SI 7 %esp)
(const_int -12 [0xfffffff4]))) 205 {addsi3+1} (nil)
(nil))
(insn 43 41 44 (set (reg:SI 32)
(const_int 0 [0x0])) 48 {movsi+2} (nil)
(expr_list:REG_EQUAL (const_int 0 [0x0])
(nil)))
(insn 44 43 46 (set (reg:DI 33)
! (reg/v:DI 23)) 79 {movdi+1} (nil)
! (expr_list:REG_DEAD (reg/v:DI 23)
(nil)))
(insn 46 44 47 (set (reg:SI 7 %esp)
(plus:SI (reg:SI 7 %esp)
(const_int 16 [0x10]))) 205 {addsi3+1} (nil)
(nil))
(insn:QI 47 46 48 (set (cc0)
(compare (subreg:SI (reg/v:DI 26) 1)
(subreg:SI (reg:DI 33) 1))) 12 {cmpsi_1} (insn_list 44 (nil))
(nil))
(jump_insn 48 47 71 (set (pc)
(if_then_else (gtu (cc0)
(const_int 0 [0x0]))
(label_ref 60)
(pc))) 349 {bleu+1} (nil)
(nil))
;; End of basic block 0
;; Start of basic block 1, registers live: 6 [bp] 7 [sp] 26 32 33
(note 71 48 49 [bb 1] NOTE_INSN_BASIC_BLOCK)
(insn:QI 49 71 50 (set (cc0)
(compare (subreg:SI (reg/v:DI 26) 1)
(subreg:SI (reg:DI 33) 1))) 12 {cmpsi_1} (nil)
(nil))
(jump_insn 50 49 72 (set (pc)
(if_then_else (ne (cc0)
(const_int 0 [0x0]))
(label_ref 57)
(pc))) 349 {bleu+1} (nil)
(nil))
;; End of basic block 1
;; Start of basic block 2, registers live: 6 [bp] 7 [sp] 26 32 33
(note 72 50 51 [bb 2] NOTE_INSN_BASIC_BLOCK)
(insn:QI 51 72 52 (set (cc0)
(compare (subreg:SI (reg/v:DI 26) 0)
(subreg:SI (reg:DI 33) 0))) 12 {cmpsi_1} (nil)
(expr_list:REG_DEAD (reg/v:DI 26)
(expr_list:REG_DEAD (reg:DI 33)
(nil))))
(jump_insn 52 51 57 (set (pc)
(if_then_else (gtu (cc0)
(const_int 0 [0x0]))
(label_ref 60)
(pc))) 349 {bleu+1} (nil)
(nil))
;; End of basic block 2
;; Start of basic block 3, registers live: 6 [bp] 7 [sp]
(code_label 57 52 73 4 "" [num uses: 1])
(note 73 57 59 [bb 3] NOTE_INSN_BASIC_BLOCK)
(insn 59 73 60 (set (reg:SI 32)
(const_int 1 [0x1])) 48 {movsi+2} (nil)
(expr_list:REG_EQUAL (const_int 1 [0x1])
(nil)))
;; End of basic block 3
;; Start of basic block 4, registers live: 6 [bp] 7 [sp] 32
(code_label 60 59 74 3 "" [num uses: 2])
(note 74 60 62 [bb 4] NOTE_INSN_BASIC_BLOCK)
(insn 62 74 64 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)) 0)
(reg:SI 32)) 44 {movsi-2} (nil)
(expr_list:REG_DEAD (reg:SI 32)
(nil)))
(call_insn 64 62 66 (call (mem:QI (symbol_ref:SI ("f2")) 0)
(const_int 16 [0x10])) -1 (nil)
(nil)
(nil))
;; End of basic block 4
(note 66 64 0 0 NOTE_INSN_BLOCK_END)
The RTL changes at the front actually look OK: we
just replace reg/v:SI 23 with reg/v:DI 23, making pseudo 23 a
double-wide and marking its top half as zero-extended. Of course,
"reg/v 23" just holds the 2nd parameter to bug() (C name "sz"):
void bug(char *buf, size_t sz, const char *name, unsigned type)
{
off_t off;
off = f1(buf, sz, name);
memcpy(buf + off, &type, sizeof(type));
f2(off <= sz);
}
so the point is presumably to zero-extend "sz" in advance of the
call f2(off <= sz), to make the compare easier.
This of course requires the change at insn 21, to add a subreg to
push only the lower 32 bits of "sz" in the call to f1(). The rest
of the call still looks OK.
The last change at insn 44 looks OK too, we just move a DI instead
of zero-extending an SI, then mark DI 23 (previously known as SI
23) dead. This rather implies the problem is elsewhere (what a
surprise...).
note to self: dump files that differ:
flow2
greg
jump2
lreg
regmove
stack
another note to self: hard regs
0 = eax
1 = edx
2 = ecx
3 = ebx
4 = esi
5 = edi
6 = ebp
7 = esp
Conclusion-jumping, to be verified later: in .greg, we see the code
that has gone wrong: the widening of parameter "sz" has been
programmed to occur via %eax+%edx; %eax is loaded, %edx is cleared;
then reg:DI %eax is STORED BACK INTO MEMORY because we ASSUME that
there is nothing after "sz" to be preserved, when in fact there is
still the un-preserved value of "name" up there. (So the problem
is that C-code-variable registers should not be widened, ever, lest
they be pushed back into memory? Prohibiting that in regmove.c
might solve the problem...)
Chris
^ permalink raw reply [flat|nested] 5+ messages in thread
* optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32
@ 2002-08-22 15:56 torek
0 siblings, 0 replies; 5+ messages in thread
From: torek @ 2002-08-22 15:56 UTC (permalink / raw)
To: gcc-gnats
>Number: 7690
>Category: optimization
>Synopsis: gcc 2.95.3: argument destroyed under -O2 on IA32
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Aug 22 15:06:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: torek@bsdi.com
>Release: gcc 2.95.3
>Organization:
>Environment:
BSD/OS 4.3
>Description:
The stripped-down C code below generates IA32 assembly that destroys the "name" parameter before making another call, but only when using -O2.
This code is simplified from a real program (squid) and no longer does anything useful on its own, so you must look at the generated assembly.
I was hoping this is a known bug with a known fix that I can find somewhere so as to patch it.
>How-To-Repeat:
typedef unsigned long long off_t;
typedef unsigned int size_t;
off_t f1(char *buf, size_t sz, const char *name);
void f2(int);
void bug(char *buf, size_t sz, const char *name, unsigned type)
{
off_t off;
off = f1(buf, sz, name);
memcpy(buf + off, &type, sizeof(type));
f2(off <= sz);
}
compile with -O2, examine assembly, note this section:
movl 8(%ebp),%edi
movl 12(%ebp),%eax
xorl %edx,%edx
movl %eax,12(%ebp)
movl %edx,16(%ebp)
note that 16(%ebp) used to hold the parameter "name" before this last movl, which (since %edx is now 0) clobbers it.
Using -O1 -fexpensive-optimizations appears to suffice to trigger the problem (but -O1 alone does not).
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2003-03-12 18:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-06 13:16 optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32 bangerth
-- strict thread matches above, loose matches on Subject: below --
2003-03-12 18:47 neroden
2002-08-23 0:06 Chris Torek
2002-08-22 18:06 Chris Torek
2002-08-22 15:56 torek
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).