Hi,
This patch fix two minor bugs when computing offset in IVOPT.
1) Considering below example:
#define MAX 100
struct tag
{
  int i;
  int j;
}
struct tag arr[MAX]

int foo (int len)
{
  int i = 0;
  for (; i < len; i++)
  {
    access arr[i].j;
  }
}

Without this patch, the offset computed by strip_offset_1 for address
arr[i].j is ZERO, which is apparently not.

2) Considering below example:
//...
  <bb 15>:
  KeyIndex_66 = KeyIndex_194 + 4294967295;
  if (KeyIndex_66 != 0)
    goto <bb 16>;
  else
    goto <bb 18>;

  <bb 16>:

  <bb 17>:
  # KeyIndex_194 = PHI <KeyIndex_66(16), KeyIndex_180(73)>
  _62 = KeyIndex_194 + 1073741823;
  _63 = _62 * 4;
  _64 = pretmp_184 + _63;
  _65 = *_64;
  if (_65 == 0)
    goto <bb 15>;
  else
    goto <bb 71>;
//...

There are iv use and candidate like:

use 1
  address
  in statement _65 = *_64;

  at position *_64
  type handletype *
  base pretmp_184 + ((sizetype) KeyIndex_180 + 1073741823) * 4
  step 4294967292
  base object (void *) pretmp_184
  related candidates 

candidate 6
  var_before ivtmp.16
  var_after ivtmp.16
  incremented before use 1
  type unsigned int
  base (unsigned int) (pretmp_184 + (sizetype) KeyIndex_180 * 4)
  step 4294967292
  base object (void *) pretmp_184
Candidate 6 is related to use 1

In function get_computation_cost_at for use 1 using cand 6, ubase and cbase
are:
pretmp_184 + ((sizetype) KeyIndex_180 + 1073741823) * 4
pretmp_184 + (sizetype) KeyIndex_180 * 4

The cstepi computed in HOST_WIDE_INT is :  0xfffffffffffffffc, while offset
computed in TYPE(utype) is : 0xfffffffc.  Though they both stand for value
"-4" in different precision, statement "offset -= ratio * cstepi" returns
0x100000000, which is wrong.

Tested on x86_64 and arm.  Is it OK?

Thanks.
bin


2013-09-24  Bin Cheng  <bin.ch...@arm.com>

        * tree-ssa-loop-ivopts.c (strip_offset_1): Count
        DECL_FIELD_BIT_OFFSET when computing offset for COMPONENT_REF.
        (get_computation_cost_at): Sign extend offset.
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c  (revision 200774)
+++ gcc/tree-ssa-loop-ivopts.c  (working copy)
@@ -2133,19 +2133,28 @@ strip_offset_1 (tree expr, bool inside_addr, bool
       break;
 
     case COMPONENT_REF:
-      if (!inside_addr)
-       return orig_expr;
+      {
+       tree field;
+       HOST_WIDE_INT boffset = 0;
+       if (!inside_addr)
+         return orig_expr;
 
-      tmp = component_ref_field_offset (expr);
-      if (top_compref
-         && cst_and_fits_in_hwi (tmp))
-       {
-         /* Strip the component reference completely.  */
-         op0 = TREE_OPERAND (expr, 0);
-         op0 = strip_offset_1 (op0, inside_addr, top_compref, &off0);
-         *offset = off0 + int_cst_value (tmp);
-         return op0;
-       }
+       field = TREE_OPERAND (expr, 1);
+       if (DECL_FIELD_BIT_OFFSET (field)
+           && cst_and_fits_in_hwi (DECL_FIELD_BIT_OFFSET (field)))
+         boffset = int_cst_value (DECL_FIELD_BIT_OFFSET (field));
+
+       tmp = component_ref_field_offset (expr);
+       if (top_compref
+           && cst_and_fits_in_hwi (tmp))
+         {
+           /* Strip the component reference completely.  */
+           op0 = TREE_OPERAND (expr, 0);
+           op0 = strip_offset_1 (op0, inside_addr, top_compref, &off0);
+           *offset = off0 + int_cst_value (tmp) + boffset / BITS_PER_UNIT;
+           return op0;
+         }
+      }
       break;
 
     case ADDR_EXPR:
@@ -4133,6 +4142,9 @@ get_computation_cost_at (struct ivopts_data *data,
         bitmap_clear (*depends_on);
     }
 
+  /* Sign-extend offset if utype has lower precision than HOST_WIDE_INT.  */
+  offset = sext_hwi (offset, TYPE_PRECISION (utype));
+
   /* If we are after the increment, the value of the candidate is higher by
      one iteration.  */
   if (stmt_is_after_inc)

Reply via email to