Commit 16842d34 by Yury Gribov Committed by Maxim Ostapenko

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
parent ba593ad5
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> 2017-06-13 Martin Liska <mliska@suse.cz>
* gimple-pretty-print.c (dump_probability): Add new argument. * gimple-pretty-print.c (dump_probability): Add new argument.
......
...@@ -4745,6 +4745,40 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh, ...@@ -4745,6 +4745,40 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
*pin_p = in_p, *plow = low, *phigh = high; *pin_p = in_p, *plow = low, *phigh = high;
return exp; 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 /* 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 type, TYPE, return an expression to test if EXP is in (or out of, depending
...@@ -4754,7 +4788,7 @@ tree ...@@ -4754,7 +4788,7 @@ tree
build_range_check (location_t loc, tree type, tree exp, int in_p, build_range_check (location_t loc, tree type, tree exp, int in_p,
tree low, tree high) tree low, tree high)
{ {
tree etype = TREE_TYPE (exp), value; tree etype = TREE_TYPE (exp), mask, value;
/* Disable this optimization for function pointer expressions /* Disable this optimization for function pointer expressions
on targets that require function pointer canonicalization. */ on targets that require function pointer canonicalization. */
...@@ -4787,6 +4821,13 @@ build_range_check (location_t loc, tree type, tree exp, int in_p, ...@@ -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, return fold_build2_loc (loc, EQ_EXPR, type, exp,
fold_convert_loc (loc, etype, low)); 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 (integer_zerop (low))
{ {
if (! TYPE_UNSIGNED (etype)) if (! TYPE_UNSIGNED (etype))
......
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> 2017-06-13 Tamar Christina <tamar.christina@arm.com>
* gcc.target/arm/sdiv_costs_1.c: * gcc.target/arm/sdiv_costs_1.c:
......
/* 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 } } */
/* 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 } } */
...@@ -142,4 +142,4 @@ f10 (int a) ...@@ -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. -.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. -.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 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" } } */
...@@ -65,4 +65,4 @@ f6 (unsigned int a) ...@@ -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. -.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. -.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 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment