aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2020-11-05 20:42:17 -0700
committerJeff Law <law@redhat.com>2020-11-05 20:46:00 -0700
commit32ee472864ada44ef05b2a3b087b8ce413bee282 (patch)
tree058c571d79ef476500b22795e764f3cce62c755d /gcc
parent6483f05989ef31ebf2583deeb4753211ca2b7e17 (diff)
downloadgcc-32ee472864ada44ef05b2a3b087b8ce413bee282.zip
gcc-32ee472864ada44ef05b2a3b087b8ce413bee282.tar.gz
gcc-32ee472864ada44ef05b2a3b087b8ce413bee282.tar.bz2
Improve overflow check
Convert x < (short) ((unsigned short)x + const) to x <= SHORT_MAX – const (and similarly for other integral types) if const is not 0. gcc/ PR tree-optimization/97223 * match.pd (overflow detection and optimization): Handle conversions. gcc/testsuite/ * gcc.dg/no-strict-overflow-4.c: Adjust expected output.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/match.pd16
-rw-r--r--gcc/testsuite/gcc.dg/no-strict-overflow-4.c5
2 files changed, 13 insertions, 8 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index d82a620..349eab6 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4945,18 +4945,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* When one argument is a constant, overflow detection can be simplified.
Currently restricted to single use so as not to interfere too much with
ADD_OVERFLOW detection in tree-ssa-math-opts.c.
- A + CST CMP A -> A CMP' CST' */
+ CONVERT?(CONVERT?(A) + CST) CMP A -> A CMP' CST' */
(for cmp (lt le ge gt)
out (gt gt le le)
(simplify
- (cmp:c (plus@2 @0 INTEGER_CST@1) @0)
- (if (TYPE_UNSIGNED (TREE_TYPE (@0))
- && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))
+ (cmp:c (convert?@3 (plus@2 (convert?@4 @0) INTEGER_CST@1)) @0)
+ (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@2))
+ && types_match (TREE_TYPE (@0), TREE_TYPE (@3))
+ && tree_nop_conversion_p (TREE_TYPE (@4), TREE_TYPE (@0))
&& wi::to_wide (@1) != 0
&& single_use (@2))
- (with { unsigned int prec = TYPE_PRECISION (TREE_TYPE (@0)); }
+ (with {
+ unsigned int prec = TYPE_PRECISION (TREE_TYPE (@0));
+ signop sign = TYPE_SIGN (TREE_TYPE (@0));
+ }
(out @0 { wide_int_to_tree (TREE_TYPE (@0),
- wi::max_value (prec, UNSIGNED)
+ wi::max_value (prec, sign)
- wi::to_wide (@1)); })))))
/* To detect overflow in unsigned A - B, A < B is simpler than A - B > A.
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-4.c b/gcc/testsuite/gcc.dg/no-strict-overflow-4.c
index b6d3da3..90145ff9 100644
--- a/gcc/testsuite/gcc.dg/no-strict-overflow-4.c
+++ b/gcc/testsuite/gcc.dg/no-strict-overflow-4.c
@@ -4,7 +4,8 @@
/* Source: Ian Lance Taylor. Dual of strict-overflow-4.c. */
/* We can only simplify the conditional when using strict overflow
- semantics. */
+ semantics or when using wrap overflow semantics. -fno-strict-overflow is
+ equivalent to -fwrapv. */
int
foo (int i)
@@ -12,4 +13,4 @@ foo (int i)
return i + 1 > i;
}
-/* { dg-final { scan-tree-dump "\[^ \]*_.(\\\(D\\\))? (>|<) \[^ \]*_." "optimized" } } */
+/* { dg-final { scan-tree-dump "\[^ \]*_.(\\\(D\\\))? != \[0-9]+" "optimized" } } */