2012-03-27 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Mar 2012 12:50:29 +0000 (12:50 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Mar 2012 12:50:29 +0000 (12:50 +0000)
PR middle-end/52720
* fold-const.c (try_move_mult_to_index): Handle &x.array more
explicitely.

* gcc.dg/torture/pr52720.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185865 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr52720.c [new file with mode: 0644]

index bf370df..e9acac3 100644 (file)
@@ -1,3 +1,9 @@
+2012-03-27  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/52720
+       * fold-const.c (try_move_mult_to_index): Handle &x.array more
+       explicitely.
+
 2012-03-27  Eric Botcazou  <ebotcazou@adacore.com>
 
        * expmed.c (store_bit_field): Assert that BITREGION_START is a multiple
index 1e91bac..df0c05c 100644 (file)
@@ -6826,64 +6826,81 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
       s = integer_one_node;
     }
 
-  for (;; ref = TREE_OPERAND (ref, 0))
+  /* Handle &x.array the same as we would handle &x.array[0].  */
+  if (TREE_CODE (ref) == COMPONENT_REF
+      && TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
     {
-      if (TREE_CODE (ref) == ARRAY_REF)
+      tree domain;
+
+      /* Remember if this was a multi-dimensional array.  */
+      if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF)
+       mdim = true;
+
+      domain = TYPE_DOMAIN (TREE_TYPE (ref));
+      if (! domain)
+       goto cont;
+      itype = TREE_TYPE (domain);
+
+      step = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref)));
+      if (TREE_CODE (step) != INTEGER_CST)
+       goto cont;
+
+      if (s)
        {
-         tree domain;
+         if (! tree_int_cst_equal (step, s))
+           goto cont;
+       }
+      else
+       {
+         /* Try if delta is a multiple of step.  */
+         tree tmp = div_if_zero_remainder (EXACT_DIV_EXPR, op1, step);
+         if (! tmp)
+           goto cont;
+         delta = tmp;
+       }
 
-         /* Remember if this was a multi-dimensional array.  */
-         if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF)
-           mdim = true;
+      /* Only fold here if we can verify we do not overflow one
+        dimension of a multi-dimensional array.  */
+      if (mdim)
+       {
+         tree tmp;
 
-         domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
-         if (! domain)
-           continue;
-         itype = TREE_TYPE (domain);
+         if (!TYPE_MIN_VALUE (domain)
+             || !TYPE_MAX_VALUE (domain)
+             || TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
+           goto cont;
 
-         step = array_ref_element_size (ref);
-         if (TREE_CODE (step) != INTEGER_CST)
-           continue;
+         tmp = fold_binary_loc (loc, PLUS_EXPR, itype,
+                                fold_convert_loc (loc, itype,
+                                                  TYPE_MIN_VALUE (domain)),
+                                fold_convert_loc (loc, itype, delta));
+         if (TREE_CODE (tmp) != INTEGER_CST
+             || tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp))
+           goto cont;
+       }
 
-         if (s)
-           {
-             if (! tree_int_cst_equal (step, s))
-                continue;
-           }
-         else
-           {
-             /* Try if delta is a multiple of step.  */
-             tree tmp = div_if_zero_remainder (EXACT_DIV_EXPR, op1, step);
-             if (! tmp)
-               continue;
-             delta = tmp;
-           }
+      /* We found a suitable component reference.  */
 
-         /* Only fold here if we can verify we do not overflow one
-            dimension of a multi-dimensional array.  */
-         if (mdim)
-           {
-             tree tmp;
+      pref = TREE_OPERAND (addr, 0);
+      ret = copy_node (pref);
+      SET_EXPR_LOCATION (ret, loc);
 
-             if (TREE_CODE (TREE_OPERAND (ref, 1)) != INTEGER_CST
-                 || !TYPE_MAX_VALUE (domain)
-                 || TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
-               continue;
+      ret = build4_loc (loc, ARRAY_REF, TREE_TYPE (TREE_TYPE (ref)), ret,
+                       fold_build2_loc
+                         (loc, PLUS_EXPR, itype,
+                          fold_convert_loc (loc, itype,
+                                            TYPE_MIN_VALUE
+                                              (TYPE_DOMAIN (TREE_TYPE (ref)))),
+                          fold_convert_loc (loc, itype, delta)),
+                       NULL_TREE, NULL_TREE);
+      return build_fold_addr_expr_loc (loc, ret);
+    }
 
-             tmp = fold_binary_loc (loc, PLUS_EXPR, itype,
-                                    fold_convert_loc (loc, itype,
-                                                      TREE_OPERAND (ref, 1)),
-                                    fold_convert_loc (loc, itype, delta));
-             if (!tmp
-                 || TREE_CODE (tmp) != INTEGER_CST
-                 || tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp))
-               continue;
-           }
+cont:
 
-         break;
-       }
-      else if (TREE_CODE (ref) == COMPONENT_REF
-              && TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
+  for (;; ref = TREE_OPERAND (ref, 0))
+    {
+      if (TREE_CODE (ref) == ARRAY_REF)
        {
          tree domain;
 
@@ -6891,12 +6908,12 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
          if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF)
            mdim = true;
 
-         domain = TYPE_DOMAIN (TREE_TYPE (ref));
+         domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
          if (! domain)
            continue;
          itype = TREE_TYPE (domain);
 
-         step = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref)));
+         step = array_ref_element_size (ref);
          if (TREE_CODE (step) != INTEGER_CST)
            continue;
 
@@ -6920,16 +6937,17 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
            {
              tree tmp;
 
-             if (!TYPE_MIN_VALUE (domain)
+             if (TREE_CODE (TREE_OPERAND (ref, 1)) != INTEGER_CST
                  || !TYPE_MAX_VALUE (domain)
                  || TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
                continue;
 
              tmp = fold_binary_loc (loc, PLUS_EXPR, itype,
                                     fold_convert_loc (loc, itype,
-                                                      TYPE_MIN_VALUE (domain)),
+                                                      TREE_OPERAND (ref, 1)),
                                     fold_convert_loc (loc, itype, delta));
-             if (TREE_CODE (tmp) != INTEGER_CST
+             if (!tmp
+                 || TREE_CODE (tmp) != INTEGER_CST
                  || tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp))
                continue;
            }
@@ -6958,29 +6976,11 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1)
       pos = TREE_OPERAND (pos, 0);
     }
 
-  if (TREE_CODE (ref) == ARRAY_REF)
-    {
-      TREE_OPERAND (pos, 1)
-       = fold_build2_loc (loc, PLUS_EXPR, itype,
-                          fold_convert_loc (loc, itype, TREE_OPERAND (pos, 1)),
-                          fold_convert_loc (loc, itype, delta));
-      return fold_build1_loc (loc, ADDR_EXPR, TREE_TYPE (addr), ret);
-    }
-  else if (TREE_CODE (ref) == COMPONENT_REF)
-    {
-      gcc_assert (ret == pos);
-      ret = build4_loc (loc, ARRAY_REF, TREE_TYPE (TREE_TYPE (ref)), ret,
-                       fold_build2_loc
-                         (loc, PLUS_EXPR, itype,
-                          fold_convert_loc (loc, itype,
-                                            TYPE_MIN_VALUE
-                                              (TYPE_DOMAIN (TREE_TYPE (ref)))),
-                          fold_convert_loc (loc, itype, delta)),
-                       NULL_TREE, NULL_TREE);
-      return build_fold_addr_expr_loc (loc, ret);
-    }
-  else
-    gcc_unreachable ();
+  TREE_OPERAND (pos, 1)
+    = fold_build2_loc (loc, PLUS_EXPR, itype,
+                      fold_convert_loc (loc, itype, TREE_OPERAND (pos, 1)),
+                      fold_convert_loc (loc, itype, delta));
+  return fold_build1_loc (loc, ADDR_EXPR, TREE_TYPE (addr), ret);
 }
 
 
index 63de5d4..408184a 100644 (file)
@@ -1,3 +1,8 @@
+2012-03-27  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/52720
+       * gcc.dg/torture/pr52720.c: New testcase.
+
 2012-03-27  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/pack17.adb: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr52720.c b/gcc/testsuite/gcc.dg/torture/pr52720.c
new file mode 100644 (file)
index 0000000..528aa16
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-march=k8-sse3" { target x86_64-*-* } } */
+
+struct alu_bank_swizzle {
+    int hw_gpr[3][4];
+    int hw_cfile_addr[4];
+};
+static void init_bank_swizzle(struct alu_bank_swizzle *bs)
+{
+  int i, cycle, component;
+  for (cycle = 0; cycle < 3; cycle++)
+    for (component = 0; component < 4; component++)
+      bs->hw_gpr[cycle][component] = -1;
+  for (i = 0; i < 4; i++) 
+    bs->hw_cfile_addr[i] = -1;
+}
+int check_and_set_bank_swizzle(int max_slots, int *slots)
+{
+  struct alu_bank_swizzle bs;
+  int i;
+  for (i = 0; i < max_slots; i++)
+    {
+      init_bank_swizzle(&bs);
+      if (slots[i])
+       check_vector(&bs); 
+    }
+}
+