No a*x+b*x factorization for signed vectors
authorMarc Glisse <marc.glisse@inria.fr>
Tue, 2 Oct 2018 14:55:39 +0000 (16:55 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Tue, 2 Oct 2018 14:55:39 +0000 (14:55 +0000)
2018-10-02  Marc Glisse  <marc.glisse@inria.fr>

PR middle-end/87319
* fold-const.c (fold_plusminus_mult_expr): Handle complex and vectors.
* tree.c (signed_or_unsigned_type_for): Handle complex.

From-SVN: r264790

gcc/ChangeLog
gcc/fold-const.c
gcc/tree.c

index 59a01f8643629e2e97e4feb6bf2d05f4c0601b60..236f70c52e0039fcfd00a4ec859538e5ffb6db4c 100644 (file)
@@ -1,3 +1,9 @@
+2018-10-02  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR middle-end/87319
+       * fold-const.c (fold_plusminus_mult_expr): Handle complex and vectors.
+       * tree.c (signed_or_unsigned_type_for): Handle complex.
+
 2018-10-02  Jeff Law  <law@redhat.com>
 
        * gimple-fold.c (get_range_strlen): Remove dead code.
index 3a6d1b19b487c830e52a3913d448bc369998c0e0..59cedeafd71efc11c1dcf893b321677aa474b4e5 100644 (file)
@@ -7143,7 +7143,7 @@ fold_plusminus_mult_expr (location_t loc, enum tree_code code, tree type,
   if (!same)
     return NULL_TREE;
 
-  if (! INTEGRAL_TYPE_P (type)
+  if (! ANY_INTEGRAL_TYPE_P (type)
       || TYPE_OVERFLOW_WRAPS (type)
       /* We are neither factoring zero nor minus one.  */
       || TREE_CODE (same) == INTEGER_CST)
index d52f87773924ddcff516cf1ff06a3f4713bf25b1..748ece690ea4905a8629d213027d44d23739ecb3 100644 (file)
@@ -11209,7 +11209,7 @@ int_cst_value (const_tree x)
 tree
 signed_or_unsigned_type_for (int unsignedp, tree type)
 {
-  if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type) == unsignedp)
+  if (ANY_INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) == unsignedp)
     return type;
 
   if (TREE_CODE (type) == VECTOR_TYPE)
@@ -11223,6 +11223,17 @@ signed_or_unsigned_type_for (int unsignedp, tree type)
       return build_vector_type (inner2, TYPE_VECTOR_SUBPARTS (type));
     }
 
+  if (TREE_CODE (type) == COMPLEX_TYPE)
+    {
+      tree inner = TREE_TYPE (type);
+      tree inner2 = signed_or_unsigned_type_for (unsignedp, inner);
+      if (!inner2)
+       return NULL_TREE;
+      if (inner == inner2)
+       return type;
+      return build_complex_type (inner2);
+    }
+
   if (!INTEGRAL_TYPE_P (type)
       && !POINTER_TYPE_P (type)
       && TREE_CODE (type) != OFFSET_TYPE)