Adjust ranges for to_upper and to_lower.
Exclude lower case chars from to_upper and upper case chars from to_lower. gcc/ PR tree-optimization/78888 * gimple-range-fold.cc (fold_using_range::range_of_builtin_call): Add cases for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER. gcc/testsuite/ * gcc.dg/pr78888.c: New.
This commit is contained in:
parent
cf5f544227
commit
1ce0b26e6e
@ -868,6 +868,38 @@ fold_using_range::range_of_builtin_call (irange &r, gcall *call,
|
||||
}
|
||||
break;
|
||||
|
||||
case CFN_BUILT_IN_TOUPPER:
|
||||
{
|
||||
arg = gimple_call_arg (call, 0);
|
||||
if (!src.get_operand (r, arg))
|
||||
return false;
|
||||
// Return the range passed in without any lower case characters,
|
||||
// but including all the upper case ones.
|
||||
int_range<2> exclude (build_int_cst (type, 'a'),
|
||||
build_int_cst (type, 'z'), VR_ANTI_RANGE);
|
||||
r.intersect (exclude);
|
||||
int_range<2> uppers (build_int_cst (type, 'A'),
|
||||
build_int_cst (type, 'Z'));
|
||||
r.union_ (uppers);
|
||||
return true;
|
||||
}
|
||||
|
||||
case CFN_BUILT_IN_TOLOWER:
|
||||
{
|
||||
arg = gimple_call_arg (call, 0);
|
||||
if (!src.get_operand (r, arg))
|
||||
return false;
|
||||
// Return the range passed in without any upper case characters,
|
||||
// but including all the lower case ones.
|
||||
int_range<2> exclude (build_int_cst (type, 'A'),
|
||||
build_int_cst (type, 'Z'), VR_ANTI_RANGE);
|
||||
r.intersect (exclude);
|
||||
int_range<2> lowers (build_int_cst (type, 'a'),
|
||||
build_int_cst (type, 'z'));
|
||||
r.union_ (lowers);
|
||||
return true;
|
||||
}
|
||||
|
||||
CASE_CFN_FFS:
|
||||
CASE_CFN_POPCOUNT:
|
||||
// __builtin_ffs* and __builtin_popcount* return [0, prec].
|
||||
|
29
gcc/testsuite/gcc.dg/pr78888.c
Normal file
29
gcc/testsuite/gcc.dg/pr78888.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* PR tree-optimization/78888 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-evrp" } */
|
||||
|
||||
void kill (void);
|
||||
void keep (void);
|
||||
|
||||
void g (int x)
|
||||
{
|
||||
if (__builtin_toupper ((unsigned char)x) == 'a')
|
||||
kill ();
|
||||
if (__builtin_toupper ((unsigned char)x) == 'z')
|
||||
kill ();
|
||||
if (__builtin_tolower ((unsigned char)x) == 'A')
|
||||
kill ();
|
||||
if (__builtin_tolower ((unsigned char)x) == 'Z')
|
||||
kill ();
|
||||
|
||||
if (__builtin_toupper ((unsigned char)x) == 'A')
|
||||
keep ();
|
||||
if (__builtin_toupper ((unsigned char)x) == 'Z')
|
||||
keep ();
|
||||
if (__builtin_tolower ((unsigned char)x) == 'a')
|
||||
keep ();
|
||||
if (__builtin_tolower ((unsigned char)x) == 'z')
|
||||
keep ();
|
||||
}
|
||||
/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
|
||||
/* { dg-final { scan-tree-dump-times "keep" 4 "evrp"} } */
|
Loading…
Reference in New Issue
Block a user