This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix A < 0 ? C : 0 optimization (PR tree-optimization/78720)
On Sat, 10 Dec 2016, Jakub Jelinek wrote:
* match.pd (A < 0 ? C : 0): Only optimize for signed A. If shift
is negative, first convert to @1's type and then lshift it by -shift.
Thanks, the ChangeLog needs updating.
--- gcc/match.pd.jj 2016-12-09 10:19:10.909735559 +0100
+++ gcc/match.pd 2016-12-10 09:21:26.260516596 +0100
@@ -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)))))
It is funny to notice that the fact that @1 is a power of 2 has become
mostly irrelevant. When C fits in the type of A, we can do an arithmetic
shift right of precision-1 to obtain a mask of 0 or -1, then bit_and works
not just for powers of 2. Otherwise, imagining that A is int32_t and C
int64_t, all we care about is that the low 31 bits of C are 0 (otherwise
we could also do an arithmetic right shift, either before or after the
convert). But that's another patch, fixing the PR is what matters for now.
--
Marc Glisse