This patch adds a multiply-and-add instruction expression to simple_rhs_p function. When debugging my sms patches, the following situation was found. Imagine a loop, with constant step > 1, where "n" and "fin" is unknown at compile time.
for (c = n * step + fin; c != fin; c -= step) ...; c is a pseudo-register and is initialized as one multiply-and-add rtl instruction before the loop. In this case, get_simple_loop_desc function gives a non-null infinite condition which looks like: (c - fin)%step == 0 It's obviously always true when you try to substitute the initialization expression. But no substitution is done, because the exression is not simple_rhs_p. So, this patch allows get_simple_loop_desc analysis to be more precise. How can this influence other optimizations? 2011-07-20 Roman Zhuykov <zhr...@ispras.ru> * loop-iv.c (simple_rhs_p): Support multiply-and-add operations. --- gcc/loop-iv.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 83d2501..dbb7728 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -1340,9 +1340,15 @@ simple_rhs_p (rtx rhs) case AND: op0 = XEXP (rhs, 0); op1 = XEXP (rhs, 1); - /* Allow reg OP const and reg OP reg. */ + /* Allow op0 to be reg or expression like "reg mult const". + * Allow op1 to be reg or const. */ if (!(REG_P (op0) && !HARD_REGISTER_P (op0)) - && !function_invariant_p (op0)) + && !function_invariant_p (op0) + && !(((GET_CODE (op0) == ASHIFT) + || (GET_CODE (op0) == ASHIFTRT) + || (GET_CODE (op0) == LSHIFTRT) + || (GET_CODE (op0) == MULT) + ) && simple_rhs_p (op0))) return false; if (!(REG_P (op1) && !HARD_REGISTER_P (op1)) && !function_invariant_p (op1)) -- Roman Zhuykov zhr...@ispras.ru