This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
IF conversion bug with CC0
- From: Dan <dgisselq at verizon dot net>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 04 Apr 2016 16:19:10 -0400
- Subject: IF conversion bug with CC0
- Authentication-results: sourceware.org; auth=none
- Reply-to: dgisselq at ieee dot org
Greetings!
GCC is usually so perfect, that I hate to write, but ... I think I'm
chasing down quite the bug in it and would appreciate some thought to
the following.
The code that causes the bug looks like:
if (ptr) {
*ptr = 1;
}
This code evaluates, in the instruction set I am working with, into the
following RTL:
(set (cc0) (compare (reg 3) (reg 1)))
(set (pc) (if-then-else (eq (cc0) (const_int 0)) (label_ref 258) (pc)))
(set (mem (reg 3)) (reg 1))
(all modes are SI)
This would be all fine and dandy, up until the if_convert modifications.
if_convert() rightly decides that the store instruction is prime for a
conditional execution conversion. Therefore, if_convert() transforms
this code into:
(cond_exec (ne (cc0) (const_int 0)) (set (mem (reg 3)) (reg 1)))
This, by itself, is a valid conversion.
The problem is that when cond_exec_process_if_block calls
merge_if_block(ce_info) to package up the changes and make them
permanent, merge_if_block then calls merge_block which deletes not only
the conditional jump statement (set (pc) ... etc.), but also the compare
that set the conditions prior to the jump statement (see
rtl_merge_blocks within cfgrtl.c). Hence instead of the working RTL,
(set (cc0) (compare (reg 3) (reg 1)))
(cond_exec (ne (cc0) (const_int 0)) (set (mem (reg 3)) (reg 1)))
I'm left with the broken RTL:
(cond_exec (ne (cc0) (const_int 0)) (set (mem (reg 3)) (reg 1)))
Can someone tell me if I am missing something, or whether this really is
a bug in GCC?
Thanks!
Dan