Hello,
I noticed quite ugly code from both testcases. This transformation does
not fix either, but it helps a bit.
bootstrap+regtest on powerpc64le-unknown-linux-gnu.
2018-09-30 Marc Glisse <[email protected]>
gcc/
* match.pd (((X /[ex] A) +- B) * A): New transformation.
gcc/testsuite/
* gcc.dg/tree-ssa/muldiv-1.c: New file.
* gcc.dg/tree-ssa/muldiv-2.c: Likewise.
--
Marc GlisseIndex: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 264371)
+++ gcc/match.pd (working copy)
@@ -2637,20 +2637,39 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& operand_equal_p (@1, build_low_bits_mask (TREE_TYPE (@1),
TYPE_PRECISION (type)), 0))
(convert @0)))
/* (X /[ex] A) * A -> X. */
(simplify
(mult (convert1? (exact_div @0 @@1)) (convert2? @1))
(convert @0))
+/* ((X /[ex] A) +- B) * A --> X +- A * B. */
+(for op (plus minus)
+ (simplify
+ (mult (convert1? (op (convert2? (exact_div @0 INTEGER_CST@@1)) INTEGER_CST@2)) @1)
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@2))
+ && tree_nop_conversion_p (TREE_TYPE (@0), TREE_TYPE (@2)))
+ (with
+ {
+ wi::overflow_type overflow;
+ wide_int mul = wi::mul (wi::to_wide (@1), wi::to_wide (@2),
+ TYPE_SIGN (type), &overflow);
+ }
+ (if (types_match (type, TREE_TYPE (@2))
+ && types_match (TREE_TYPE (@0), TREE_TYPE (@2)) && !overflow)
+ (op @0 { wide_int_to_tree (type, mul); })
+ (with { tree utype = unsigned_type_for (type); }
+ (convert (op (convert:utype @0)
+ (mult (convert:utype @1) (convert:utype @2))))))))))
+
/* Canonicalization of binary operations. */
/* Convert X + -C into X - C. */
(simplify
(plus @0 REAL_CST@1)
(if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (@1)))
(with { tree tem = const_unop (NEGATE_EXPR, type, @1); }
(if (!TREE_OVERFLOW (tem) || !flag_trapping_math)
(minus @0 { tem; })))))
Index: gcc/testsuite/gcc.dg/tree-ssa/muldiv-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/muldiv-1.c (nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/muldiv-1.c (working copy)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized-raw" } */
+
+// ldist produces (((q-p-4)/4)&...+1)*4
+// Make sure we remove at least the division
+// Eventually this should just be n*4
+
+void foo(int*p, __SIZE_TYPE__ n){
+ for(int*q=p+n;p!=q;++p)*p=0;
+}
+
+/* { dg-final { scan-tree-dump "builtin_memset" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "div" "optimized" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/muldiv-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/muldiv-2.c (nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/muldiv-2.c (working copy)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
+
+// 'a' should disappear, but we are not there yet
+
+int* f(int* a, int* b, int* c){
+ __PTRDIFF_TYPE__ d = b - a;
+ d += 1;
+ return a + d;
+}
+
+/* { dg-final { scan-tree-dump-not "div" "optimized" } } */