OSDN Git Service

2006-04-18 Paolo Bonzini <bonzini@gnu.org>
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Apr 2006 08:08:47 +0000 (08:08 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Apr 2006 08:08:47 +0000 (08:08 +0000)
        PR tree-optimization/26821
        * tree-ssa-math-opts.c (get_constant_one): New.
        (insert_reciprocals): Use it.

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

gcc/ChangeLog
gcc/testsuite/gcc.dg/vect/vect-recip.c [new file with mode: 0644]
gcc/tree-ssa-math-opts.c

index 665266c..2d26302 100644 (file)
@@ -1,3 +1,9 @@
+2006-04-18  Paolo Bonzini  <bonzini@gnu.org>
+
+        PR tree-optimization/26821
+        * tree-ssa-math-opts.c (get_constant_one): New.
+        (insert_reciprocals): Use it.
+
 2006-04-17  Geoffrey Keating  <geoffk@apple.com>
 
        * dwarf2out.c (free_AT): Delete.
 2006-04-17  Geoffrey Keating  <geoffk@apple.com>
 
        * dwarf2out.c (free_AT): Delete.
diff --git a/gcc/testsuite/gcc.dg/vect/vect-recip.c b/gcc/testsuite/gcc.dg/vect/vect-recip.c
new file mode 100644 (file)
index 0000000..89af984
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_float } */
+
+void f(float *__restrict__ qa, float *__restrict__ qb,
+       float *__restrict__ qc, float *__restrict__ rtrms)
+{
+  int i;
+  static float qam[600];
+  static float qbm[600];
+  static float qcm[600];
+  for(i=0;i<600;i++)
+  {
+    float a = rtrms[i];
+    qam[i] = qa[i]/a;
+    qbm[i] = qb[i]/a;
+    qcm[i] = qc[i]/a;
+  }
+}
index 609c408..4d02894 100644 (file)
@@ -279,6 +279,35 @@ is_division_by (tree use_stmt, tree def)
         && TREE_OPERAND (TREE_OPERAND (use_stmt, 1), 1) == def;
 }
 
         && TREE_OPERAND (TREE_OPERAND (use_stmt, 1), 1) == def;
 }
 
+/* Return the LHS of a RDIV_EXPR that computes a reciprocal in type TYPE.  */
+static tree
+get_constant_one (tree type)
+{
+  tree scalar, cst;
+  int i;
+
+  gcc_assert (FLOAT_TYPE_P (type));
+  switch (TREE_CODE (type))
+    {
+    case REAL_TYPE:
+      return build_real (type, dconst1);
+
+    case VECTOR_TYPE:
+      scalar = build_real (TREE_TYPE (type), dconst1);
+
+      /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
+      cst = NULL_TREE;
+      for (i = TYPE_VECTOR_SUBPARTS (type); --i >= 0; )
+        cst = tree_cons (NULL_TREE, scalar, cst);
+
+      return build_vector (type, cst);
+
+    default:
+      /* Complex operations have been split already.  */
+      gcc_unreachable ();
+    }
+}
+
 /* Walk the subset of the dominator tree rooted at OCC, setting the
    RECIP_DEF field to a definition of 1.0 / DEF that can be used in
    the given basic block.  The field may be left NULL, of course,
 /* Walk the subset of the dominator tree rooted at OCC, setting the
    RECIP_DEF field to a definition of 1.0 / DEF that can be used in
    the given basic block.  The field may be left NULL, of course,
@@ -304,8 +333,8 @@ insert_reciprocals (block_stmt_iterator *def_bsi, struct occurrence *occ,
       type = TREE_TYPE (def);
       recip_def = make_rename_temp (type, "reciptmp");
       new_stmt = build2 (MODIFY_EXPR, void_type_node, recip_def,
       type = TREE_TYPE (def);
       recip_def = make_rename_temp (type, "reciptmp");
       new_stmt = build2 (MODIFY_EXPR, void_type_node, recip_def,
-                        fold_build2 (RDIV_EXPR, type,
-                                     build_real (type, dconst1), def));
+                        fold_build2 (RDIV_EXPR, type, get_constant_one (type),
+                                     def));
   
   
       if (occ->bb_has_division)
   
   
       if (occ->bb_has_division)