The following is needed to allow building libada if the conversion simplifications go in. Currently IVOPTs replaces IV uses in arbitrary order which can result in intermediate code that still refers to IVs that are going to be removed. As it folds replacement statements via force_gimple_operand (which eventually folds all generated statements) the match-and-simplify process can still reach those IVs via SSA name definitions (that are eventually replaced later).
The IVOPTs machinery removing unused IVs certainly doesn't expect that to happen. One option is to remove that "DCE", another is to make sure we don't reach un-replaced USEs when processing other uses which is what the patch below tries by sorting the iv_use vector after dominators (and stmt uids). Bootstrap and regtest in progress on x86_64-unknown-linux-gnu. I hope we don't run into too many other similar cases... Thanks, Richard. 2014-08-26 Richard Biener <rguent...@suse.de> * tree-ssa-loop-ivopts.c (ivuse_cmp): New function. (rewrite_uses): Sort the vector of iv_uses after dominator order. Index: gcc/tree-ssa-loop-ivopts.c =================================================================== --- gcc/tree-ssa-loop-ivopts.c (revision 214500) +++ gcc/tree-ssa-loop-ivopts.c (working copy) @@ -6526,6 +6526,30 @@ rewrite_use (struct ivopts_data *data, s update_stmt (use->stmt); } +/* Compare routine for sorting the vector of iv_uses after dominance. */ + +static int +ivuse_cmp (const void *a, const void *b) +{ + const struct iv_use *usea = *((const struct iv_use * const *)a); + const struct iv_use *useb = *((const struct iv_use * const *)b); + basic_block bba = gimple_bb (usea->stmt); + basic_block bbb = gimple_bb (useb->stmt); + if (bba == bbb) + { + if (usea->stmt == useb->stmt) + return 0; + if (gimple_uid (usea->stmt) > gimple_uid (useb->stmt)) + return 1; + else + return -1; + } + else if (dominated_by_p (CDI_DOMINATORS, bba, bbb)) + return 1; + else + return -1; +} + /* Rewrite the uses using the selected induction variables. */ static void @@ -6535,6 +6559,9 @@ rewrite_uses (struct ivopts_data *data) struct iv_cand *cand; struct iv_use *use; + /* Sort uses so that dominating uses are processed first. */ + data->iv_uses.qsort (ivuse_cmp); + for (i = 0; i < n_iv_uses (data); i++) { use = iv_use (data, i);