* gimple.c (check_loadstore): Return false when 0 is a valid address.
* fold-const.c (const_unop) [ADDR_SPACE_CONVERT_EXPR]: Do not fold
null when 0 is valid in the source address space.
* target.def (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): New.
* targhooks.c (default_addr_space_zero_address_valid): New.
* targhooks.h (default_addr_space_zero_address_valid): Declare.
* doc/tm.texi.in (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): Mark it.
* doc/tm.texi: Rebuild.
From-SVN: r229999
2015-11-09 Richard Henderson <rth@redhat.com>
+ * gimple.c (check_loadstore): Return false when 0 is a valid address.
+ * fold-const.c (const_unop) [ADDR_SPACE_CONVERT_EXPR]: Do not fold
+ null when 0 is valid in the source address space.
+ * target.def (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): New.
+ * targhooks.c (default_addr_space_zero_address_valid): New.
+ * targhooks.h (default_addr_space_zero_address_valid): Declare.
+ * doc/tm.texi.in (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): Mark it.
+ * doc/tm.texi: Rebuild.
+
* cselib.c (add_mem_for_addr): Compare address spaces when
matching memories.
(cselib_lookup_mem): Likewise.
converted to pointers to a subset address space via explicit casts.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID (addr_space_t @var{as})
+Define this to modify the default handling of address 0 for the
+address space. Return true if 0 should be considered a valid address.
+@end deftypefn
+
@deftypefn {Target Hook} rtx TARGET_ADDR_SPACE_CONVERT (rtx @var{op}, tree @var{from_type}, tree @var{to_type})
Define this to convert the pointer expression represented by the RTL
@var{op} with type @var{from_type} that points to a named address
@hook TARGET_ADDR_SPACE_SUBSET_P
+@hook TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
+
@hook TARGET_ADDR_SPACE_CONVERT
@node Misc
return fold_convert_const (code, type, arg0);
case ADDR_SPACE_CONVERT_EXPR:
- if (integer_zerop (arg0))
+ /* If the source address is 0, and the source address space
+ cannot have a valid object at 0, fold to dest type null. */
+ if (integer_zerop (arg0)
+ && !(targetm.addr_space.zero_address_valid
+ (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0))))))
return fold_convert_const (code, type, arg0);
break;
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "gimplify.h"
+#include "target.h"
/* All the tuples have their operand vector (if present) at the very bottom
static bool
check_loadstore (gimple *, tree op, tree, void *data)
{
- if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
- && operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0))
- return true;
+ if (TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
+ {
+ /* Some address spaces may legitimately dereference zero. */
+ addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (op));
+ if (targetm.addr_space.zero_address_valid (as))
+ return false;
+
+ return operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0);
+ }
return false;
}
bool, (addr_space_t subset, addr_space_t superset),
default_addr_space_subset_p)
+/* True if 0 is a valid address in the address space, or false if
+ 0 is a NULL in the address space. */
+DEFHOOK
+(zero_address_valid,
+ "Define this to modify the default handling of address 0 for the\n\
+address space. Return true if 0 should be considered a valid address.",
+ bool, (addr_space_t as),
+ default_addr_space_zero_address_valid)
+
/* Function to convert an rtl expression from one address space to another. */
DEFHOOK
(convert,
return (subset == superset);
}
+/* The default hook for determining if 0 within a named address
+ space is a valid address. */
+
+bool
+default_addr_space_zero_address_valid (addr_space_t as ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
/* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be
called for targets with only a generic address space. */
extern rtx default_addr_space_legitimize_address (rtx, rtx, machine_mode,
addr_space_t);
extern bool default_addr_space_subset_p (addr_space_t, addr_space_t);
+extern bool default_addr_space_zero_address_valid (addr_space_t);
extern rtx default_addr_space_convert (rtx, tree, tree);
extern unsigned int default_case_values_threshold (void);
extern bool default_have_conditional_execution (void);