This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

NOP conversions in X+CST+CST


Hello,

now that FRE was fixed to avoid infinite recursion, this patch passes bootstrap+testsuite on x86_64-pc-linux-gnu multilib with all languages (including ada).

This isn't exactly the patch that was reverted, because the previous patch did not actually handle vectors properly.

It still shouldn't interfere with the patch by Robin Dapp which IIUC only handles the case where the conversion is an extension.

2017-06-21  Marc Glisse  <marc.glisse@inria.fr>

gcc/
	* match.pd (nop_convert): New predicate.
	((A +- CST1) +- CST2): Allow some NOP conversions.

gcc/testsuite/
	* gcc.dg/tree-ssa/addadd.c: Un-XFAIL.
	* gcc.dg/tree-ssa/addadd-2.c: New file.

--
Marc Glisse
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 249413)
+++ gcc/match.pd	(working copy)
@@ -67,20 +67,34 @@ along with GCC; see the file COPYING3.
 			      BUILT_IN_L##FN \
 			      BUILT_IN_LL##FN) \
   (define_operator_list X##FN##L BUILT_IN_I##FN##L \
 				 BUILT_IN_L##FN##L \
 				 BUILT_IN_LL##FN##L)
 
 DEFINE_INT_AND_FLOAT_ROUND_FN (FLOOR)
 DEFINE_INT_AND_FLOAT_ROUND_FN (CEIL)
 DEFINE_INT_AND_FLOAT_ROUND_FN (ROUND)
 DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
+    
+/* As opposed to convert?, this still creates a single pattern, so
+   it is not a suitable replacement for convert? in all cases.  */
+(match (nop_convert @0)
+ (convert @0)
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))))
+(match (nop_convert @0)
+ (view_convert @0)
+ (if (VECTOR_TYPE_P (type) && VECTOR_TYPE_P (TREE_TYPE (@0))
+      && TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0))
+      && tree_nop_conversion_p (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0))))))
+/* This one has to be last, or it shadows the others.  */
+(match (nop_convert @0)
+ @0) 
 
 /* Simplifications of operations with one constant operand and
    simplifications to constants or single values.  */
 
 (for op (plus pointer_plus minus bit_ior bit_xor)
   (simplify
     (op @0 integer_zerop)
     (non_lvalue @0)))
 
 /* 0 +p index -> (type)index */
@@ -1289,32 +1303,58 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (simplify
     (plus:c (minus @0 @1) @1)
     @0)
   (simplify
    (minus @0 (plus:c @0 @1))
    (negate @1))
   (simplify
    (minus @0 (minus @0 @1))
    @1)
 
-  /* (A +- CST1) +- CST2 -> A + CST3  */
+  /* (A +- CST1) +- CST2 -> A + CST3
+     Use view_convert because it is safe for vectors and equivalent for
+     scalars.  */
   (for outer_op (plus minus)
    (for inner_op (plus minus)
+	neg_inner_op (minus plus)
     (simplify
-     (outer_op (inner_op @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2)
-     /* If the constant operation overflows we cannot do the transform
-	as we would introduce undefined overflow, for example
-	with (a - 1) + INT_MIN.  */
-     (with { tree cst = const_binop (outer_op == inner_op
-				     ? PLUS_EXPR : MINUS_EXPR, type, @1, @2); }
-      (if (cst && !TREE_OVERFLOW (cst))
-       (inner_op @0 { cst; } ))))))
+     (outer_op (nop_convert (inner_op @0 CONSTANT_CLASS_P@1))
+	       CONSTANT_CLASS_P@2)
+     /* If one of the types wraps, use that one.  */
+     (if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
+      (if (outer_op == PLUS_EXPR)
+       (plus (view_convert @0) (inner_op @2 (view_convert @1)))
+       (minus (view_convert @0) (neg_inner_op @2 (view_convert @1))))
+      (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+	   || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+       (if (outer_op == PLUS_EXPR)
+	(view_convert (plus @0 (inner_op (view_convert @2) @1)))
+	(view_convert (minus @0 (neg_inner_op (view_convert @2) @1))))
+       /* If the constant operation overflows we cannot do the transform
+	  directly as we would introduce undefined overflow, for example
+	  with (a - 1) + INT_MIN.  */
+       (if (types_match (type, @0))
+	(with { tree cst = const_binop (outer_op == inner_op
+					? PLUS_EXPR : MINUS_EXPR,
+					type, @1, @2); }
+	 (if (cst && !TREE_OVERFLOW (cst))
+	  (inner_op @0 { cst; } )
+	  /* X+INT_MAX+1 is X-INT_MIN.  */
+	  (if (INTEGRAL_TYPE_P (type) && cst
+	       && wi::eq_p (cst, wi::min_value (type)))
+	   (neg_inner_op @0 { wide_int_to_tree (type, cst); })
+	   /* Last resort, use some unsigned type.  */
+	   (with { tree utype = unsigned_type_for (type); }
+	    (view_convert (inner_op
+			   (view_convert:utype @0)
+			   (view_convert:utype
+			    { drop_tree_overflow (cst); })))))))))))))
 
   /* (CST1 - A) +- CST2 -> CST3 - A  */
   (for outer_op (plus minus)
    (simplify
     (outer_op (minus CONSTANT_CLASS_P@1 @0) CONSTANT_CLASS_P@2)
     (with { tree cst = const_binop (outer_op, type, @1, @2); }
      (if (cst && !TREE_OVERFLOW (cst))
       (minus { cst; } @0)))))
 
   /* CST1 - (CST2 - A) -> CST3 + A  */
Index: gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c	(working copy)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+typedef int S __attribute__((vector_size(64)));
+typedef unsigned U __attribute__((vector_size(64)));
+void j(S*x){
+  *x += __INT_MAX__;
+  *x += __INT_MAX__;
+}
+void k(S*x){
+  U y = (U)(*x + __INT_MAX__);
+  *x = (S)(y + __INT_MAX__);
+}
+
+/* { dg-final { scan-tree-dump-not "2147483647" "optimized" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/addadd.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/addadd.c	(revision 249413)
+++ gcc/testsuite/gcc.dg/tree-ssa/addadd.c	(working copy)
@@ -22,13 +22,13 @@ int i(int x){
   x += __INT_MAX__;
   x += __INT_MAX__;
   return x;
 }
 typedef int S __attribute__((vector_size(16)));
 void j(S*x){
   *x += __INT_MAX__;
   *x += __INT_MAX__;
 }
 
-/* { dg-final { scan-tree-dump-times " \\+ 24;" 2 "optimized" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 2 "optimized" { xfail *-*-* }  } } */
-/* { dg-final { scan-tree-dump-not "2147483647" "optimized" { xfail *-*-* }  } } */
+/* { dg-final { scan-tree-dump-times " \\+ 24;" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "2147483647" "optimized" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]