This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Bug in if_convert



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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]