diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-12-10 12:06:12 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-12-10 12:06:12 +0000 |
commit | fbfc787444e42303f3a4950ba92b389d2f0e3f2a (patch) | |
tree | 1c3ee7a1e61c83a5cfcca91584530a3b01495645 /gcc/match.pd | |
parent | 30a04590e24ee70915dec0bfa6088b07ce898cd9 (diff) | |
download | gcc-fbfc787444e42303f3a4950ba92b389d2f0e3f2a.tar.gz |
PR tree-optimization/78720
* match.pd (A < 0 ? C : 0): Only optimize for signed A. If shift
is negative, sign extend to @1's type and than AND with C.
* gcc.c-torture/execute/pr78720.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243516 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/match.pd')
-rw-r--r-- | gcc/match.pd | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index feaa4a14478..f4cc2d810c3 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2768,17 +2768,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (ncmp (convert:stype @0) { build_zero_cst (stype); }))))) /* If we have A < 0 ? C : 0 where C is a power of 2, convert - this into a right shift followed by ANDing with C. */ + this into a right shift or sign extension followed by ANDing with C. */ (simplify (cond (lt @0 integer_zerop) integer_pow2p@1 integer_zerop) - (with { + (if (!TYPE_UNSIGNED (TREE_TYPE (@0))) + (with { int shift = element_precision (@0) - wi::exact_log2 (@1) - 1; - } - (bit_and - (convert (rshift @0 { build_int_cst (integer_type_node, shift); })) - @1))) + } + (if (shift >= 0) + (bit_and + (convert (rshift @0 { build_int_cst (integer_type_node, shift); })) + @1) + /* Otherwise ctype must be wider than TREE_TYPE (@0) and pure + sign extension followed by AND with C will achieve the effect. */ + (bit_and (convert @0) @1))))) /* When the addresses are not directly of decls compare base and offset. This implements some remaining parts of fold_comparison address |