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.
This commit is contained in:
Jeff Law 2020-11-05 20:42:17 -07:00
parent 6483f05989
commit 32ee472864
2 changed files with 13 additions and 8 deletions

View File

@ -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.

View File

@ -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" } } */