canonicalize_addr_expr (expr_p);
}
+ /* If we have a conversion to a non-register type force the
+ use of a VIEW_CONVERT_EXPR instead. */
+ if (!is_gimple_reg_type (TREE_TYPE (*expr_p)))
+ *expr_p = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
+ TREE_OPERAND (*expr_p, 0));
+
return GS_OK;
}
/* Mark the RHS addressable. */
ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
is_gimple_addressable, fb_either);
- if (ret != GS_ERROR)
- {
- op0 = TREE_OPERAND (expr, 0);
+ if (ret == GS_ERROR)
+ break;
- /* For various reasons, the gimplification of the expression
- may have made a new INDIRECT_REF. */
- if (TREE_CODE (op0) == INDIRECT_REF)
- goto do_indirect_ref;
+ /* We cannot rely on making the RHS addressable if it is
+ a temporary created by gimplification. In this case create a
+ new temporary that is initialized by a copy (which will
+ become a store after we mark it addressable).
+ This mostly happens if the frontend passed us something that
+ it could not mark addressable yet, like a fortran
+ pass-by-reference parameter (int) floatvar. */
+ if (is_gimple_formal_tmp_var (TREE_OPERAND (expr, 0)))
+ TREE_OPERAND (expr, 0)
+ = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
- /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
- recompute_tree_invariant_for_addr_expr (expr);
+ op0 = TREE_OPERAND (expr, 0);
- mark_addressable (TREE_OPERAND (expr, 0));
- }
+ /* For various reasons, the gimplification of the expression
+ may have made a new INDIRECT_REF. */
+ if (TREE_CODE (op0) == INDIRECT_REF)
+ goto do_indirect_ref;
+
+ /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
+ recompute_tree_invariant_for_addr_expr (expr);
+
+ mark_addressable (TREE_OPERAND (expr, 0));
break;
}