Hello,

Please find the updated version of the patch in the attachment. It has addressed the previous comments and also included some changes in order to pass the bootstrapping on x86_64.

It's also passed the regtest on arm-none-eabi and aarch64-none-elf.

It will also fix the test failure as reported here:
http://gcc.gnu.org/ml/gcc-patches/2013-09/msg01317.html

OK for the trunk?

Thanks,
Yufeng


gcc/

* gimple-ssa-strength-reduction.c (safe_to_multiply_p): New function.
        (backtrace_base_for_ref): Call get_unwidened, check 'base_in'
again and set unwidend_p with true; call safe_to_multiply_p to avoid
        unsafe unwidened cases.

gcc/testsuite/

        * gcc.dg/tree-ssa/slsr-40.c: New test.



On 09/11/13 13:39, Bill Schmidt wrote:
On Wed, 2013-09-11 at 10:32 +0200, Richard Biener wrote:
On Tue, Sep 10, 2013 at 5:53 PM, Yufeng Zhang<yufeng.zh...@arm.com>  wrote:
Hi,

Following Bin's patch in
http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00695.html, this patch tweaks
backtrace_base_for_ref () to strip of any widening conversion after the
first TREE_CODE check fails.  Without this patch, the test
(gcc.dg/tree-ssa/slsr-39.c) in Bin's patch will fail on AArch64, as
backtrace_base_for_ref () will stop if not seeing an ssa_name since the tree
code can be nop_expr instead.

Regtested on arm and aarch64; still bootstrapping x86_64.

OK for the trunk if the x86_64 bootstrap succeeds?

Please add a testcase.

Also, the comment "Strip of" should read "Strip off".  Otherwise I have
no comments.

Thanks,
Bill


Richard.
diff --git a/gcc/gimple-ssa-strength-reduction.c 
b/gcc/gimple-ssa-strength-reduction.c
index 8d48add..1c04382 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -750,6 +750,40 @@ slsr_process_phi (gimple phi, bool speed)
   add_cand_for_stmt (phi, c);
 }
 
+/* Utility function for backtrace_base_for_ref.
+
+   Given
+
+     T2 = T2' + CST
+     RES = (wider_type) T2 * C3
+
+   where TYPE is TREE_TYPE (T2), this function returns false when it is
+   _not_ safe to carry out the following transformation.
+
+     RES = (wider_type) T2' * C3 + (wider_type) CST * C3
+
+   One example unsafe case is:
+
+     int array[40];
+     array[n - 1]
+
+   where n is a 32-bit unsigned int and pointer are 64-bit long.  In this
+   case, the gimple for (n - 1) is:
+
+     _2 = n_1(D) + 4294967295; // 0xFFFFFFFF
+
+   and it is wrong to multiply the large constant by 4 in the 64-bit space.  */
+
+static bool
+safe_to_multiply_p (tree type, double_int cst)
+{
+  if (TYPE_UNSIGNED (type)
+      && ! double_int_fits_to_tree_p (signed_type_for (type), cst))
+    return false;
+
+  return true;
+}
+
 /* Given PBASE which is a pointer to tree, look up the defining
    statement for it and check whether the candidate is in the
    form of:
@@ -766,10 +800,19 @@ backtrace_base_for_ref (tree *pbase)
 {
   tree base_in = *pbase;
   slsr_cand_t base_cand;
+  bool unwidened_p = false;
 
   STRIP_NOPS (base_in);
   if (TREE_CODE (base_in) != SSA_NAME)
-    return tree_to_double_int (integer_zero_node);
+    {
+      /* Strip off widening conversion(s) to handle cases where
+        e.g. 'B' is widened from an 'int' in order to calculate
+        a 64-bit address.  */
+      base_in = get_unwidened (base_in, NULL_TREE);
+      if (TREE_CODE (base_in) != SSA_NAME)
+       return tree_to_double_int (integer_zero_node);
+      unwidened_p = true;
+    }
 
   base_cand = base_cand_from_table (base_in);
 
@@ -777,7 +820,10 @@ backtrace_base_for_ref (tree *pbase)
     {
       if (base_cand->kind == CAND_ADD
          && base_cand->index.is_one ()
-         && TREE_CODE (base_cand->stride) == INTEGER_CST)
+         && TREE_CODE (base_cand->stride) == INTEGER_CST
+         && (! unwidened_p
+             || safe_to_multiply_p (TREE_TYPE (base_cand->stride),
+                                    tree_to_double_int (base_cand->stride))))
        {
          /* X = B + (1 * S), S is integer constant.  */
          *pbase = base_cand->base_expr;
@@ -785,8 +831,11 @@ backtrace_base_for_ref (tree *pbase)
        }
       else if (base_cand->kind == CAND_ADD
               && TREE_CODE (base_cand->stride) == INTEGER_CST
-              && integer_onep (base_cand->stride))
-        {
+              && integer_onep (base_cand->stride)
+              && (! unwidened_p
+                  || safe_to_multiply_p (TREE_TYPE (base_cand->base_expr),
+                                         base_cand->index)))
+       {
          /* X = B + (i * S), S is integer one.  */
          *pbase = base_cand->base_expr;
          return base_cand->index;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-40.c 
b/gcc/testsuite/gcc.dg/tree-ssa/slsr-40.c
new file mode 100644
index 0000000..72726a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-40.c
@@ -0,0 +1,27 @@
+/* Verify straight-line strength reduction for array
+   subscripting.
+
+   elems[n-1] is reduced to elems + n * 4 + 0xffffffff * 4, only when
+   pointers are of the same size as that of int (assuming 4 bytes).  */
+
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+struct data
+{
+  unsigned long elms[1];
+} gData;
+
+void __attribute__((noinline))
+foo (struct data *dst, unsigned int n)
+{
+  dst->elms[n - 1] &= 1;
+}
+
+int
+main ()
+{
+  foo (&gData, 1);
+  return 0;
+}
+

Reply via email to