aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2017-06-07 10:49:09 +0000
committerBin Cheng <amker@gcc.gnu.org>2017-06-07 10:49:09 +0000
commitba00284cedbcb0b980af4e5e41f427581af64462 (patch)
treeb19b90322a38f30446e0196c1c32f130ed39a972 /gcc
parent8813f50d2c8653bbc65450fd1244a85c1ba7902f (diff)
downloadgcc-ba00284cedbcb0b980af4e5e41f427581af64462.zip
gcc-ba00284cedbcb0b980af4e5e41f427581af64462.tar.gz
gcc-ba00284cedbcb0b980af4e5e41f427581af64462.tar.bz2
tree-affine.c (ssa.h): Include header file.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/tree-affine.c25
2 files changed, 31 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b2d7232..708051d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
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).
2017-06-07 Bin Cheng <bin.cheng@arm.com>
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index d2983ab5..f7a5f12 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -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;