tree-affine.c (ssa.h): Include header file.
authorBin Cheng <bin.cheng@arm.com>
Wed, 7 Jun 2017 10:49:09 +0000 (10:49 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Wed, 7 Jun 2017 10:49:09 +0000 (10:49 +0000)
* tree-affine.c (ssa.h): Include header file.
(tree_to_aff_combination): Handle (T1)(X - CST) when inner type
has wrapping overflow behavior.

From-SVN: r248957

gcc/ChangeLog
gcc/tree-affine.c

index b2d723250d40b07cecd8e263496487d75b4c2531..708051d9b495ed6c591caed26fcff22c2052fdf0 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-07  Bin Cheng  <bin.cheng@arm.com>
+
+       * tree-affine.c (ssa.h): Include header file.
+       (tree_to_aff_combination): Handle (T1)(X - CST) when inner type
+       has wrapping overflow behavior.
+
 2017-06-07  Bin Cheng  <bin.cheng@arm.com>
 
        * tree-affine.c (tree_to_aff_combination): Handle (T1)(X + X).
index d2983ab5e8a892e778e64baa81803691a757b2ec..f7a5f121c9c9ed74498a2f9ba5d702c17d7b025c 100644 (file)
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "rtl.h"
 #include "tree.h"
 #include "gimple.h"
+#include "ssa.h"
 #include "tree-pretty-print.h"
 #include "fold-const.h"
 #include "tree-affine.h"
@@ -393,6 +394,30 @@ tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
                tree_to_aff_combination (expr, type, comb);
                return;
              }
+           wide_int minv, maxv;
+           /* If inner type has wrapping overflow behavior, fold conversion
+              for below case:
+                (T1)(X - CST) -> (T1)X - (T1)CST
+              if X - CST doesn't overflow by range information.  Also handle
+              (T1)(X + CST) as (T1)(X - (-CST)).  */
+           if (TYPE_UNSIGNED (itype)
+               && TYPE_OVERFLOW_WRAPS (itype)
+               && TREE_CODE (op0) == SSA_NAME
+               && TREE_CODE (op1) == INTEGER_CST
+               && icode != MULT_EXPR
+               && get_range_info (op0, &minv, &maxv) == VR_RANGE)
+             {
+               if (icode == PLUS_EXPR)
+                 op1 = wide_int_to_tree (itype, wi::neg (op1));
+               if (wi::geu_p (minv, op1))
+                 {
+                   op0 = fold_convert (otype, op0);
+                   op1 = fold_convert (otype, op1);
+                   expr = fold_build2 (MINUS_EXPR, otype, op0, op1);
+                   tree_to_aff_combination (expr, type, comb);
+                   return;
+                 }
+             }
          }
       }
       break;