public inbox for gcc-prs@sourceware.org help / color / mirror / Atom feed
From: Chris Torek <torek@elf.eng.bsdi.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, Subject: Re: optimization/7690: gcc 2.95.3: argument destroyed under -O2 on IA32 Date: Thu, 22 Aug 2002 18:06:00 -0000 [thread overview] Message-ID: <20020822235600.22890.qmail@sources.redhat.com> (raw) 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
next reply other threads:[~2002-08-22 23:56 UTC|newest] Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top 2002-08-22 18:06 Chris Torek [this message] -- strict thread matches above, loose matches on Subject: below -- 2003-03-12 18:47 neroden 2002-12-06 13:16 bangerth 2002-08-23 0:06 Chris Torek 2002-08-22 15:56 torek
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20020822235600.22890.qmail@sources.redhat.com \ --to=torek@elf.eng.bsdi.com \ --cc=gcc-prs@gcc.gnu.org \ --cc=nobody@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).