I am testing the following patch to fix PR69983 - SCEV was confused by a PRE inserted PHI node where it checks for equality of the evolution of all edges. After my SCEV fix these have conversions which are not handled by eq_evolutions_p.
I've noticed the function misses any type compatibility check and operand_equal_p on INTEGER_CSTs will ignore types. Also it will give up on SSA names or ADDR_EXPRs which can occur in both the evolution and init part of SCEVs. So simply fall back to operand_equal_p for all bits where we don't expect any further embeded CHRECs (operand_equal_p does no handle TREE_CHREC currently). Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2016-03-01 Richard Biener <rguent...@suse.de> PR tree-optimization/69983 * tree-chrec.c (eq_evolutions_p): Handle conversions, compare types and fall back to operand_equal_p. Index: gcc/tree-chrec.c =================================================================== *** gcc/tree-chrec.c (revision 233840) --- gcc/tree-chrec.c (working copy) *************** eq_evolutions_p (const_tree chrec0, cons *** 1468,1478 **** if (chrec0 == chrec1) return true; switch (TREE_CODE (chrec0)) { - case INTEGER_CST: - return operand_equal_p (chrec0, chrec1, 0); - case POLYNOMIAL_CHREC: return (CHREC_VARIABLE (chrec0) == CHREC_VARIABLE (chrec1) && eq_evolutions_p (CHREC_LEFT (chrec0), CHREC_LEFT (chrec1)) --- 1468,1478 ---- if (chrec0 == chrec1) return true; + if (! types_compatible_p (TREE_TYPE (chrec0), TREE_TYPE (chrec1))) + return false; + switch (TREE_CODE (chrec0)) { case POLYNOMIAL_CHREC: return (CHREC_VARIABLE (chrec0) == CHREC_VARIABLE (chrec1) && eq_evolutions_p (CHREC_LEFT (chrec0), CHREC_LEFT (chrec1)) *************** eq_evolutions_p (const_tree chrec0, cons *** 1487,1494 **** && eq_evolutions_p (TREE_OPERAND (chrec0, 1), TREE_OPERAND (chrec1, 1)); default: ! return false; } } --- 1487,1498 ---- && eq_evolutions_p (TREE_OPERAND (chrec0, 1), TREE_OPERAND (chrec1, 1)); + CASE_CONVERT: + return eq_evolutions_p (TREE_OPERAND (chrec0, 0), + TREE_OPERAND (chrec1, 0)); + default: ! return operand_equal_p (chrec0, chrec1, 0); } }