You want to look at tree-ssa-operands.c:get_expr_operands() and see where things go wrong. Also for D.861 not in SSA form, there might be a missing call to mark_vars_to_rename and/or update_ssa somewhere. At which point in the pass flow does the above happen? Is it ever "correct"?
A couple of hours after sending my email, I figured out what happened. The reason why D.861 was not in SSA form was that it was TREE_ADDRESSABLE and everything else was due to that. This turned out to be the "well known" problem that the Ada front end is making an ADDR_EXPR of odd things, in this case a COMPOUND_EXPR. If I put code in the language-specific gimplifier to do: /* Otherwise, if we are taking the address of something that is neither a refence, declaration, or constant, make a variable for the operand here and then take its address. If we don't do it this way, we may confuse the gimplifier because it needs to know the variable is addressable at this point. This duplicates code in internal_get_tmp_var, which is unfortunate. */ else if (TREE_CODE_CLASS (TREE_CODE (op)) != tcc_reference && TREE_CODE_CLASS (TREE_CODE (op)) != tcc_declaration && TREE_CODE_CLASS (TREE_CODE (op)) != tcc_constant) { tree new_var = create_tmp_var (TREE_TYPE (op), "A"); tree mod = build (MODIFY_EXPR, TREE_TYPE (op), new_var, op); TREE_ADDRESSABLE (new_var) = 1; if (TREE_CODE (TREE_TYPE (op)) == COMPLEX_TYPE) DECL_COMPLEX_GIMPLE_REG_P (new_var) = 1; if (EXPR_HAS_LOCATION (op)) SET_EXPR_LOCUS (mod, EXPR_LOCUS (op)); gimplify_and_add (mod, pre_p); TREE_OPERAND (expr, 0) = new_var; recompute_tree_invarant_for_addr_expr (expr); return GS_ALL_DONE; } it all works. Whether this should be here or in gimplify.c is a matter mostly of philosphy. I don't care for the duplication of code in internal_get_tmp_var from a maintainability point of view and that argues for adding an "addressable" parameter to the routine and calling it that way from gimplify_addr_expr. The counter argument is that this tree is only made by Ada, so it should be done within the Ada front end. On the other hand, we define "valid GENERIC" to be those trees that were generated by the compiler immediately before the tree-ssa conversion and trees of the above form were generated then. So they are valid GENERIC and ought to be handled by the gimplifier. It would also be good to put an assert into the gimplifier that detects the case where one of its variable is suddenly marked addressable since that meant it produced invalid gimple earlier, but since we have no flag to denote such, I don't think we can do it now. Are there are feelings about where this code should go? My preference is gimplify.c, but if there are strong feelings the other way, I'm OK with leaving it where it is now.