This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Bug in if_convert
- To: rth at cygnus dot com, gcc-bugs at gcc dot gnu dot org
- Subject: Bug in if_convert
- From: Richard Earnshaw <rearnsha at arm dot com>
- Date: Wed, 03 May 2000 19:09:14 +0100
- cc: rearnsha at arm dot com
- Organization: ARM Ltd.
- Reply-To: rearnsha at arm dot com
Richard,
The ARM port is failing to build again. This time it is a transformation
by if_convert() that is putting a use before its set. Things then all
fall apart when checking the flow graph.
What we have (in summary) are the basic blocks
bb 1
(insn (set (reg:CC 24) (compare:CC (reg:SI 0) (reg:SI 1))))
(jump_insn (set (pc) (if_then_else
(ge (reg:CC 24) (const_int 0))
(label_ref 20)
(pc)))
bb 2
(insn (set (reg:SI 0) (const_int -1)))
(jump_insn (set (pc) (label_ref 27)))
bb 3
(code_label 20)
(insn (set (reg:SI 0) (gt:SI (reg:CC 24) (const_int 0))))
bb 4
(code_label 27)
...
That is, we have a simple if-then-else sequence with both arms setting x;
except that in this case the 'else' setter is a complex expression
involving the condition code register (this was generated by a previous
pass of if_convert, but cse has eliminated the comparison, since it was
identical to the earlier one). What happens next is that we try to
transform this into
bb3
compare
conditionally-bb2
but the compare is now after the use, so the flow checks will fail.
I'm not sure how to approach this from now on. There is no information
about the condition flags stored in if_info, so there seems to be no easy
way to check for this situation.
Test case (I'm sure we have something like this already in the test-suite,
but we never get that far into the build):
int foo (int a, int b)
{
if (a < b) return -1;
else if (a > b) return 1;
else return 0;
}
R.