From 8f0d743c2dee6afae5c6f861b0642b7b112a4a70 Mon Sep 17 00:00:00 2001 From: Feng Xue Date: Mon, 17 Aug 2020 23:00:35 +0800 Subject: [PATCH] tree-optimization/94234 - add plusminus-with-convert pattern Add a rule (T)(A) +- (T)(B) -> (T)(A +- B), which works only when (A +- B) could be folded to a simple value. By this rule, a plusminus-mult-with-convert expression could be handed over to the rule (A * C) +- (B * C) -> (A +- B). 2020-09-15 Feng Xue gcc/ PR tree-optimization/94234 * match.pd (T)(A) +- (T)(B) -> (T)(A +- B): New simplification. gcc/testsuite/ PR tree-optimization/94234 * gcc.dg/pr94234-3.c: New test. --- gcc/match.pd | 15 ++++++++++++ gcc/testsuite/gcc.dg/pr94234-3.c | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr94234-3.c diff --git a/gcc/match.pd b/gcc/match.pd index 46fd880bd37..7d63bb973cb 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2397,6 +2397,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (plus (convert @0) (op @2 (convert @1)))))) #endif +/* (T)(A) +- (T)(B) -> (T)(A +- B) only when (A +- B) could be simplified + to a simple value. */ +#if GIMPLE + (for op (plus minus) + (simplify + (op (convert @0) (convert @1)) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@0)) + && types_match (TREE_TYPE (@0), TREE_TYPE (@1)) + && !TYPE_OVERFLOW_TRAPS (type) + && !TYPE_OVERFLOW_SANITIZED (type)) + (convert (op! @0 @1))))) +#endif + /* ~A + A -> -1 */ (simplify (plus:c (bit_not @0) @0) diff --git a/gcc/testsuite/gcc.dg/pr94234-3.c b/gcc/testsuite/gcc.dg/pr94234-3.c new file mode 100644 index 00000000000..9bb9b46bd96 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94234-3.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop1" } */ + +typedef __SIZE_TYPE__ size_t; +typedef __PTRDIFF_TYPE__ ptrdiff_t; + +ptrdiff_t foo1 (char *a, size_t n) +{ + char *b1 = a + 8 * n; + char *b2 = a + 8 * (n - 1); + + return b1 - b2; +} + +int use_ptr (char *a, char *b); + +ptrdiff_t foo2 (char *a, size_t n) +{ + char *b1 = a + 8 * (n - 1); + char *b2 = a + 8 * n; + + use_ptr (b1, b2); + + return b1 - b2; +} + +int use_int (int i); + +unsigned goo (unsigned m_param, unsigned n_param) +{ + unsigned b1 = m_param * (n_param + 2); + unsigned b2 = m_param * (n_param + 1); + int r = (int)(b1) - (int)(b2); + + use_int (r); + + return r; +} + +/* { dg-final { scan-tree-dump-times "return 8;" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "return -8;" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "return m_param" 1 "forwprop1" } } */ -- 2.30.2