From 16842d34e7fceebcecc24910e9219a1581fffb32 Mon Sep 17 00:00:00 2001 From: Yury Gribov Date: Tue, 13 Jun 2017 11:13:52 +0000 Subject: [PATCH] re PR tree-optimization/67328 (range test rather than single bit test for code testing enum values) 2017-06-13 Yury Gribov gcc/ PR tree-optimization/67328 * fold-const.c (maskable_range_p): New function. (build_range_check): Generate bittests if possible. gcc/testsuite/ PR tree-optimization/67328 * c-c++-common/fold-masked-cmp-1.c: New test. * c-c++-common/fold-masked-cmp-2.c: Likewise. * gcc.dg/pr46309.c: Fix pattern. * gcc.dg/pr46309-2.c: Likewise. From-SVN: r249149 --- gcc/ChangeLog | 6 +++ gcc/fold-const.c | 43 ++++++++++++++++++- gcc/testsuite/ChangeLog | 8 ++++ .../c-c++-common/fold-masked-cmp-1.c | 41 ++++++++++++++++++ .../c-c++-common/fold-masked-cmp-2.c | 42 ++++++++++++++++++ gcc/testsuite/gcc.dg/pr46309-2.c | 2 +- gcc/testsuite/gcc.dg/pr46309.c | 2 +- 7 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/fold-masked-cmp-1.c create mode 100644 gcc/testsuite/c-c++-common/fold-masked-cmp-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 344e5fa43b3..83f048001fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-06-13 Yury Gribov + + PR tree-optimization/67328 + * fold-const.c (maskable_range_p): New function. + (build_range_check): Generate bittests if possible. + 2017-06-13 Martin Liska * gimple-pretty-print.c (dump_probability): Add new argument. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a6dd274f3d2..74bbdb07ffb 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4745,6 +4745,40 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh, *pin_p = in_p, *plow = low, *phigh = high; return exp; } + +/* Returns TRUE if [LOW, HIGH] range check can be optimized to + a bitwise check i.e. when + LOW == 0xXX...X00...0 + HIGH == 0xXX...X11...1 + Return corresponding mask in MASK and stem in VALUE. */ + +static bool +maskable_range_p (const_tree low, const_tree high, tree type, tree *mask, + tree *value) +{ + if (TREE_CODE (low) != INTEGER_CST + || TREE_CODE (high) != INTEGER_CST) + return false; + + unsigned prec = TYPE_PRECISION (type); + wide_int lo = wi::to_wide (low, prec); + wide_int hi = wi::to_wide (high, prec); + + wide_int end_mask = lo ^ hi; + if ((end_mask & (end_mask + 1)) != 0 + || (lo & end_mask) != 0) + return false; + + wide_int stem_mask = ~end_mask; + wide_int stem = lo & stem_mask; + if (stem != (hi & stem_mask)) + return false; + + *mask = wide_int_to_tree (type, stem_mask); + *value = wide_int_to_tree (type, stem); + + return true; +} /* Given a range, LOW, HIGH, and IN_P, an expression, EXP, and a result type, TYPE, return an expression to test if EXP is in (or out of, depending @@ -4754,7 +4788,7 @@ tree build_range_check (location_t loc, tree type, tree exp, int in_p, tree low, tree high) { - tree etype = TREE_TYPE (exp), value; + tree etype = TREE_TYPE (exp), mask, value; /* Disable this optimization for function pointer expressions on targets that require function pointer canonicalization. */ @@ -4787,6 +4821,13 @@ build_range_check (location_t loc, tree type, tree exp, int in_p, return fold_build2_loc (loc, EQ_EXPR, type, exp, fold_convert_loc (loc, etype, low)); + if (TREE_CODE (exp) == BIT_AND_EXPR + && maskable_range_p (low, high, etype, &mask, &value)) + return fold_build2_loc (loc, EQ_EXPR, type, + fold_build2_loc (loc, BIT_AND_EXPR, etype, + exp, mask), + value); + if (integer_zerop (low)) { if (! TYPE_UNSIGNED (etype)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f4b020a626..678b89287cc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2017-06-13 Yury Gribov + + PR tree-optimization/67328 + * c-c++-common/fold-masked-cmp-1.c: New test. + * c-c++-common/fold-masked-cmp-2.c: Likewise. + * gcc.dg/pr46309.c: Fix pattern. + * gcc.dg/pr46309-2.c: Likewise. + 2017-06-13 Tamar Christina * gcc.target/arm/sdiv_costs_1.c: diff --git a/gcc/testsuite/c-c++-common/fold-masked-cmp-1.c b/gcc/testsuite/c-c++-common/fold-masked-cmp-1.c new file mode 100644 index 00000000000..a0e9083709e --- /dev/null +++ b/gcc/testsuite/c-c++-common/fold-masked-cmp-1.c @@ -0,0 +1,41 @@ +/* Based on PR 67328 */ + +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-options "-O2" } */ + +enum output_type +{ + type_pde, + type_pie, + type_relocatable, + type_dll, +}; + +struct bfd_link_info +{ + enum output_type type : 2; + unsigned int pad : 30; +}; + +#define bfd_link_pde(info) ((info)->type == type_pde) +#define bfd_link_dll(info) ((info)->type == type_dll) +#define bfd_link_relocatable(info) ((info)->type == type_relocatable) +#define bfd_link_pie(info) ((info)->type == type_pie) +#define bfd_link_executable(info) (bfd_link_pde (info) || bfd_link_pie (info)) +#define bfd_link_pic(info) (bfd_link_dll (info) || bfd_link_pie (info)) + +int result; + +void test_pic (struct bfd_link_info *info) +{ + if (bfd_link_pic (info)) + result++; +} + +int test_exe (struct bfd_link_info *info) +{ + if (bfd_link_executable (info)) + result++; +} + +/* { dg-final { scan-assembler-times "testn?b" 2 } } */ diff --git a/gcc/testsuite/c-c++-common/fold-masked-cmp-2.c b/gcc/testsuite/c-c++-common/fold-masked-cmp-2.c new file mode 100644 index 00000000000..13d068aa1e0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fold-masked-cmp-2.c @@ -0,0 +1,42 @@ +/* Based on PR 67328 */ + +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-options "-O2" } */ + +enum output_type +{ + type_pde, + type_relocatable, + type_pie, + type_dll, +}; + +struct bfd_link_info +{ + enum output_type type : 2; + unsigned int pad : 30; +}; + +#define bfd_link_pde(info) ((info)->type == type_pde) +#define bfd_link_dll(info) ((info)->type == type_dll) +#define bfd_link_relocatable(info) ((info)->type == type_relocatable) +#define bfd_link_pie(info) ((info)->type == type_pie) +#define bfd_link_executable(info) (bfd_link_pde (info) || bfd_link_pie (info)) +#define bfd_link_pic(info) (bfd_link_dll (info) || bfd_link_pie (info)) + +int result; + +void test_pic (struct bfd_link_info *info) +{ + if (bfd_link_pic (info)) + result++; +} + +int test_exe (struct bfd_link_info *info) +{ + if (bfd_link_executable (info)) + result++; +} + +/* { dg-final { scan-assembler-times "testn?b" 2 } } */ + diff --git a/gcc/testsuite/gcc.dg/pr46309-2.c b/gcc/testsuite/gcc.dg/pr46309-2.c index 39b9b8377f7..f56df42935c 100644 --- a/gcc/testsuite/gcc.dg/pr46309-2.c +++ b/gcc/testsuite/gcc.dg/pr46309-2.c @@ -142,4 +142,4 @@ f10 (int a) /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.0, 31. and -.64, 95.\[\n\r\]* into" 1 "reassoc1" } } */ /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.128, 159. and -.192, 223.\[\n\r\]* into" 1 "reassoc1" } } */ /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.1, 1. and -.2, 2. and -.3, 3. and -.4, 4. and -.5, 5. and -.6, 6. and -.7, 7. and -.8, 8.\[\n\r\]* into" 7 "reassoc1" } } */ -/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 31. and -.128, 159.\[\n\r\]* into" 1 "reassoc2" } } */ +/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 0. and -.128, 128.\[\n\r\]* into" 1 "reassoc2" } } */ diff --git a/gcc/testsuite/gcc.dg/pr46309.c b/gcc/testsuite/gcc.dg/pr46309.c index f362ac3eb42..68229cf61d9 100644 --- a/gcc/testsuite/gcc.dg/pr46309.c +++ b/gcc/testsuite/gcc.dg/pr46309.c @@ -65,4 +65,4 @@ f6 (unsigned int a) /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.1, 1. and -.2, 2.\[\n\r\]* into" 1 "reassoc1" } } */ /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.0, 31. and -.64, 95.\[\n\r\]* into" 2 "reassoc1" } } */ /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.128, 159. and -.192, 223.\[\n\r\]* into" 1 "reassoc1" } } */ -/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 31. and -.128, 159.\[\n\r\]* into" 1 "reassoc2" } } */ +/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 0. and -.128, 128.\[\n\r\]* into" 1 "reassoc2" } } */ -- 2.30.2