Change default of non-overlapping address space conversion

The current default of making all undefined coversions being
set to null is not useful.  It has caused all users to lie
and say that spaces are subsets when they are not, just so
that they can override the conversion.

	* expr.c (expand_expr_real_2): Use convert_modes on disjoint
	address spaces.

From-SVN: r229142
This commit is contained in:
Richard Henderson 2015-10-21 13:31:26 -07:00 committed by Richard Henderson
parent abcc43f532
commit 2e44cd8b00
2 changed files with 23 additions and 12 deletions

View File

@ -1,3 +1,8 @@
2015-10-21 Richard Henderson <rth@redhat.com>
* expr.c (expand_expr_real_2): Use convert_modes on disjoint
address spaces.
2015-10-21 Richard Sandiford <richard.sandiford@arm.com>
* builtins.c (fold_builtin_cabs): Delete.

View File

@ -8171,36 +8171,42 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
case ADDR_SPACE_CONVERT_EXPR:
{
tree treeop0_type = TREE_TYPE (treeop0);
addr_space_t as_to;
addr_space_t as_from;
gcc_assert (POINTER_TYPE_P (type));
gcc_assert (POINTER_TYPE_P (treeop0_type));
as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
/* Conversions between pointers to the same address space should
have been implemented via CONVERT_EXPR / NOP_EXPR. */
gcc_assert (as_to != as_from);
op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
/* Ask target code to handle conversion between pointers
to overlapping address spaces. */
if (targetm.addr_space.subset_p (as_to, as_from)
|| targetm.addr_space.subset_p (as_from, as_to))
{
op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
op0 = targetm.addr_space.convert (op0, treeop0_type, type);
}
else
{
/* For disjoint address spaces, converting anything but a null
pointer invokes undefined behaviour. We truncate or extend the
value as if we'd converted via integers, which handles 0 as
required, and all others as the programmer likely expects. */
#ifndef POINTERS_EXTEND_UNSIGNED
const int POINTERS_EXTEND_UNSIGNED = 1;
#endif
op0 = convert_modes (mode, TYPE_MODE (treeop0_type),
op0, POINTERS_EXTEND_UNSIGNED);
}
gcc_assert (op0);
return op0;
}
/* For disjoint address spaces, converting anything but
a null pointer invokes undefined behaviour. We simply
always return a null pointer here. */
return CONST0_RTX (mode);
}
case POINTER_PLUS_EXPR:
/* Even though the sizetype mode and the pointer's mode can be different
expand is able to handle this correctly and get the correct result out