aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-12-21 07:01:38 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-12-21 07:01:38 +0000
commite7301f5fcbfa649beb05da1e3508db7fc7c4d26b (patch)
tree78865bf62d706915d434176a2fbc7d8632a24802 /gcc
parentf8f667be749428f92a33d6c4ff8b56538f958c10 (diff)
downloadgcc-e7301f5fcbfa649beb05da1e3508db7fc7c4d26b.zip
gcc-e7301f5fcbfa649beb05da1e3508db7fc7c4d26b.tar.gz
gcc-e7301f5fcbfa649beb05da1e3508db7fc7c4d26b.tar.bz2
poly_int: bit_field_size/offset
verify_expr ensured that the size and offset in gimple BIT_FIELD_REFs satisfied tree_fits_uhwi_p. This patch extends that so that they can be poly_uint64s, and adds helper routines for accessing them when the verify_expr requirements apply. 2017-12-21 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * tree.h (bit_field_size, bit_field_offset): New functions. * hsa-gen.c (gen_hsa_addr): Use them. * tree-ssa-forwprop.c (simplify_bitfield_ref): Likewise. (simplify_vector_constructor): Likewise. * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise. * tree-cfg.c (verify_expr): Require the sizes and offsets of a BIT_FIELD_REF to be poly_uint64s rather than uhwis. * fold-const.c (fold_ternary_loc): Protect tree_to_uhwi with tree_fits_uhwi_p. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r255926
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/fold-const.c4
-rw-r--r--gcc/hsa-gen.c4
-rw-r--r--gcc/tree-cfg.c16
-rw-r--r--gcc/tree-ssa-forwprop.c14
-rw-r--r--gcc/tree-ssa-sccvn.c8
-rw-r--r--gcc/tree.h18
7 files changed, 54 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9c985b2..a3ed3ce 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,20 @@
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
+ * tree.h (bit_field_size, bit_field_offset): New functions.
+ * hsa-gen.c (gen_hsa_addr): Use them.
+ * tree-ssa-forwprop.c (simplify_bitfield_ref): Likewise.
+ (simplify_vector_constructor): Likewise.
+ * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise.
+ * tree-cfg.c (verify_expr): Require the sizes and offsets of a
+ BIT_FIELD_REF to be poly_uint64s rather than uhwis.
+ * fold-const.c (fold_ternary_loc): Protect tree_to_uhwi with
+ tree_fits_uhwi_p.
+
+2017-12-21 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
* expr.h (emit_group_load, emit_group_load_into_temps)
(emit_group_store): Take the size as a poly_int64 rather than an int.
* expr.c (emit_group_load_1, emit_group_load): Likewise.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 2039d4d..b21f35a 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -11632,7 +11632,9 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
fold (nearly) all BIT_FIELD_REFs. */
if (CONSTANT_CLASS_P (arg0)
&& can_native_interpret_type_p (type)
- && BITS_PER_UNIT == 8)
+ && BITS_PER_UNIT == 8
+ && tree_fits_uhwi_p (op1)
+ && tree_fits_uhwi_p (op2))
{
unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (op1);
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 9284a3c..155bcdf 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -1959,8 +1959,8 @@ gen_hsa_addr (tree ref, hsa_bb *hbb, HOST_WIDE_INT *output_bitsize = NULL,
goto out;
}
else if (TREE_CODE (ref) == BIT_FIELD_REF
- && ((tree_to_uhwi (TREE_OPERAND (ref, 1)) % BITS_PER_UNIT) != 0
- || (tree_to_uhwi (TREE_OPERAND (ref, 2)) % BITS_PER_UNIT) != 0))
+ && (!multiple_p (bit_field_size (ref), BITS_PER_UNIT)
+ || !multiple_p (bit_field_offset (ref), BITS_PER_UNIT)))
{
HSA_SORRY_ATV (EXPR_LOCATION (origref),
"support for HSA does not implement "
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index ae5335b..bed4947 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3170,8 +3170,9 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
tree t0 = TREE_OPERAND (t, 0);
tree t1 = TREE_OPERAND (t, 1);
tree t2 = TREE_OPERAND (t, 2);
- if (!tree_fits_uhwi_p (t1)
- || !tree_fits_uhwi_p (t2)
+ poly_uint64 size, bitpos;
+ if (!poly_int_tree_p (t1, &size)
+ || !poly_int_tree_p (t2, &bitpos)
|| !types_compatible_p (bitsizetype, TREE_TYPE (t1))
|| !types_compatible_p (bitsizetype, TREE_TYPE (t2)))
{
@@ -3179,8 +3180,7 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
return t;
}
if (INTEGRAL_TYPE_P (TREE_TYPE (t))
- && (TYPE_PRECISION (TREE_TYPE (t))
- != tree_to_uhwi (t1)))
+ && maybe_ne (TYPE_PRECISION (TREE_TYPE (t)), size))
{
error ("integral result type precision does not match "
"field size of BIT_FIELD_REF");
@@ -3188,16 +3188,16 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
}
else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
&& TYPE_MODE (TREE_TYPE (t)) != BLKmode
- && (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (t)))
- != tree_to_uhwi (t1)))
+ && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (t))),
+ size))
{
error ("mode size of non-integral result does not "
"match field size of BIT_FIELD_REF");
return t;
}
if (!AGGREGATE_TYPE_P (TREE_TYPE (t0))
- && (tree_to_uhwi (t1) + tree_to_uhwi (t2)
- > tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t0)))))
+ && maybe_gt (size + bitpos,
+ tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (t0)))))
{
error ("position plus size exceeds size of referenced object in "
"BIT_FIELD_REF");
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 74a54c3..41ee409 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1781,7 +1781,7 @@ simplify_bitfield_ref (gimple_stmt_iterator *gsi)
gimple *def_stmt;
tree op, op0, op1, op2;
tree elem_type;
- unsigned idx, n, size;
+ unsigned idx, size;
enum tree_code code;
op = gimple_assign_rhs1 (stmt);
@@ -1816,12 +1816,11 @@ simplify_bitfield_ref (gimple_stmt_iterator *gsi)
return false;
size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
- n = TREE_INT_CST_LOW (op1) / size;
- if (n != 1)
+ if (maybe_ne (bit_field_size (op), size))
return false;
- idx = TREE_INT_CST_LOW (op2) / size;
- if (code == VEC_PERM_EXPR)
+ if (code == VEC_PERM_EXPR
+ && constant_multiple_p (bit_field_offset (op), size, &idx))
{
tree p, m, tem;
unsigned nelts;
@@ -2074,9 +2073,10 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
return false;
orig = ref;
}
- if (TREE_INT_CST_LOW (TREE_OPERAND (op1, 1)) != elem_size)
+ unsigned int elt;
+ if (maybe_ne (bit_field_size (op1), elem_size)
+ || !constant_multiple_p (bit_field_offset (op1), elem_size, &elt))
return false;
- unsigned int elt = TREE_INT_CST_LOW (TREE_OPERAND (op1, 2)) / elem_size;
if (elt != i)
maybe_ident = false;
sel.quick_push (elt);
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index b59d8eb..89ef26c 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -779,12 +779,8 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
/* Record bits, position and storage order. */
temp.op0 = TREE_OPERAND (ref, 1);
temp.op1 = TREE_OPERAND (ref, 2);
- if (tree_fits_shwi_p (TREE_OPERAND (ref, 2)))
- {
- HOST_WIDE_INT off = tree_to_shwi (TREE_OPERAND (ref, 2));
- if (off % BITS_PER_UNIT == 0)
- temp.off = off / BITS_PER_UNIT;
- }
+ if (!multiple_p (bit_field_offset (ref), BITS_PER_UNIT, &temp.off))
+ temp.off = -1;
temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
break;
case COMPONENT_REF:
diff --git a/gcc/tree.h b/gcc/tree.h
index 5ac1f25..e8a2470 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4784,6 +4784,24 @@ poly_int_tree_p (const_tree t)
return (TREE_CODE (t) == INTEGER_CST || POLY_INT_CST_P (t));
}
+/* Return the bit size of BIT_FIELD_REF T, in cases where it is known
+ to be a poly_uint64. (This is always true at the gimple level.) */
+
+inline poly_uint64
+bit_field_size (const_tree t)
+{
+ return tree_to_poly_uint64 (TREE_OPERAND (t, 1));
+}
+
+/* Return the starting bit offset of BIT_FIELD_REF T, in cases where it is
+ known to be a poly_uint64. (This is always true at the gimple level.) */
+
+inline poly_uint64
+bit_field_offset (const_tree t)
+{
+ return tree_to_poly_uint64 (TREE_OPERAND (t, 2));
+}
+
extern tree strip_float_extensions (tree);
extern int really_constant_p (const_tree);
extern bool ptrdiff_tree_p (const_tree, poly_int64_pod *);