]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
poly_int: get_inner_reference & co.
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 21 Dec 2017 06:57:41 +0000 (06:57 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 21 Dec 2017 06:57:41 +0000 (06:57 +0000)
This patch makes get_inner_reference and ptr_difference_const return the
bit size and bit position as poly_int64s rather than HOST_WIDE_INTS.
The non-mechanical changes were handled by previous patches.

2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* tree.h (get_inner_reference): Return the bitsize and bitpos
as poly_int64_pods rather than HOST_WIDE_INT.
* fold-const.h (ptr_difference_const): Return the pointer difference
as a poly_int64_pod rather than a HOST_WIDE_INT.
* expr.c (get_inner_reference): Return the bitsize and bitpos
as poly_int64_pods rather than HOST_WIDE_INT.
(expand_expr_addr_expr_1, expand_expr_real_1): Track polynomial
offsets and sizes.
* fold-const.c (make_bit_field_ref): Take the bitpos as a poly_int64
rather than a HOST_WIDE_INT.  Update call to get_inner_reference.
(optimize_bit_field_compare): Update call to get_inner_reference.
(decode_field_reference): Likewise.
(fold_unary_loc): Track polynomial offsets and sizes.
(split_address_to_core_and_offset): Return the bitpos as a
poly_int64_pod rather than a HOST_WIDE_INT.
(ptr_difference_const): Likewise for the pointer difference.
* asan.c (instrument_derefs): Track polynomial offsets and sizes.
* config/mips/mips.c (r10k_safe_mem_expr_p): Likewise.
* dbxout.c (dbxout_expand_expr): Likewise.
* dwarf2out.c (loc_list_for_address_of_addr_expr_of_indirect_ref)
(loc_list_from_tree_1, fortran_common): Likewise.
* gimple-laddress.c (pass_laddress::execute): Likewise.
* gimple-ssa-store-merging.c (find_bswap_or_nop_load): Likewise.
* gimplify.c (gimplify_scan_omp_clauses): Likewise.
* simplify-rtx.c (delegitimize_mem_from_attrs): Likewise.
* tree-affine.c (tree_to_aff_combination): Likewise.
(get_inner_reference_aff): Likewise.
* tree-data-ref.c (split_constant_offset_1): Likewise.
(dr_analyze_innermost): Likewise.
* tree-scalar-evolution.c (interpret_rhs_expr): Likewise.
* tree-sra.c (ipa_sra_check_caller): Likewise.
* tree-vect-data-refs.c (vect_check_gather_scatter): Likewise.
* ubsan.c (maybe_instrument_pointer_overflow): Likewise.
(instrument_bool_enum_load, instrument_object_size): Likewise.
* gimple-ssa-strength-reduction.c (slsr_process_ref): Update call
to get_inner_reference.
* hsa-gen.c (gen_hsa_addr): Likewise.
* sanopt.c (maybe_optimize_ubsan_ptr_ifn): Likewise.
* tsan.c (instrument_expr): Likewise.
* match.pd: Update call to ptr_difference_const.

gcc/ada/
* gcc-interface/trans.c (Attribute_to_gnu): Track polynomial
offsets and sizes.
* gcc-interface/utils2.c (build_unary_op): Likewise.

gcc/cp/
* constexpr.c (check_automatic_or_tls): Track polynomial
offsets and sizes.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255914

29 files changed:
gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c
gcc/ada/gcc-interface/utils2.c
gcc/asan.c
gcc/config/mips/mips.c
gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/dbxout.c
gcc/dwarf2out.c
gcc/expr.c
gcc/fold-const.c
gcc/fold-const.h
gcc/gimple-laddress.c
gcc/gimple-ssa-store-merging.c
gcc/gimple-ssa-strength-reduction.c
gcc/gimplify.c
gcc/hsa-gen.c
gcc/match.pd
gcc/sanopt.c
gcc/simplify-rtx.c
gcc/tree-affine.c
gcc/tree-data-ref.c
gcc/tree-scalar-evolution.c
gcc/tree-sra.c
gcc/tree-vect-data-refs.c
gcc/tree.h
gcc/tsan.c
gcc/ubsan.c

index acfbb4e193c86a6bbeccc06a9cbb5615a55d8223..fd061b9c2cafcedb11f9a1bbe420043dab2cb8ca 100644 (file)
@@ -1,3 +1,48 @@
+2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * tree.h (get_inner_reference): Return the bitsize and bitpos
+       as poly_int64_pods rather than HOST_WIDE_INT.
+       * fold-const.h (ptr_difference_const): Return the pointer difference
+       as a poly_int64_pod rather than a HOST_WIDE_INT.
+       * expr.c (get_inner_reference): Return the bitsize and bitpos
+       as poly_int64_pods rather than HOST_WIDE_INT.
+       (expand_expr_addr_expr_1, expand_expr_real_1): Track polynomial
+       offsets and sizes.
+       * fold-const.c (make_bit_field_ref): Take the bitpos as a poly_int64
+       rather than a HOST_WIDE_INT.  Update call to get_inner_reference.
+       (optimize_bit_field_compare): Update call to get_inner_reference.
+       (decode_field_reference): Likewise.
+       (fold_unary_loc): Track polynomial offsets and sizes.
+       (split_address_to_core_and_offset): Return the bitpos as a
+       poly_int64_pod rather than a HOST_WIDE_INT.
+       (ptr_difference_const): Likewise for the pointer difference.
+       * asan.c (instrument_derefs): Track polynomial offsets and sizes.
+       * config/mips/mips.c (r10k_safe_mem_expr_p): Likewise.
+       * dbxout.c (dbxout_expand_expr): Likewise.
+       * dwarf2out.c (loc_list_for_address_of_addr_expr_of_indirect_ref)
+       (loc_list_from_tree_1, fortran_common): Likewise.
+       * gimple-laddress.c (pass_laddress::execute): Likewise.
+       * gimple-ssa-store-merging.c (find_bswap_or_nop_load): Likewise.
+       * gimplify.c (gimplify_scan_omp_clauses): Likewise.
+       * simplify-rtx.c (delegitimize_mem_from_attrs): Likewise.
+       * tree-affine.c (tree_to_aff_combination): Likewise.
+       (get_inner_reference_aff): Likewise.
+       * tree-data-ref.c (split_constant_offset_1): Likewise.
+       (dr_analyze_innermost): Likewise.
+       * tree-scalar-evolution.c (interpret_rhs_expr): Likewise.
+       * tree-sra.c (ipa_sra_check_caller): Likewise.
+       * tree-vect-data-refs.c (vect_check_gather_scatter): Likewise.
+       * ubsan.c (maybe_instrument_pointer_overflow): Likewise.
+       (instrument_bool_enum_load, instrument_object_size): Likewise.
+       * gimple-ssa-strength-reduction.c (slsr_process_ref): Update call
+       to get_inner_reference.
+       * hsa-gen.c (gen_hsa_addr): Likewise.
+       * sanopt.c (maybe_optimize_ubsan_ptr_ifn): Likewise.
+       * tsan.c (instrument_expr): Likewise.
+       * match.pd: Update call to ptr_difference_const.
+
 2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index d06ddffa0c95f9a9cef324faf9cf0a6923b5c2f4..13a0c80e43171238489f6c2aa02177cf2748021b 100644 (file)
@@ -1,3 +1,11 @@
+2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * gcc-interface/trans.c (Attribute_to_gnu): Track polynomial
+       offsets and sizes.
+       * gcc-interface/utils2.c (build_unary_op): Likewise.
+
 2017-12-20  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/trans.c (Loop_Statement_to_gnu): Use IN_RANGE macro.
index 9f34718f16d82801266d34b00928002674099513..587063b6e7735decb8008e9da115ebb22640a37f 100644 (file)
@@ -2187,8 +2187,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
     case Attr_Last_Bit:
     case Attr_Bit:
       {
-       HOST_WIDE_INT bitsize;
-       HOST_WIDE_INT bitpos;
+       poly_int64 bitsize;
+       poly_int64 bitpos;
        tree gnu_offset;
        tree gnu_field_bitpos;
        tree gnu_field_offset;
@@ -2255,11 +2255,11 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
 
          case Attr_First_Bit:
          case Attr_Bit:
-           gnu_result = size_int (bitpos % BITS_PER_UNIT);
+           gnu_result = size_int (num_trailing_bits (bitpos));
            break;
 
          case Attr_Last_Bit:
-           gnu_result = bitsize_int (bitpos % BITS_PER_UNIT);
+           gnu_result = bitsize_int (num_trailing_bits (bitpos));
            gnu_result = size_binop (PLUS_EXPR, gnu_result,
                                     TYPE_SIZE (TREE_TYPE (gnu_prefix)));
            /* ??? Avoid a large unsigned result that will overflow when
index dcd4134a434a25e9610f7630bfb009a2b96080bf..7f3a3d3ff1acc816ac864eee94a3a0e2df2fd7dd 100644 (file)
@@ -1439,8 +1439,8 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
               the offset to the field.  Otherwise, do this the normal way.  */
          if (op_code == ATTR_ADDR_EXPR)
            {
-             HOST_WIDE_INT bitsize;
-             HOST_WIDE_INT bitpos;
+             poly_int64 bitsize;
+             poly_int64 bitpos;
              tree offset, inner;
              machine_mode mode;
              int unsignedp, reversep, volatilep;
@@ -1460,8 +1460,9 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
              if (!offset)
                offset = size_zero_node;
 
-             offset = size_binop (PLUS_EXPR, offset,
-                                  size_int (bitpos / BITS_PER_UNIT));
+             offset
+               = size_binop (PLUS_EXPR, offset,
+                             size_int (bits_to_bytes_round_down (bitpos)));
 
              /* Take the address of INNER, convert it to a pointer to our type
                 and add the offset.  */
index e27338fda77074ec78bd568e9bb6228f64486100..144bfb3585589cf89c54790252a20df7c1934a3a 100644 (file)
@@ -2076,7 +2076,7 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
   if (size_in_bytes <= 0)
     return;
 
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos;
   tree offset;
   machine_mode mode;
   int unsignedp, reversep, volatilep = 0;
@@ -2094,19 +2094,19 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
       return;
     }
 
-  if (bitpos % BITS_PER_UNIT
-      || bitsize != size_in_bytes * BITS_PER_UNIT)
+  if (!multiple_p (bitpos, BITS_PER_UNIT)
+      || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT))
     return;
 
   if (VAR_P (inner) && DECL_HARD_REGISTER (inner))
     return;
 
+  poly_int64 decl_size;
   if (VAR_P (inner)
       && offset == NULL_TREE
-      && bitpos >= 0
       && DECL_SIZE (inner)
-      && tree_fits_shwi_p (DECL_SIZE (inner))
-      && bitpos + bitsize <= tree_to_shwi (DECL_SIZE (inner)))
+      && poly_int_tree_p (DECL_SIZE (inner), &decl_size)
+      && known_subrange_p (bitpos, bitsize, 0, decl_size))
     {
       if (DECL_THREAD_LOCAL_P (inner))
        return;
index f16a67b5e1f8a9473c2a6dd900170df150a19b35..8f2f6e09824e0b6bd2dfaf82ef1f9e4806198370 100644 (file)
@@ -17613,7 +17613,7 @@ r10k_safe_address_p (rtx x, rtx_insn *insn)
 static bool
 r10k_safe_mem_expr_p (tree expr, unsigned HOST_WIDE_INT offset)
 {
-  HOST_WIDE_INT bitoffset, bitsize;
+  poly_int64 bitoffset, bitsize;
   tree inner, var_offset;
   machine_mode mode;
   int unsigned_p, reverse_p, volatile_p;
index 77e18677c4fc8d2fd9eaccb4a2e875c78bef5c87..92a8ac6261355e2579206b3edb02d8b0df714768 100644 (file)
@@ -1,3 +1,10 @@
+2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * constexpr.c (check_automatic_or_tls): Track polynomial
+       offsets and sizes.
+
 2017-12-19  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/82593
index 518798e0c431819a9b8aef60035e37a5c5144643..6845ca407c1a9e2fdeec98755534ba435f2029fe 100644 (file)
@@ -5110,7 +5110,7 @@ static int
 check_automatic_or_tls (tree ref)
 {
   machine_mode mode;
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos;
   tree offset;
   int volatilep = 0, unsignedp = 0;
   tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
index 19827138ced9cad2ba4be4ba0785f98c448cb1a0..7c611ffc91abcb89426235b9bbd8efa88c3406d9 100644 (file)
@@ -2531,7 +2531,7 @@ dbxout_expand_expr (tree expr)
     case BIT_FIELD_REF:
       {
        machine_mode mode;
-       HOST_WIDE_INT bitsize, bitpos;
+       poly_int64 bitsize, bitpos;
        tree offset, tem;
        int unsignedp, reversep, volatilep = 0;
        rtx x;
@@ -2548,8 +2548,8 @@ dbxout_expand_expr (tree expr)
              return NULL;
            x = adjust_address_nv (x, mode, tree_to_shwi (offset));
          }
-       if (bitpos != 0)
-         x = adjust_address_nv (x, mode, bitpos / BITS_PER_UNIT);
+       if (maybe_ne (bitpos, 0))
+         x = adjust_address_nv (x, mode, bits_to_bytes_round_down (bitpos));
 
        return x;
       }
index 1fa76d08af105eac1c7c87a339e829685fe10465..018f5123259119038de2d214a7b934f0fa4696da 100644 (file)
@@ -16700,7 +16700,7 @@ loc_list_for_address_of_addr_expr_of_indirect_ref (tree loc, bool toplev,
                                                   loc_descr_context *context)
 {
   tree obj, offset;
-  HOST_WIDE_INT bitsize, bitpos, bytepos;
+  poly_int64 bitsize, bitpos, bytepos;
   machine_mode mode;
   int unsignedp, reversep, volatilep = 0;
   dw_loc_list_ref list_ret = NULL, list_ret1 = NULL;
@@ -16709,7 +16709,7 @@ loc_list_for_address_of_addr_expr_of_indirect_ref (tree loc, bool toplev,
                             &bitsize, &bitpos, &offset, &mode,
                             &unsignedp, &reversep, &volatilep);
   STRIP_NOPS (obj);
-  if (bitpos % BITS_PER_UNIT)
+  if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos))
     {
       expansion_failed (loc, NULL_RTX, "bitfield access");
       return 0;
@@ -16720,7 +16720,7 @@ loc_list_for_address_of_addr_expr_of_indirect_ref (tree loc, bool toplev,
                        NULL_RTX, "no indirect ref in inner refrence");
       return 0;
     }
-  if (!offset && !bitpos)
+  if (!offset && known_eq (bitpos, 0))
     list_ret = loc_list_from_tree (TREE_OPERAND (obj, 0), toplev ? 2 : 1,
                                   context);
   else if (toplev
@@ -16742,12 +16742,11 @@ loc_list_for_address_of_addr_expr_of_indirect_ref (tree loc, bool toplev,
          add_loc_descr_to_each (list_ret,
                                 new_loc_descr (DW_OP_plus, 0, 0));
        }
-      bytepos = bitpos / BITS_PER_UNIT;
-      if (bytepos > 0)
+      HOST_WIDE_INT value;
+      if (bytepos.is_constant (&value) && value > 0)
        add_loc_descr_to_each (list_ret,
-                              new_loc_descr (DW_OP_plus_uconst,
-                                             bytepos, 0));
-      else if (bytepos < 0)
+                              new_loc_descr (DW_OP_plus_uconst, value, 0));
+      else if (maybe_ne (bytepos, 0))
        loc_list_plus_const (list_ret, bytepos);
       add_loc_descr_to_each (list_ret,
                             new_loc_descr (DW_OP_stack_value, 0, 0));
@@ -17717,7 +17716,7 @@ loc_list_from_tree_1 (tree loc, int want_address,
     case IMAGPART_EXPR:
       {
        tree obj, offset;
-       HOST_WIDE_INT bitsize, bitpos, bytepos;
+       poly_int64 bitsize, bitpos, bytepos;
        machine_mode mode;
        int unsignedp, reversep, volatilep = 0;
 
@@ -17728,13 +17727,15 @@ loc_list_from_tree_1 (tree loc, int want_address,
 
        list_ret = loc_list_from_tree_1 (obj,
                                         want_address == 2
-                                        && !bitpos && !offset ? 2 : 1,
+                                        && known_eq (bitpos, 0)
+                                        && !offset ? 2 : 1,
                                         context);
        /* TODO: We can extract value of the small expression via shifting even
           for nonzero bitpos.  */
        if (list_ret == 0)
          return 0;
-       if (bitpos % BITS_PER_UNIT != 0 || bitsize % BITS_PER_UNIT != 0)
+       if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
+           || !multiple_p (bitsize, BITS_PER_UNIT))
          {
            expansion_failed (loc, NULL_RTX,
                              "bitfield access");
@@ -17753,10 +17754,11 @@ loc_list_from_tree_1 (tree loc, int want_address,
            add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_plus, 0, 0));
          }
 
-       bytepos = bitpos / BITS_PER_UNIT;
-       if (bytepos > 0)
-         add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_plus_uconst, bytepos, 0));
-       else if (bytepos < 0)
+       HOST_WIDE_INT value;
+       if (bytepos.is_constant (&value) && value > 0)
+         add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_plus_uconst,
+                                                         value, 0));
+       else if (maybe_ne (bytepos, 0))
          loc_list_plus_const (list_ret, bytepos);
 
        have_address = 1;
@@ -19286,8 +19288,9 @@ fortran_common (tree decl, HOST_WIDE_INT *value)
 {
   tree val_expr, cvar;
   machine_mode mode;
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos;
   tree offset;
+  HOST_WIDE_INT cbitpos;
   int unsignedp, reversep, volatilep = 0;
 
   /* If the decl isn't a VAR_DECL, or if it isn't static, or if
@@ -19310,7 +19313,10 @@ fortran_common (tree decl, HOST_WIDE_INT *value)
   if (cvar == NULL_TREE
       || !VAR_P (cvar)
       || DECL_ARTIFICIAL (cvar)
-      || !TREE_PUBLIC (cvar))
+      || !TREE_PUBLIC (cvar)
+      /* We don't expect to have to cope with variable offsets,
+        since at present all static data must have a constant size.  */
+      || !bitpos.is_constant (&cbitpos))
     return NULL_TREE;
 
   *value = 0;
@@ -19320,8 +19326,8 @@ fortran_common (tree decl, HOST_WIDE_INT *value)
        return NULL_TREE;
       *value = tree_to_shwi (offset);
     }
-  if (bitpos != 0)
-    *value += bitpos / BITS_PER_UNIT;
+  if (cbitpos != 0)
+    *value += cbitpos / BITS_PER_UNIT;
 
   return cvar;
 }
index 372b5fc84a06cec55f07dcc141dad9e7ec20e5c0..4d146f9e2bad101ac5ad89059086b2f5a75874ed 100644 (file)
@@ -7038,8 +7038,8 @@ store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos,
    this case, but the address of the object can be found.  */
 
 tree
-get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
-                    HOST_WIDE_INT *pbitpos, tree *poffset,
+get_inner_reference (tree exp, poly_int64_pod *pbitsize,
+                    poly_int64_pod *pbitpos, tree *poffset,
                     machine_mode *pmode, int *punsignedp,
                     int *preversep, int *pvolatilep)
 {
@@ -7047,7 +7047,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
   machine_mode mode = VOIDmode;
   bool blkmode_bitfield = false;
   tree offset = size_zero_node;
-  offset_int bit_offset = 0;
+  poly_offset_int bit_offset = 0;
 
   /* First get the mode, signedness, storage order and size.  We do this from
      just the outermost expression.  */
@@ -7121,7 +7121,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
       switch (TREE_CODE (exp))
        {
        case BIT_FIELD_REF:
-         bit_offset += wi::to_offset (TREE_OPERAND (exp, 2));
+         bit_offset += wi::to_poly_offset (TREE_OPERAND (exp, 2));
          break;
 
        case COMPONENT_REF:
@@ -7136,7 +7136,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
              break;
 
            offset = size_binop (PLUS_EXPR, offset, this_offset);
-           bit_offset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
+           bit_offset += wi::to_poly_offset (DECL_FIELD_BIT_OFFSET (field));
 
            /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN.  */
          }
@@ -7204,44 +7204,36 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
   /* If OFFSET is constant, see if we can return the whole thing as a
      constant bit position.  Make sure to handle overflow during
      this conversion.  */
-  if (TREE_CODE (offset) == INTEGER_CST)
+  if (poly_int_tree_p (offset))
     {
-      offset_int tem = wi::sext (wi::to_offset (offset),
-                                TYPE_PRECISION (sizetype));
+      poly_offset_int tem = wi::sext (wi::to_poly_offset (offset),
+                                     TYPE_PRECISION (sizetype));
       tem <<= LOG2_BITS_PER_UNIT;
       tem += bit_offset;
-      if (wi::fits_shwi_p (tem))
-       {
-         *pbitpos = tem.to_shwi ();
-         *poffset = offset = NULL_TREE;
-       }
+      if (tem.to_shwi (pbitpos))
+       *poffset = offset = NULL_TREE;
     }
 
   /* Otherwise, split it up.  */
   if (offset)
     {
       /* Avoid returning a negative bitpos as this may wreak havoc later.  */
-      if (wi::neg_p (bit_offset) || !wi::fits_shwi_p (bit_offset))
+      if (!bit_offset.to_shwi (pbitpos) || maybe_lt (*pbitpos, 0))
         {
-         offset_int mask = wi::mask <offset_int> (LOG2_BITS_PER_UNIT, false);
-         offset_int tem = wi::bit_and_not (bit_offset, mask);
-         /* TEM is the bitpos rounded to BITS_PER_UNIT towards -Inf.
-            Subtract it to BIT_OFFSET and add it (scaled) to OFFSET.  */
-         bit_offset -= tem;
-         tem >>= LOG2_BITS_PER_UNIT;
+         *pbitpos = num_trailing_bits (bit_offset.force_shwi ());
+         poly_offset_int bytes = bits_to_bytes_round_down (bit_offset);
          offset = size_binop (PLUS_EXPR, offset,
-                              wide_int_to_tree (sizetype, tem));
+                              build_int_cst (sizetype, bytes.force_shwi ()));
        }
 
-      *pbitpos = bit_offset.to_shwi ();
       *poffset = offset;
     }
 
   /* We can use BLKmode for a byte-aligned BLKmode bitfield.  */
   if (mode == VOIDmode
       && blkmode_bitfield
-      && (*pbitpos % BITS_PER_UNIT) == 0
-      && (*pbitsize % BITS_PER_UNIT) == 0)
+      && multiple_p (*pbitpos, BITS_PER_UNIT)
+      && multiple_p (*pbitsize, BITS_PER_UNIT))
     *pmode = BLKmode;
   else
     *pmode = mode;
@@ -7777,7 +7769,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
 {
   rtx result, subtarget;
   tree inner, offset;
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos;
   int unsignedp, reversep, volatilep = 0;
   machine_mode mode1;
 
@@ -7893,7 +7885,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
   /* We must have made progress.  */
   gcc_assert (inner != exp);
 
-  subtarget = offset || bitpos ? NULL_RTX : target;
+  subtarget = offset || maybe_ne (bitpos, 0) ? NULL_RTX : target;
   /* For VIEW_CONVERT_EXPR, where the outer alignment is bigger than
      inner alignment, force the inner to be sufficiently aligned.  */
   if (CONSTANT_CLASS_P (inner)
@@ -7928,20 +7920,19 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
        result = simplify_gen_binary (PLUS, tmode, result, tmp);
       else
        {
-         subtarget = bitpos ? NULL_RTX : target;
+         subtarget = maybe_ne (bitpos, 0) ? NULL_RTX : target;
          result = expand_simple_binop (tmode, PLUS, result, tmp, subtarget,
                                        1, OPTAB_LIB_WIDEN);
        }
     }
 
-  if (bitpos)
+  if (maybe_ne (bitpos, 0))
     {
       /* Someone beforehand should have rejected taking the address
-        of such an object.  */
-      gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
-
+        of an object that isn't byte-aligned.  */
+      poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
       result = convert_memory_address_addr_space (tmode, result, as);
-      result = plus_constant (tmode, result, bitpos / BITS_PER_UNIT);
+      result = plus_constant (tmode, result, bytepos);
       if (modifier < EXPAND_SUM)
        result = force_operand (result, target);
     }
@@ -10496,7 +10487,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
     normal_inner_ref:
       {
        machine_mode mode1, mode2;
-       HOST_WIDE_INT bitsize, bitpos;
+       poly_int64 bitsize, bitpos, bytepos;
        tree offset;
        int reversep, volatilep = 0, must_force_mem;
        tree tem
@@ -10549,13 +10540,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
           to a larger size.  */
        must_force_mem = (offset
                          || mode1 == BLKmode
-                         || bitpos + bitsize > GET_MODE_BITSIZE (mode2));
+                         || maybe_gt (bitpos + bitsize,
+                                      GET_MODE_BITSIZE (mode2)));
 
        /* Handle CONCAT first.  */
        if (GET_CODE (op0) == CONCAT && !must_force_mem)
          {
-           if (bitpos == 0
-               && bitsize == GET_MODE_BITSIZE (GET_MODE (op0))
+           if (known_eq (bitpos, 0)
+               && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
                && COMPLEX_MODE_P (mode1)
                && COMPLEX_MODE_P (GET_MODE (op0))
                && (GET_MODE_PRECISION (GET_MODE_INNER (mode1))
@@ -10587,17 +10579,20 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
                  }
                return op0;
              }
-           if (bitpos == 0
-               && bitsize == GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
-               && bitsize)
+           if (known_eq (bitpos, 0)
+               && known_eq (bitsize,
+                            GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
+               && maybe_ne (bitsize, 0))
              {
                op0 = XEXP (op0, 0);
                mode2 = GET_MODE (op0);
              }
-           else if (bitpos == GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
-                    && bitsize == GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1)))
-                    && bitpos
-                    && bitsize)
+           else if (known_eq (bitpos,
+                              GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
+                    && known_eq (bitsize,
+                                 GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1))))
+                    && maybe_ne (bitpos, 0)
+                    && maybe_ne (bitsize, 0))
              {
                op0 = XEXP (op0, 1);
                bitpos = 0;
@@ -10652,13 +10647,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 
            /* See the comment in expand_assignment for the rationale.  */
            if (mode1 != VOIDmode
-               && bitpos != 0
-               && bitsize > 0
-               && (bitpos % bitsize) == 0
-               && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
+               && maybe_ne (bitpos, 0)
+               && maybe_gt (bitsize, 0)
+               && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
+               && multiple_p (bitpos, bitsize)
+               && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
                && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode1))
              {
-               op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
+               op0 = adjust_address (op0, mode1, bytepos);
                bitpos = 0;
              }
 
@@ -10668,7 +10664,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 
        /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
           record its alignment as BIGGEST_ALIGNMENT.  */
-       if (MEM_P (op0) && bitpos == 0 && offset != 0
+       if (MEM_P (op0)
+           && known_eq (bitpos, 0)
+           && offset != 0
            && is_aligning_offset (offset, tem))
          set_mem_align (op0, BIGGEST_ALIGNMENT);
 
@@ -10701,37 +10699,37 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
            || (volatilep && TREE_CODE (exp) == COMPONENT_REF
                && DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1))
                && mode1 != BLKmode
-               && bitsize < GET_MODE_SIZE (mode1) * BITS_PER_UNIT)
+               && maybe_lt (bitsize, GET_MODE_SIZE (mode1) * BITS_PER_UNIT))
            /* If the field isn't aligned enough to fetch as a memref,
               fetch it as a bit field.  */
            || (mode1 != BLKmode
                && (((MEM_P (op0)
                      ? MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
-                       || (bitpos % GET_MODE_ALIGNMENT (mode1) != 0)
+                       || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode1))
                      : TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
-                       || (bitpos % GET_MODE_ALIGNMENT (mode) != 0))
+                       || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
                     && modifier != EXPAND_MEMORY
                     && ((modifier == EXPAND_CONST_ADDRESS
                          || modifier == EXPAND_INITIALIZER)
                         ? STRICT_ALIGNMENT
                         : targetm.slow_unaligned_access (mode1,
                                                          MEM_ALIGN (op0))))
-                   || (bitpos % BITS_PER_UNIT != 0)))
+                   || !multiple_p (bitpos, BITS_PER_UNIT)))
            /* If the type and the field are a constant size and the
               size of the type isn't the same size as the bitfield,
               we must use bitfield operations.  */
-           || (bitsize >= 0
+           || (known_size_p (bitsize)
                && TYPE_SIZE (TREE_TYPE (exp))
-               && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST
-               && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)),
-                                    bitsize) != 0))
+               && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
+               && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
+                            bitsize)))
          {
            machine_mode ext_mode = mode;
 
            if (ext_mode == BLKmode
                && ! (target != 0 && MEM_P (op0)
                      && MEM_P (target)
-                     && bitpos % BITS_PER_UNIT == 0))
+                     && multiple_p (bitpos, BITS_PER_UNIT)))
              ext_mode = int_mode_for_size (bitsize, 1).else_blk ();
 
            if (ext_mode == BLKmode)
@@ -10741,20 +10739,19 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 
                /* ??? Unlike the similar test a few lines below, this one is
                   very likely obsolete.  */
-               if (bitsize == 0)
+               if (known_eq (bitsize, 0))
                  return target;
 
                /* In this case, BITPOS must start at a byte boundary and
                   TARGET, if specified, must be a MEM.  */
                gcc_assert (MEM_P (op0)
-                           && (!target || MEM_P (target))
-                           && !(bitpos % BITS_PER_UNIT));
+                           && (!target || MEM_P (target)));
 
+               bytepos = exact_div (bitpos, BITS_PER_UNIT);
+               poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
                emit_block_move (target,
-                                adjust_address (op0, VOIDmode,
-                                                bitpos / BITS_PER_UNIT),
-                                GEN_INT ((bitsize + BITS_PER_UNIT - 1)
-                                         / BITS_PER_UNIT),
+                                adjust_address (op0, VOIDmode, bytepos),
+                                gen_int_mode (bytesize, Pmode),
                                 (modifier == EXPAND_STACK_PARM
                                  ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
 
@@ -10765,7 +10762,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
               with SHIFT_COUNT_TRUNCATED == 0 and garbage otherwise.  Always
               return 0 for the sake of consistency, as reading a zero-sized
               bitfield is valid in Ada and the value is fully specified.  */
-           if (bitsize == 0)
+           if (known_eq (bitsize, 0))
              return const0_rtx;
 
            op0 = validize_mem (op0);
@@ -10798,7 +10795,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
              {
                HOST_WIDE_INT size = GET_MODE_BITSIZE (op0_mode);
 
-               if (bitsize < size
+               gcc_checking_assert (known_le (bitsize, size));
+               if (maybe_lt (bitsize, size)
                    && reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
                  op0 = expand_shift (LSHIFT_EXPR, op0_mode, op0,
                                      size - bitsize, op0, 1);
@@ -10830,11 +10828,12 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
          mode1 = BLKmode;
 
        /* Get a reference to just this component.  */
+       bytepos = bits_to_bytes_round_down (bitpos);
        if (modifier == EXPAND_CONST_ADDRESS
            || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
-         op0 = adjust_address_nv (op0, mode1, bitpos / BITS_PER_UNIT);
+         op0 = adjust_address_nv (op0, mode1, bytepos);
        else
-         op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
+         op0 = adjust_address (op0, mode1, bytepos);
 
        if (op0 == orig_op0)
          op0 = copy_rtx (op0);
@@ -10917,12 +10916,12 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
       /* If we are converting to BLKmode, try to avoid an intermediate
         temporary by fetching an inner memory reference.  */
       if (mode == BLKmode
-         && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+         && poly_int_tree_p (TYPE_SIZE (type))
          && TYPE_MODE (TREE_TYPE (treeop0)) != BLKmode
          && handled_component_p (treeop0))
       {
        machine_mode mode1;
-       HOST_WIDE_INT bitsize, bitpos;
+       poly_int64 bitsize, bitpos, bytepos;
        tree offset;
        int unsignedp, reversep, volatilep = 0;
        tree tem
@@ -10932,10 +10931,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 
        /* ??? We should work harder and deal with non-zero offsets.  */
        if (!offset
-           && (bitpos % BITS_PER_UNIT) == 0
+           && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
            && !reversep
-           && bitsize >= 0
-           && compare_tree_int (TYPE_SIZE (type), bitsize) == 0)
+           && known_size_p (bitsize)
+           && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize))
          {
            /* See the normal_inner_ref case for the rationale.  */
            orig_op0
@@ -10957,9 +10956,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
                if (modifier == EXPAND_CONST_ADDRESS
                    || modifier == EXPAND_SUM
                    || modifier == EXPAND_INITIALIZER)
-                 op0 = adjust_address_nv (op0, mode, bitpos / BITS_PER_UNIT);
+                 op0 = adjust_address_nv (op0, mode, bytepos);
                else
-                 op0 = adjust_address (op0, mode, bitpos / BITS_PER_UNIT);
+                 op0 = adjust_address (op0, mode, bytepos);
 
                if (op0 == orig_op0)
                  op0 = copy_rtx (op0);
index d0a069c32cbf0f513cdca3ee9f8846bbcc825429..2039d4dd2f9e3deab1a8cad4d6639cf36347d541 100644 (file)
@@ -3950,7 +3950,7 @@ invert_truthvalue_loc (location_t loc, tree arg)
 
 static tree
 make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type,
-                   HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
+                   HOST_WIDE_INT bitsize, poly_int64 bitpos,
                    int unsignedp, int reversep)
 {
   tree result, bftype;
@@ -3960,7 +3960,7 @@ make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type,
     {
       tree ninner = TREE_OPERAND (orig_inner, 0);
       machine_mode nmode;
-      HOST_WIDE_INT nbitsize, nbitpos;
+      poly_int64 nbitsize, nbitpos;
       tree noffset;
       int nunsignedp, nreversep, nvolatilep = 0;
       tree base = get_inner_reference (ninner, &nbitsize, &nbitpos,
@@ -3968,9 +3968,7 @@ make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type,
                                       &nreversep, &nvolatilep);
       if (base == inner
          && noffset == NULL_TREE
-         && nbitsize >= bitsize
-         && nbitpos <= bitpos
-         && bitpos + bitsize <= nbitpos + nbitsize
+         && known_subrange_p (bitpos, bitsize, nbitpos, nbitsize)
          && !reversep
          && !nreversep
          && !nvolatilep)
@@ -3986,7 +3984,7 @@ make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type,
                         build_fold_addr_expr (inner),
                         build_int_cst (ptr_type_node, 0));
 
-  if (bitpos == 0 && !reversep)
+  if (known_eq (bitpos, 0) && !reversep)
     {
       tree size = TYPE_SIZE (TREE_TYPE (inner));
       if ((INTEGRAL_TYPE_P (TREE_TYPE (inner))
@@ -4035,7 +4033,8 @@ static tree
 optimize_bit_field_compare (location_t loc, enum tree_code code,
                            tree compare_type, tree lhs, tree rhs)
 {
-  HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
+  poly_int64 plbitpos, plbitsize, rbitpos, rbitsize;
+  HOST_WIDE_INT lbitpos, lbitsize, nbitpos, nbitsize;
   tree type = TREE_TYPE (lhs);
   tree unsigned_type;
   int const_p = TREE_CODE (rhs) == INTEGER_CST;
@@ -4049,14 +4048,20 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
   tree offset;
 
   /* Get all the information about the extractions being done.  If the bit size
-     if the same as the size of the underlying object, we aren't doing an
+     is the same as the size of the underlying object, we aren't doing an
      extraction at all and so can do nothing.  We also don't want to
      do anything if the inner expression is a PLACEHOLDER_EXPR since we
      then will no longer be able to replace it.  */
-  linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
+  linner = get_inner_reference (lhs, &plbitsize, &plbitpos, &offset, &lmode,
                                &lunsignedp, &lreversep, &lvolatilep);
-  if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
-      || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR || lvolatilep)
+  if (linner == lhs
+      || !known_size_p (plbitsize)
+      || !plbitsize.is_constant (&lbitsize)
+      || !plbitpos.is_constant (&lbitpos)
+      || lbitsize == GET_MODE_BITSIZE (lmode)
+      || offset != 0
+      || TREE_CODE (linner) == PLACEHOLDER_EXPR
+      || lvolatilep)
     return 0;
 
   if (const_p)
@@ -4069,9 +4074,14 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
        = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
                              &runsignedp, &rreversep, &rvolatilep);
 
-     if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
-        || lunsignedp != runsignedp || lreversep != rreversep || offset != 0
-        || TREE_CODE (rinner) == PLACEHOLDER_EXPR || rvolatilep)
+     if (rinner == rhs
+        || maybe_ne (lbitpos, rbitpos)
+        || maybe_ne (lbitsize, rbitsize)
+        || lunsignedp != runsignedp
+        || lreversep != rreversep
+        || offset != 0
+        || TREE_CODE (rinner) == PLACEHOLDER_EXPR
+        || rvolatilep)
        return 0;
    }
 
@@ -4080,7 +4090,6 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
   poly_uint64 bitend = 0;
   if (TREE_CODE (lhs) == COMPONENT_REF)
     {
-      poly_int64 plbitpos;
       get_bit_range (&bitstart, &bitend, lhs, &plbitpos, &offset);
       if (!plbitpos.is_constant (&lbitpos) || offset != NULL_TREE)
        return 0;
@@ -4250,10 +4259,14 @@ decode_field_reference (location_t loc, tree *exp_, HOST_WIDE_INT *pbitsize,
        return 0;
     }
 
-  inner = get_inner_reference (exp, pbitsize, pbitpos, &offset, pmode,
-                              punsignedp, preversep, pvolatilep);
+  poly_int64 poly_bitsize, poly_bitpos;
+  inner = get_inner_reference (exp, &poly_bitsize, &poly_bitpos, &offset,
+                              pmode, punsignedp, preversep, pvolatilep);
   if ((inner == exp && and_mask == 0)
-      || *pbitsize < 0 || offset != 0
+      || !poly_bitsize.is_constant (pbitsize)
+      || !poly_bitpos.is_constant (pbitpos)
+      || *pbitsize < 0
+      || offset != 0
       || TREE_CODE (inner) == PLACEHOLDER_EXPR
       /* Reject out-of-bound accesses (PR79731).  */
       || (! AGGREGATE_TYPE_P (TREE_TYPE (inner))
@@ -7819,7 +7832,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
          && POINTER_TYPE_P (type)
          && handled_component_p (TREE_OPERAND (op0, 0)))
         {
-         HOST_WIDE_INT bitsize, bitpos;
+         poly_int64 bitsize, bitpos;
          tree offset;
          machine_mode mode;
          int unsignedp, reversep, volatilep;
@@ -7830,7 +7843,8 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
          /* If the reference was to a (constant) zero offset, we can use
             the address of the base if it has the same base type
             as the result type and the pointer type is unqualified.  */
-         if (! offset && bitpos == 0
+         if (!offset
+             && known_eq (bitpos, 0)
              && (TYPE_MAIN_VARIANT (TREE_TYPE (type))
                  == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
              && TYPE_QUALS (type) == TYPE_UNQUALIFIED)
@@ -14351,12 +14365,12 @@ round_down_loc (location_t loc, tree value, int divisor)
 
 static tree
 split_address_to_core_and_offset (tree exp,
-                                 HOST_WIDE_INT *pbitpos, tree *poffset)
+                                 poly_int64_pod *pbitpos, tree *poffset)
 {
   tree core;
   machine_mode mode;
   int unsignedp, reversep, volatilep;
-  HOST_WIDE_INT bitsize;
+  poly_int64 bitsize;
   location_t loc = EXPR_LOCATION (exp);
 
   if (TREE_CODE (exp) == ADDR_EXPR)
@@ -14372,16 +14386,14 @@ split_address_to_core_and_offset (tree exp,
       STRIP_NOPS (core);
       *pbitpos = 0;
       *poffset = TREE_OPERAND (exp, 1);
-      if (TREE_CODE (*poffset) == INTEGER_CST)
+      if (poly_int_tree_p (*poffset))
        {
-         offset_int tem = wi::sext (wi::to_offset (*poffset),
-                                    TYPE_PRECISION (TREE_TYPE (*poffset)));
+         poly_offset_int tem
+           = wi::sext (wi::to_poly_offset (*poffset),
+                       TYPE_PRECISION (TREE_TYPE (*poffset)));
          tem <<= LOG2_BITS_PER_UNIT;
-         if (wi::fits_shwi_p (tem))
-           {
-             *pbitpos = tem.to_shwi ();
-             *poffset = NULL_TREE;
-           }
+         if (tem.to_shwi (pbitpos))
+           *poffset = NULL_TREE;
        }
     }
   else
@@ -14398,17 +14410,18 @@ split_address_to_core_and_offset (tree exp,
    otherwise.  If they do, E1 - E2 is stored in *DIFF.  */
 
 bool
-ptr_difference_const (tree e1, tree e2, HOST_WIDE_INT *diff)
+ptr_difference_const (tree e1, tree e2, poly_int64_pod *diff)
 {
   tree core1, core2;
-  HOST_WIDE_INT bitpos1, bitpos2;
+  poly_int64 bitpos1, bitpos2;
   tree toffset1, toffset2, tdiff, type;
 
   core1 = split_address_to_core_and_offset (e1, &bitpos1, &toffset1);
   core2 = split_address_to_core_and_offset (e2, &bitpos2, &toffset2);
 
-  if (bitpos1 % BITS_PER_UNIT != 0
-      || bitpos2 % BITS_PER_UNIT != 0
+  poly_int64 bytepos1, bytepos2;
+  if (!multiple_p (bitpos1, BITS_PER_UNIT, &bytepos1)
+      || !multiple_p (bitpos2, BITS_PER_UNIT, &bytepos2)
       || !operand_equal_p (core1, core2, 0))
     return false;
 
@@ -14433,7 +14446,7 @@ ptr_difference_const (tree e1, tree e2, HOST_WIDE_INT *diff)
   else
     *diff = 0;
 
-  *diff += (bitpos1 - bitpos2) / BITS_PER_UNIT;
+  *diff += bytepos1 - bytepos2;
   return true;
 }
 
index 73a8764d7ce765f6900e298bc216f7c0b1b72e93..256dc6ffb350d5c89bae401431c41dac1d60da98 100644 (file)
@@ -122,7 +122,7 @@ extern tree div_if_zero_remainder (const_tree, const_tree);
 extern bool tree_swap_operands_p (const_tree, const_tree);
 extern enum tree_code swap_tree_comparison (enum tree_code);
 
-extern bool ptr_difference_const (tree, tree, HOST_WIDE_INT *);
+extern bool ptr_difference_const (tree, tree, poly_int64_pod *);
 extern enum tree_code invert_tree_comparison (enum tree_code, bool);
 
 extern bool tree_unary_nonzero_warnv_p (enum tree_code, tree, tree, bool *);
index 8e07e30b11a1226370fe2ca0132e4c7a0d6c5a5c..690e1f587084b66657f4dcf94ed384570d8f32e5 100644 (file)
@@ -100,19 +100,19 @@ pass_laddress::execute (function *fun)
          */
 
          tree expr = gimple_assign_rhs1 (stmt);
-         HOST_WIDE_INT bitsize, bitpos;
+         poly_int64 bitsize, bitpos;
          tree base, offset;
          machine_mode mode;
          int volatilep = 0, reversep, unsignedp = 0;
          base = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize,
                                      &bitpos, &offset, &mode, &unsignedp,
                                      &reversep, &volatilep);
-         gcc_assert (base != NULL_TREE && (bitpos % BITS_PER_UNIT) == 0);
+         gcc_assert (base != NULL_TREE);
+         poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
          if (offset != NULL_TREE)
            {
-             if (bitpos != 0)
-               offset = size_binop (PLUS_EXPR, offset,
-                                    size_int (bitpos / BITS_PER_UNIT));
+             if (maybe_ne (bytepos, 0))
+               offset = size_binop (PLUS_EXPR, offset, size_int (bytepos));
              offset = force_gimple_operand_gsi (&gsi, offset, true, NULL,
                                                 true, GSI_SAME_STMT);
              base = build_fold_addr_expr (base);
index 078acca82122df084932c7744b0c5b87a079184f..dddafb7bf2739bbfd53d5ea7f76ceb1e1d53fd33 100644 (file)
@@ -354,7 +354,7 @@ find_bswap_or_nop_load (gimple *stmt, tree ref, struct symbolic_number *n)
 {
   /* Leaf node is an array or component ref. Memorize its base and
      offset from base to compare to other such leaf node.  */
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos, bytepos;
   machine_mode mode;
   int unsignedp, reversep, volatilep;
   tree offset, base_addr;
@@ -407,9 +407,9 @@ find_bswap_or_nop_load (gimple *stmt, tree ref, struct symbolic_number *n)
   else
     base_addr = build_fold_addr_expr (base_addr);
 
-  if (bitpos % BITS_PER_UNIT)
+  if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos))
     return false;
-  if (bitsize % BITS_PER_UNIT)
+  if (!multiple_p (bitsize, BITS_PER_UNIT))
     return false;
   if (reversep)
     return false;
@@ -418,7 +418,7 @@ find_bswap_or_nop_load (gimple *stmt, tree ref, struct symbolic_number *n)
     return false;
   n->base_addr = base_addr;
   n->offset = offset;
-  n->bytepos = bitpos / BITS_PER_UNIT;
+  n->bytepos = bytepos;
   n->alias_set = reference_alias_ptr_type (ref);
   n->vuse = gimple_vuse (stmt);
   return true;
index 45ddfc4d76374c08e46bffc81088c7aa28b96ddf..7d8543c28ca9ca13737137b409fc5781fb2165cf 100644 (file)
@@ -1031,7 +1031,7 @@ static void
 slsr_process_ref (gimple *gs)
 {
   tree ref_expr, base, offset, type;
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos;
   machine_mode mode;
   int unsignedp, reversep, volatilep;
   slsr_cand_t c;
@@ -1049,9 +1049,10 @@ slsr_process_ref (gimple *gs)
 
   base = get_inner_reference (ref_expr, &bitsize, &bitpos, &offset, &mode,
                              &unsignedp, &reversep, &volatilep);
-  if (reversep)
+  HOST_WIDE_INT cbitpos;
+  if (reversep || !bitpos.is_constant (&cbitpos))
     return;
-  widest_int index = bitpos;
+  widest_int index = cbitpos;
 
   if (!restructure_reference (&base, &offset, &index, &type))
     return;
index 947580759e3e8b5dcbe7a9b6f0c42a9fb4d657e1..eb4ad967d0d7b6b362a5d74a2e556050e01d37ae 100644 (file)
@@ -7972,7 +7972,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                    }
 
                  tree offset;
-                 HOST_WIDE_INT bitsize, bitpos;
+                 poly_int64 bitsize, bitpos;
                  machine_mode mode;
                  int unsignedp, reversep, volatilep = 0;
                  tree base = OMP_CLAUSE_DECL (c);
@@ -7993,7 +7993,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                    base = TREE_OPERAND (base, 0);
                  gcc_assert (base == decl
                              && (offset == NULL_TREE
-                                 || TREE_CODE (offset) == INTEGER_CST));
+                                 || poly_int_tree_p (offset)));
 
                  splay_tree_node n
                    = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
@@ -8072,13 +8072,13 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                      tree *sc = NULL, *scp = NULL;
                      if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
                        n->value |= GOVD_SEEN;
-                     offset_int o1, o2;
+                     poly_offset_int o1, o2;
                      if (offset)
-                       o1 = wi::to_offset (offset);
+                       o1 = wi::to_poly_offset (offset);
                      else
                        o1 = 0;
-                     if (bitpos)
-                       o1 = o1 + bitpos / BITS_PER_UNIT;
+                     if (maybe_ne (bitpos, 0))
+                       o1 += bits_to_bytes_round_down (bitpos);
                      sc = &OMP_CLAUSE_CHAIN (*osc);
                      if (*sc != c
                          && (OMP_CLAUSE_MAP_KIND (*sc)
@@ -8097,7 +8097,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                        else
                          {
                            tree offset2;
-                           HOST_WIDE_INT bitsize2, bitpos2;
+                           poly_int64 bitsize2, bitpos2;
                            base = OMP_CLAUSE_DECL (*sc);
                            if (TREE_CODE (base) == ARRAY_REF)
                              {
@@ -8133,7 +8133,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                            if (scp)
                              continue;
                            gcc_assert (offset == NULL_TREE
-                                       || TREE_CODE (offset) == INTEGER_CST);
+                                       || poly_int_tree_p (offset));
                            tree d1 = OMP_CLAUSE_DECL (*sc);
                            tree d2 = OMP_CLAUSE_DECL (c);
                            while (TREE_CODE (d1) == ARRAY_REF)
@@ -8163,13 +8163,13 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                                break;
                              }
                            if (offset2)
-                             o2 = wi::to_offset (offset2);
+                             o2 = wi::to_poly_offset (offset2);
                            else
                              o2 = 0;
-                           if (bitpos2)
-                             o2 = o2 + bitpos2 / BITS_PER_UNIT;
-                           if (wi::ltu_p (o1, o2)
-                               || (wi::eq_p (o1, o2) && bitpos < bitpos2))
+                           o2 += bits_to_bytes_round_down (bitpos2);
+                           if (maybe_lt (o1, o2)
+                               || (known_eq (o1, 2)
+                                   && maybe_lt (bitpos, bitpos2)))
                              {
                                if (ptr)
                                  scp = sc;
index 70f715ec8fe24ea27505cf8d730588424a566eb0..9284a3cceba2c91cae8e831d346b305763948234 100644 (file)
@@ -1972,12 +1972,22 @@ gen_hsa_addr (tree ref, hsa_bb *hbb, HOST_WIDE_INT *output_bitsize = NULL,
     {
       machine_mode mode;
       int unsignedp, volatilep, preversep;
-
-      ref = get_inner_reference (ref, &bitsize, &bitpos, &varoffset, &mode,
-                                &unsignedp, &preversep, &volatilep);
-
-      offset = bitpos;
-      offset = wi::rshift (offset, LOG2_BITS_PER_UNIT, SIGNED);
+      poly_int64 pbitsize, pbitpos;
+      tree new_ref;
+
+      new_ref = get_inner_reference (ref, &pbitsize, &pbitpos, &varoffset,
+                                    &mode, &unsignedp, &preversep,
+                                    &volatilep);
+      /* When this isn't true, the switch below will report an
+        appropriate error.  */
+      if (pbitsize.is_constant () && pbitpos.is_constant ())
+       {
+         bitsize = pbitsize.to_constant ();
+         bitpos = pbitpos.to_constant ();
+         ref = new_ref;
+         offset = bitpos;
+         offset = wi::rshift (offset, LOG2_BITS_PER_UNIT, SIGNED);
+       }
     }
 
   switch (TREE_CODE (ref))
index 7a7cb90ad17280ba65460fe5629c352ab9fa6651..ec99250f1c5ca403814006792c0754f378b534cb 100644 (file)
@@ -1561,27 +1561,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (simplify
  (minus (convert ADDR_EXPR@0) (convert @1))
  (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
-  (with { HOST_WIDE_INT diff; }
+  (with { poly_int64 diff; }
    (if (ptr_difference_const (@0, @1, &diff))
     { build_int_cst_type (type, diff); }))))
 (simplify
  (minus (convert @0) (convert ADDR_EXPR@1))
  (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
-  (with { HOST_WIDE_INT diff; }
+  (with { poly_int64 diff; }
    (if (ptr_difference_const (@0, @1, &diff))
     { build_int_cst_type (type, diff); }))))
 (simplify
  (pointer_diff (convert?@2 ADDR_EXPR@0) (convert?@3 @1))
  (if (tree_nop_conversion_p (TREE_TYPE(@2), TREE_TYPE (@0))
       && tree_nop_conversion_p (TREE_TYPE(@3), TREE_TYPE (@1)))
-  (with { HOST_WIDE_INT diff; }
+  (with { poly_int64 diff; }
    (if (ptr_difference_const (@0, @1, &diff))
     { build_int_cst_type (type, diff); }))))
 (simplify
  (pointer_diff (convert?@2 @0) (convert?@3 ADDR_EXPR@1))
  (if (tree_nop_conversion_p (TREE_TYPE(@2), TREE_TYPE (@0))
       && tree_nop_conversion_p (TREE_TYPE(@3), TREE_TYPE (@1)))
-  (with { HOST_WIDE_INT diff; }
+  (with { poly_int64 diff; }
    (if (ptr_difference_const (@0, @1, &diff))
     { build_int_cst_type (type, diff); }))))
 
index 997bcfd3df71fc058524e5456caac1314066afea..d726c5e65e9efa24b54f214d03c533b1aac927dc 100644 (file)
@@ -459,7 +459,7 @@ record_ubsan_ptr_check_stmt (sanopt_ctx *ctx, gimple *stmt, tree ptr,
 static bool
 maybe_optimize_ubsan_ptr_ifn (sanopt_ctx *ctx, gimple *stmt)
 {
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, pbitpos;
   machine_mode mode;
   int volatilep = 0, reversep, unsignedp = 0;
   tree offset;
@@ -483,9 +483,12 @@ maybe_optimize_ubsan_ptr_ifn (sanopt_ctx *ctx, gimple *stmt)
     {
       base = TREE_OPERAND (base, 0);
 
-      base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
+      HOST_WIDE_INT bitpos;
+      base = get_inner_reference (base, &bitsize, &pbitpos, &offset, &mode,
                                  &unsignedp, &reversep, &volatilep);
-      if (offset == NULL_TREE && DECL_P (base))
+      if (offset == NULL_TREE
+         && DECL_P (base)
+         && pbitpos.is_constant (&bitpos))
        {
          gcc_assert (!DECL_REGISTER (base));
          offset_int expr_offset = bitpos / BITS_PER_UNIT;
index 6feaaf78d6c02cea62c9657b8fb89810bf89399f..35c98fb883f0b250c53e75d2e06038ac73d359c5 100644 (file)
@@ -308,23 +308,19 @@ delegitimize_mem_from_attrs (rtx x)
        case IMAGPART_EXPR:
        case VIEW_CONVERT_EXPR:
          {
-           HOST_WIDE_INT bitsize, bitpos;
+           poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
            tree toffset;
            int unsignedp, reversep, volatilep = 0;
 
            decl
              = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
                                     &unsignedp, &reversep, &volatilep);
-           if (bitsize != GET_MODE_BITSIZE (mode)
-               || (bitpos % BITS_PER_UNIT)
-               || (toffset && !tree_fits_shwi_p (toffset)))
+           if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
+               || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
+               || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
              decl = NULL;
            else
-             {
-               offset += bitpos / BITS_PER_UNIT;
-               if (toffset)
-                 offset += tree_to_shwi (toffset);
-             }
+             offset += bytepos + toffset_val;
            break;
          }
        }
index 5c6bb7d09063d3e5712348cabbe3229602709ed1..e3d461e69124cdfe26a4c843cbdd65da715d5007 100644 (file)
@@ -267,7 +267,7 @@ tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
   aff_tree tmp;
   enum tree_code code;
   tree cst, core, toffset;
-  HOST_WIDE_INT bitpos, bitsize;
+  poly_int64 bitpos, bitsize, bytepos;
   machine_mode mode;
   int unsignedp, reversep, volatilep;
 
@@ -324,12 +324,13 @@ tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
       core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos,
                                  &toffset, &mode, &unsignedp, &reversep,
                                  &volatilep);
-      if (bitpos % BITS_PER_UNIT != 0)
+      if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos))
        break;
-      aff_combination_const (comb, type, bitpos / BITS_PER_UNIT);
+      aff_combination_const (comb, type, bytepos);
       if (TREE_CODE (core) == MEM_REF)
        {
-         aff_combination_add_cst (comb, wi::to_widest (TREE_OPERAND (core, 1)));
+         tree mem_offset = TREE_OPERAND (core, 1);
+         aff_combination_add_cst (comb, wi::to_poly_widest (mem_offset));
          core = TREE_OPERAND (core, 0);
        }
       else
@@ -929,7 +930,7 @@ debug_aff (aff_tree *val)
 tree
 get_inner_reference_aff (tree ref, aff_tree *addr, poly_widest_int *size)
 {
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos;
   tree toff;
   machine_mode mode;
   int uns, rev, vol;
@@ -948,10 +949,10 @@ get_inner_reference_aff (tree ref, aff_tree *addr, poly_widest_int *size)
       aff_combination_add (addr, &tmp);
     }
 
-  aff_combination_const (&tmp, sizetype, bitpos / BITS_PER_UNIT);
+  aff_combination_const (&tmp, sizetype, bits_to_bytes_round_down (bitpos));
   aff_combination_add (addr, &tmp);
 
-  *size = (bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+  *size = bits_to_bytes_round_up (bitsize);
 
   return base;
 }
index 4b805aaa612e78a6c07a710bcf4a0e4027bc3834..86a587d04c0559eced40438c1649fa52a7bcd20a 100644 (file)
@@ -627,7 +627,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
     case ADDR_EXPR:
       {
        tree base, poffset;
-       HOST_WIDE_INT pbitsize, pbitpos;
+       poly_int64 pbitsize, pbitpos, pbytepos;
        machine_mode pmode;
        int punsignedp, preversep, pvolatilep;
 
@@ -636,10 +636,10 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
          = get_inner_reference (op0, &pbitsize, &pbitpos, &poffset, &pmode,
                                 &punsignedp, &preversep, &pvolatilep);
 
-       if (pbitpos % BITS_PER_UNIT != 0)
+       if (!multiple_p (pbitpos, BITS_PER_UNIT, &pbytepos))
          return false;
        base = build_fold_addr_expr (base);
-       off0 = ssize_int (pbitpos / BITS_PER_UNIT);
+       off0 = ssize_int (pbytepos);
 
        if (poffset)
          {
@@ -789,7 +789,7 @@ bool
 dr_analyze_innermost (innermost_loop_behavior *drb, tree ref,
                      struct loop *loop)
 {
-  HOST_WIDE_INT pbitsize, pbitpos;
+  poly_int64 pbitsize, pbitpos;
   tree base, poffset;
   machine_mode pmode;
   int punsignedp, preversep, pvolatilep;
@@ -804,7 +804,8 @@ dr_analyze_innermost (innermost_loop_behavior *drb, tree ref,
                              &punsignedp, &preversep, &pvolatilep);
   gcc_assert (base != NULL_TREE);
 
-  if (pbitpos % BITS_PER_UNIT != 0)
+  poly_int64 pbytepos;
+  if (!multiple_p (pbitpos, BITS_PER_UNIT, &pbytepos))
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "failed: bit offset alignment.\n");
@@ -885,7 +886,7 @@ dr_analyze_innermost (innermost_loop_behavior *drb, tree ref,
         }
     }
 
-  init = ssize_int (pbitpos / BITS_PER_UNIT);
+  init = ssize_int (pbytepos);
 
   /* Subtract any constant component from the base and add it to INIT instead.
      Adjust the misalignment to reflect the amount we subtracted.  */
index b47b4ed77209ee76a7108aef8c17a873d02f522a..7ee70fa5dc5be11d6d911afdbed2b96b1c930e1d 100644 (file)
@@ -1731,7 +1731,7 @@ interpret_rhs_expr (struct loop *loop, gimple *at_stmt,
          || handled_component_p (TREE_OPERAND (rhs1, 0)))
         {
          machine_mode mode;
-         HOST_WIDE_INT bitsize, bitpos;
+         poly_int64 bitsize, bitpos;
          int unsignedp, reversep;
          int volatilep = 0;
          tree base, offset;
@@ -1770,11 +1770,9 @@ interpret_rhs_expr (struct loop *loop, gimple *at_stmt,
              res = chrec_fold_plus (type, res, chrec2);
            }
 
-         if (bitpos != 0)
+         if (maybe_ne (bitpos, 0))
            {
-             gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
-
-             unitpos = size_int (bitpos / BITS_PER_UNIT);
+             unitpos = size_int (exact_div (bitpos, BITS_PER_UNIT));
              chrec3 = analyze_scalar_evolution (loop, unitpos);
              chrec3 = chrec_convert (TREE_TYPE (unitpos), chrec3, at_stmt);
              chrec3 = instantiate_parameters (loop, chrec3);
index 36f7885cfcee9327f779e0666f138c020040c0e6..93de0442a807b51df289db2fcf9db5591da4240a 100644 (file)
@@ -5399,12 +5399,12 @@ ipa_sra_check_caller (struct cgraph_node *node, void *data)
              continue;
 
          tree offset;
-         HOST_WIDE_INT bitsize, bitpos;
+         poly_int64 bitsize, bitpos;
          machine_mode mode;
          int unsignedp, reversep, volatilep = 0;
          get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
                               &unsignedp, &reversep, &volatilep);
-         if (bitpos % BITS_PER_UNIT)
+         if (!multiple_p (bitpos, BITS_PER_UNIT))
            {
              iscc->bad_arg_alignment = true;
              return true;
index 78ee673a9d332d75ef5195c0a7fabd872299de89..9867077cd86a002c8eb262fe52073bda6b42eeda 100644 (file)
@@ -3226,7 +3226,8 @@ bool
 vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo,
                           gather_scatter_info *info)
 {
-  HOST_WIDE_INT scale = 1, pbitpos, pbitsize;
+  HOST_WIDE_INT scale = 1;
+  poly_int64 pbitpos, pbitsize;
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
@@ -3267,7 +3268,8 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo,
      that can be gimplified before the loop.  */
   base = get_inner_reference (base, &pbitsize, &pbitpos, &off, &pmode,
                              &punsignedp, &reversep, &pvolatilep);
-  gcc_assert (base && (pbitpos % BITS_PER_UNIT) == 0 && !reversep);
+  gcc_assert (base && !reversep);
+  poly_int64 pbytepos = exact_div (pbitpos, BITS_PER_UNIT);
 
   if (TREE_CODE (base) == MEM_REF)
     {
@@ -3300,14 +3302,14 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo,
       if (!integer_zerop (off))
        return false;
       off = base;
-      base = size_int (pbitpos / BITS_PER_UNIT);
+      base = size_int (pbytepos);
     }
   /* Otherwise put base + constant offset into the loop invariant BASE
      and continue with OFF.  */
   else
     {
       base = fold_convert (sizetype, base);
-      base = size_binop (PLUS_EXPR, base, size_int (pbitpos / BITS_PER_UNIT));
+      base = size_binop (PLUS_EXPR, base, size_int (pbytepos));
     }
 
   /* OFF at this point may be either a SSA_NAME or some tree expression
index db87321882797a4426057eeb96f86b17634e240c..5ac1f2594f072915942b39f670e96607c1df7a24 100644 (file)
@@ -5636,19 +5636,8 @@ extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
 /* Given an expression EXP that is a handled_component_p,
    look for the ultimate containing object, which is returned and specify
    the access position and size.  */
-extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
+extern tree get_inner_reference (tree, poly_int64_pod *, poly_int64_pod *,
                                 tree *, machine_mode *, int *, int *, int *);
-/* Temporary.  */
-inline tree
-get_inner_reference (tree exp, poly_int64_pod *pbitsize,
-                    poly_int64_pod *pbitpos, tree *poffset,
-                    machine_mode *pmode, int *punsignedp,
-                    int *preversep, int *pvolatilep)
-{
-  return get_inner_reference (exp, &pbitsize->coeffs[0], &pbitpos->coeffs[0],
-                             poffset, pmode, punsignedp, preversep,
-                             pvolatilep);
-}
 
 extern tree build_personality_function (const char *);
 
index 51b5821deb33c84bc51c23b6fa65f678ddb9c2ce..538d315b11f62d2855cdfbb021d72b83b5ec85e8 100644 (file)
@@ -110,12 +110,12 @@ instrument_expr (gimple_stmt_iterator gsi, tree expr, bool is_write)
   if (size <= 0)
     return false;
 
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 unused_bitsize, unused_bitpos;
   tree offset;
   machine_mode mode;
   int unsignedp, reversep, volatilep = 0;
-  base = get_inner_reference (expr, &bitsize, &bitpos, &offset, &mode,
-                             &unsignedp, &reversep, &volatilep);
+  base = get_inner_reference (expr, &unused_bitsize, &unused_bitpos, &offset,
+                             &mode, &unsignedp, &reversep, &volatilep);
 
   /* No need to instrument accesses to decls that don't escape,
      they can't escape to other threads then.  */
@@ -142,6 +142,7 @@ instrument_expr (gimple_stmt_iterator gsi, tree expr, bool is_write)
        && DECL_BIT_FIELD_TYPE (TREE_OPERAND (expr, 1)))
       || TREE_CODE (expr) == BIT_FIELD_REF)
     {
+      HOST_WIDE_INT bitpos, bitsize;
       base = TREE_OPERAND (expr, 0);
       if (TREE_CODE (expr) == COMPONENT_REF)
        {
index efde3f7bc365d6dcaa1e79b5f156e1499328c060..e89e87bcd2a01091eaebac0afae485f1e18cece9 100644 (file)
@@ -1425,7 +1425,7 @@ maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
   if (!handled_component_p (t) && TREE_CODE (t) != MEM_REF)
     return;
 
-  HOST_WIDE_INT bitsize, bitpos, bytepos;
+  poly_int64 bitsize, bitpos, bytepos;
   tree offset;
   machine_mode mode;
   int volatilep = 0, reversep, unsignedp = 0;
@@ -1443,14 +1443,14 @@ maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
       /* If BASE is a fixed size automatic variable or
         global variable defined in the current TU and bitpos
         fits, don't instrument anything.  */
+      poly_int64 base_size;
       if (offset == NULL_TREE
-         && bitpos > 0
+         && maybe_ne (bitpos, 0)
          && (VAR_P (base)
              || TREE_CODE (base) == PARM_DECL
              || TREE_CODE (base) == RESULT_DECL)
-         && DECL_SIZE (base)
-         && TREE_CODE (DECL_SIZE (base)) == INTEGER_CST
-         && compare_tree_int (DECL_SIZE (base), bitpos) >= 0
+         && poly_int_tree_p (DECL_SIZE (base), &base_size)
+         && known_ge (base_size, bitpos)
          && (!is_global_var (base) || decl_binds_to_current_def_p (base)))
        return;
     }
@@ -1471,8 +1471,8 @@ maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
 
   if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
     return;
-  bytepos = bitpos / BITS_PER_UNIT;
-  if (offset == NULL_TREE && bytepos == 0 && moff == NULL_TREE)
+  bytepos = bits_to_bytes_round_down (bitpos);
+  if (offset == NULL_TREE && known_eq (bytepos, 0) && moff == NULL_TREE)
     return;
 
   tree base_addr = base;
@@ -1480,7 +1480,7 @@ maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
     base_addr = build1 (ADDR_EXPR,
                        build_pointer_type (TREE_TYPE (base)), base);
   t = offset;
-  if (bytepos)
+  if (maybe_ne (bytepos, 0))
     {
       if (t)
        t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
@@ -1663,7 +1663,7 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
     return;
 
   int modebitsize = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type));
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos;
   tree offset;
   machine_mode mode;
   int volatilep = 0, reversep, unsignedp = 0;
@@ -1672,8 +1672,8 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
   tree utype = build_nonstandard_integer_type (modebitsize, 1);
 
   if ((VAR_P (base) && DECL_HARD_REGISTER (base))
-      || (bitpos % modebitsize) != 0
-      || bitsize != modebitsize
+      || !multiple_p (bitpos, modebitsize)
+      || maybe_ne (bitsize, modebitsize)
       || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype)) != modebitsize
       || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
     return;
@@ -2085,15 +2085,15 @@ instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
   if (size_in_bytes <= 0)
     return;
 
-  HOST_WIDE_INT bitsize, bitpos;
+  poly_int64 bitsize, bitpos;
   tree offset;
   machine_mode mode;
   int volatilep = 0, reversep, unsignedp = 0;
   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
                                    &unsignedp, &reversep, &volatilep);
 
-  if (bitpos % BITS_PER_UNIT != 0
-      || bitsize != size_in_bytes * BITS_PER_UNIT)
+  if (!multiple_p (bitpos, BITS_PER_UNIT)
+      || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT))
     return;
 
   bool decl_p = DECL_P (inner);