diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2021-07-26 09:40:32 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2021-07-26 14:14:30 -0400 |
commit | 1ce0b26e6e1e6c348b1d54f1f462a44df6fe47f5 (patch) | |
tree | 585616944ff4855f91c893e3ebb4d0854bab097f /gcc | |
parent | cf5f544227f16b63e224529190329eb0edca791c (diff) | |
download | gcc-1ce0b26e6e1e6c348b1d54f1f462a44df6fe47f5.zip gcc-1ce0b26e6e1e6c348b1d54f1f462a44df6fe47f5.tar.gz gcc-1ce0b26e6e1e6c348b1d54f1f462a44df6fe47f5.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-range-fold.cc | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr78888.c | 29 |
2 files changed, 61 insertions, 0 deletions
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index f95af3d..8465b4a 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -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]. diff --git a/gcc/testsuite/gcc.dg/pr78888.c b/gcc/testsuite/gcc.dg/pr78888.c new file mode 100644 index 0000000..77a130c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr78888.c @@ -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"} } */ |