From 1ce0b26e6e1e6c348b1d54f1f462a44df6fe47f5 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 26 Jul 2021 09:40:32 -0400 Subject: [PATCH] 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. --- gcc/gimple-range-fold.cc | 32 ++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr78888.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr78888.c diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index f95af3d5866..8465b4a82f6 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 00000000000..77a130cf11c --- /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"} } */