diff options
author | Yury Gribov <tetra2005@gmail.com> | 2017-06-13 11:13:52 +0000 |
---|---|---|
committer | Maxim Ostapenko <chefmax@gcc.gnu.org> | 2017-06-13 14:13:52 +0300 |
commit | 16842d34e7fceebcecc24910e9219a1581fffb32 (patch) | |
tree | b8dfa51c6b364f24b5de6aa6cf85779c233e4c24 /gcc | |
parent | ba593ad58f849c711afc0f2255630757e020ccda (diff) | |
download | gcc-16842d34e7fceebcecc24910e9219a1581fffb32.zip gcc-16842d34e7fceebcecc24910e9219a1581fffb32.tar.gz gcc-16842d34e7fceebcecc24910e9219a1581fffb32.tar.bz2 |
re PR tree-optimization/67328 (range test rather than single bit test for code testing enum values)
2017-06-13 Yury Gribov <tetra2005@gmail.com>
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 43 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/fold-masked-cmp-1.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/fold-masked-cmp-2.c | 42 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr46309-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr46309.c | 2 |
7 files changed, 141 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 344e5fa..83f0480 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-06-13 Yury Gribov <tetra2005@gmail.com> + + PR tree-optimization/67328 + * fold-const.c (maskable_range_p): New function. + (build_range_check): Generate bittests if possible. + 2017-06-13 Martin Liska <mliska@suse.cz> * gimple-pretty-print.c (dump_probability): Add new argument. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a6dd274..74bbdb0 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 9f4b020..678b892 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2017-06-13 Yury Gribov <tetra2005@gmail.com> + + 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 <tamar.christina@arm.com> * 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 0000000..a0e9083 --- /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 0000000..13d068a --- /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 39b9b83..f56df42 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 f362ac3..68229cf 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" } } */ |