Jeff Law <l...@redhat.com> writes: > On 01/09/2018 11:39 AM, Richard Sandiford wrote: >> This patch generalises various places that used hwi tree accessors >> so that they can handle poly_ints instead. Earlier patches did >> this while updating interfaces; this patch just mops up some >> left-over pieces that weren't necessary to make things compile, >> but that still make sense. >> >> In many cases these changes are by inspection rather than because >> something had shown them to be necessary. >> >> I think the alias.c part is a minor bug fix: previously we used >> fits_uhwi_p for a signed HOST_WIDE_INT (which the caller does >> treat as signed rather than unsigned). We also checked whether >> each individual offset overflowed but didn't check whether the >> sum did. >> >> Sorry for not posting this earlier. I kept holding it back in case >> more examples showed up. >> >> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu. >> Also tested by comparing the before-and-after assembly output for at >> least one target per CPU directory. OK to install? >> >> Richard >> >> >> 2018-01-09 Richard Sandiford <richard.sandif...@linaro.org> >> >> gcc/ >> * alias.c (adjust_offset_for_component_ref): Use poly_int_tree_p >> and wi::to_poly_offset. Add the current offset and then check >> whether the sum fits, rather than using an unchecked addition of >> a checked term. Check for a shwi rather than a uhwi. >> * expr.c (get_bit_range): Use tree_to_poly_uint64. >> (store_constructor): Use poly_int_tree_p. >> (expand_expr_real_1): Likewise. >> * function.c (assign_temp): Likewise. >> * fold-const.c (const_binop): Use poly_int_tree_p and >> wi::to_poly_offset. >> (fold_indirect_ref_1): Likewise. Use known_in_range_p to test >> for an in-range vector access and multiple_p to attempt an exact >> division. >> * gimplify.c (gimple_add_tmp_var_fn): Use tree_fits_poly_uint64_p. >> (gimple_add_tmp_var): Likewise. >> * ipa-icf-gimple.c (func_checker::compare_operand): Use >> to_poly_offset for MEM offsets. >> * ipa-icf.c (sem_variable::equals): Likewise. >> * stor-layout.c (compute_record_mode): Use poly_int_tree_p. >> * tree-vectorizer.c (get_vec_alignment_for_array_type): Likewise. >> * tree-predcom.c (aff_combination_dr_offset): Use wi::to_poly_widest >> rather than wi::to_widest for DR_INITs. >> * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use >> wi::to_poly_offset for BIT_FIELD_REF offsets. >> (vn_reference_maybe_forwprop_address): Use poly_int_tree_p and >> wi::to_poly_offset. >> * tree-vect-data-refs.c (vect_find_same_alignment_drs): Use >> wi::to_poly_offset for DR_INIT. >> (vect_analyze_data_ref_accesses): Require both DR_INITs to be >> INTEGER_CSTs. >> (vect_analyze_group_access_1): Note that here. >> * var-tracking.c (emit_note_insn_var_location): Use >> tree_to_poly_uint64. > OK. If minor edits are necessary to deal changes since this was > originally posted, consider those pre-approved.
Thanks Jeff! Finally got round to updating and retesting this. Committed as r260914. Richard 2018-05-30 Richard Sandiford <richard.sandif...@linaro.org> gcc/ * alias.c (adjust_offset_for_component_ref): Use poly_int_tree_p and wi::to_poly_offset. Add the current offset and then check whether the sum fits, rather than using an unchecked addition of a checked term. Check for a shwi rather than a uhwi. * expr.c (get_bit_range): Use tree_to_poly_uint64. (store_constructor): Use poly_int_tree_p. (expand_expr_real_1): Likewise. * function.c (assign_temp): Likewise. * fold-const.c (const_binop): Use poly_int_tree_p and wi::to_poly_offset. (fold_indirect_ref_1): Likewise. Use multiple_p to attempt an exact division. * ipa-icf-gimple.c (func_checker::compare_operand): Use to_poly_offset for MEM offsets. * ipa-icf.c (sem_variable::equals): Likewise. * stor-layout.c (compute_record_mode): Use poly_int_tree_p. * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use wi::to_poly_offset for BIT_FIELD_REF offsets. (vn_reference_maybe_forwprop_address): Use poly_int_tree_p and wi::to_poly_offset. * var-tracking.c (emit_note_insn_var_location): Use tree_to_poly_uint64. Index: gcc/alias.c =================================================================== --- gcc/alias.c 2018-04-10 11:26:52.500490858 +0100 +++ gcc/alias.c 2018-05-30 07:26:50.931554833 +0100 @@ -2698,22 +2698,22 @@ adjust_offset_for_component_ref (tree x, { tree xoffset = component_ref_field_offset (x); tree field = TREE_OPERAND (x, 1); - if (TREE_CODE (xoffset) != INTEGER_CST) + if (!poly_int_tree_p (xoffset)) { *known_p = false; return; } - offset_int woffset - = (wi::to_offset (xoffset) + poly_offset_int woffset + = (wi::to_poly_offset (xoffset) + (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)) - >> LOG2_BITS_PER_UNIT)); - if (!wi::fits_uhwi_p (woffset)) + >> LOG2_BITS_PER_UNIT) + + *offset); + if (!woffset.to_shwi (offset)) { *known_p = false; return; } - *offset += woffset.to_uhwi (); x = TREE_OPERAND (x, 0); } Index: gcc/expr.c =================================================================== --- gcc/expr.c 2018-05-18 09:26:37.721714880 +0100 +++ gcc/expr.c 2018-05-30 07:26:50.933554808 +0100 @@ -4913,7 +4913,7 @@ get_bit_range (poly_uint64_pod *bitstart else *bitstart = *bitpos - bitoffset; - *bitend = *bitstart + tree_to_uhwi (DECL_SIZE (repr)) - 1; + *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1; } /* Returns true if ADDR is an ADDR_EXPR of a DECL that does not reside @@ -6521,12 +6521,10 @@ store_constructor (tree exp, rtx target, continue; mode = TYPE_MODE (elttype); - if (mode == BLKmode) - bitsize = (tree_fits_uhwi_p (TYPE_SIZE (elttype)) - ? tree_to_uhwi (TYPE_SIZE (elttype)) - : -1); - else + if (mode != BLKmode) bitsize = GET_MODE_BITSIZE (mode); + else if (!poly_int_tree_p (TYPE_SIZE (elttype), &bitsize)) + bitsize = -1; if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR) { @@ -10235,11 +10233,11 @@ expand_expr_real_1 (tree exp, rtx target { poly_int64 offset = mem_ref_offset (exp).force_shwi (); base = TREE_OPERAND (base, 0); + poly_uint64 type_size; if (known_eq (offset, 0) && !reverse - && tree_fits_uhwi_p (TYPE_SIZE (type)) - && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), - tree_to_uhwi (TYPE_SIZE (type)))) + && poly_int_tree_p (TYPE_SIZE (type), &type_size) + && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size)) return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base), target, tmode, modifier); if (TYPE_MODE (type) == BLKmode) Index: gcc/function.c =================================================================== --- gcc/function.c 2018-03-24 10:52:14.276582048 +0000 +++ gcc/function.c 2018-05-30 07:26:50.935554783 +0100 @@ -978,25 +978,26 @@ assign_temp (tree type_or_decl, int memo if (mode == BLKmode || memory_required) { - HOST_WIDE_INT size = int_size_in_bytes (type); + poly_int64 size; rtx tmp; - /* Zero sized arrays are GNU C extension. Set size to 1 to avoid - problems with allocating the stack space. */ - if (size == 0) - size = 1; - /* Unfortunately, we don't yet know how to allocate variable-sized temporaries. However, sometimes we can find a fixed upper limit on the size, so try that instead. */ - else if (size == -1) + if (!poly_int_tree_p (TYPE_SIZE_UNIT (type), &size)) size = max_int_size_in_bytes (type); + /* Zero sized arrays are a GNU C extension. Set size to 1 to avoid + problems with allocating the stack space. */ + if (known_eq (size, 0)) + size = 1; + /* The size of the temporary may be too large to fit into an integer. */ /* ??? Not sure this should happen except for user silliness, so limit this to things that aren't compiler-generated temporaries. The rest of the time we'll die in assign_stack_temp_for_type. */ - if (decl && size == -1 + if (decl + && !known_size_p (size) && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST) { error ("size of variable %q+D is too large", decl); Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c 2018-05-30 07:24:51.607241042 +0100 +++ gcc/fold-const.c 2018-05-30 07:26:50.934554795 +0100 @@ -1611,10 +1611,10 @@ const_binop (enum tree_code code, tree t return NULL_TREE; case POINTER_DIFF_EXPR: - if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg2) == INTEGER_CST) + if (poly_int_tree_p (arg1) && poly_int_tree_p (arg2)) { - offset_int res = wi::sub (wi::to_offset (arg1), - wi::to_offset (arg2)); + poly_offset_int res = (wi::to_poly_offset (arg1) + - wi::to_poly_offset (arg2)); return force_fit_type (type, res, 1, TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)); } @@ -14193,13 +14193,12 @@ fold_indirect_ref_1 (location_t loc, tre tree min_val = size_zero_node; if (type_domain && TYPE_MIN_VALUE (type_domain)) min_val = TYPE_MIN_VALUE (type_domain); - offset_int off = wi::to_offset (op01); - offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type)); - offset_int remainder; - off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder); - if (remainder == 0 && TREE_CODE (min_val) == INTEGER_CST) + poly_uint64 type_size, index; + if (poly_int_tree_p (min_val) + && poly_int_tree_p (TYPE_SIZE_UNIT (type), &type_size) + && multiple_p (const_op01, type_size, &index)) { - off = off + wi::to_offset (min_val); + poly_offset_int off = index + wi::to_poly_offset (min_val); op01 = wide_int_to_tree (sizetype, off); return build4_loc (loc, ARRAY_REF, type, op00, op01, NULL_TREE, NULL_TREE); Index: gcc/ipa-icf-gimple.c =================================================================== --- gcc/ipa-icf-gimple.c 2018-01-12 16:56:29.267928000 +0000 +++ gcc/ipa-icf-gimple.c 2018-05-30 07:26:50.935554783 +0100 @@ -463,7 +463,7 @@ func_checker::compare_operand (tree t1, return return_false_with_msg (""); /* Type of the offset on MEM_REF does not matter. */ - return wi::to_offset (y1) == wi::to_offset (y2); + return known_eq (wi::to_poly_offset (y1), wi::to_poly_offset (y2)); } case COMPONENT_REF: { Index: gcc/ipa-icf.c =================================================================== --- gcc/ipa-icf.c 2018-05-22 13:22:01.883333074 +0100 +++ gcc/ipa-icf.c 2018-05-30 07:26:50.935554783 +0100 @@ -1983,8 +1983,8 @@ sem_variable::equals (tree t1, tree t2) /* Type of the offset on MEM_REF does not matter. */ return return_with_debug (sem_variable::equals (x1, x2) - && wi::to_offset (y1) - == wi::to_offset (y2)); + && known_eq (wi::to_poly_offset (y1), + wi::to_poly_offset (y2))); } case ADDR_EXPR: case FDESC_EXPR: Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c 2018-03-01 08:20:43.845526342 +0000 +++ gcc/stor-layout.c 2018-05-30 07:26:50.936554770 +0100 @@ -1838,9 +1838,11 @@ compute_record_mode (tree type) /* If we only have one real field; use its mode if that mode's size matches the type's size. This only applies to RECORD_TYPE. This does not apply to unions. */ - if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode - && tree_fits_uhwi_p (TYPE_SIZE (type)) - && known_eq (GET_MODE_BITSIZE (mode), tree_to_uhwi (TYPE_SIZE (type)))) + poly_uint64 type_size; + if (TREE_CODE (type) == RECORD_TYPE + && mode != VOIDmode + && poly_int_tree_p (TYPE_SIZE (type), &type_size) + && known_eq (GET_MODE_BITSIZE (mode), type_size)) ; else mode = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1).else_blk (); Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c 2018-05-30 07:24:51.894236549 +0100 +++ gcc/tree-ssa-sccvn.c 2018-05-30 07:26:50.936554770 +0100 @@ -999,7 +999,7 @@ ao_ref_init_from_vn_reference (ao_ref *r /* And now the usual component-reference style ops. */ case BIT_FIELD_REF: - offset += wi::to_offset (op->op1); + offset += wi::to_poly_offset (op->op1); break; case COMPONENT_REF: @@ -1265,10 +1265,10 @@ vn_reference_maybe_forwprop_address (vec ptroff = gimple_assign_rhs2 (def_stmt); if (TREE_CODE (ptr) != SSA_NAME || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr) - || TREE_CODE (ptroff) != INTEGER_CST) + || !poly_int_tree_p (ptroff)) return false; - off += wi::to_offset (ptroff); + off += wi::to_poly_offset (ptroff); op->op0 = ptr; } Index: gcc/var-tracking.c =================================================================== --- gcc/var-tracking.c 2018-05-01 19:31:03.074312721 +0100 +++ gcc/var-tracking.c 2018-05-30 07:26:50.937554757 +0100 @@ -8665,7 +8665,6 @@ emit_note_insn_var_location (variable ** bool complete; enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED; HOST_WIDE_INT last_limit; - tree type_size_unit; HOST_WIDE_INT offsets[MAX_VAR_PARTS]; rtx loc[MAX_VAR_PARTS]; tree decl; @@ -8816,8 +8815,9 @@ emit_note_insn_var_location (variable ** } ++n_var_parts; } - type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl)); - if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit)) + poly_uint64 type_size_unit + = tree_to_poly_uint64 (TYPE_SIZE_UNIT (TREE_TYPE (decl))); + if (maybe_lt (poly_uint64 (last_limit), type_size_unit)) complete = false; if (! flag_var_tracking_uninit)