This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, GCC] PR middle-end/55299, fold bitnot through ASR and rotates
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: Mikhail Maltsev <maltsevm at gmail dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Richard Biener <richard dot guenther at gmail dot com>
- Date: Wed, 11 May 2016 09:52:05 +0200 (CEST)
- Subject: Re: [PATCH, GCC] PR middle-end/55299, fold bitnot through ASR and rotates
- Authentication-results: sourceware.org; auth=none
- References: <572F6B36 dot 8050804 at gmail dot com> <alpine dot DEB dot 2 dot 20 dot 1605082148450 dot 2068 at laptop-mg dot saclay dot inria dot fr> <5731E816 dot 9050006 at gmail dot com>
- Reply-to: gcc-patches at gcc dot gnu dot org
On Tue, 10 May 2016, Mikhail Maltsev wrote:
On 05/08/2016 10:57 PM, Marc Glisse wrote:
On Sun, 8 May 2016, Mikhail Maltsev wrote:
Hi!
I decided to revive this patch:
https://gcc.gnu.org/ml/gcc-patches/2015-06/msg00999.html.
I addressed review comments about sign conversions. Bootstrapped and regtested
on x86_64-linux-gnu {,-m32}. OK for trunk?
Hello,
are you sure that your transformations are safe for any kind of conversion?
Oops, indeed, only narrowing conversions should be allowed. I updated the patch
and added some more test cases.
+/* ~((~X) >> Y) -> X >> Y (for arithmetic shift). */
+(simplify
+ (bit_not (convert? (rshift (bit_not @0) @1)))
+ (if (!TYPE_UNSIGNED (TREE_TYPE (@0))
+ && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@0)))
+ (convert (rshift @0 @1))))
Is there a particular reason to split the converting / non-converting
cases? For rotate, you managed to merge them nicely.
+
+(simplify
+ (bit_not (convert? (rshift (convert@0 (bit_not @1)) @2)))
+ (if (!TYPE_UNSIGNED (TREE_TYPE (@0))
+ && TYPE_PRECISION (TREE_TYPE (@0)) <= TYPE_PRECISION (TREE_TYPE (@1))
+ && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@0)))
+ (with
+ { tree shift_type = TREE_TYPE (@0); }
+ (convert (rshift:shift_type (convert @1) @2)))))
+
+/* Same as above, but for rotates. */
+(for rotate (lrotate rrotate)
+ (simplify
+ (bit_not (convert1?@0 (rotate (convert2?@1 (bit_not @2)) @3)))
+ (if (TYPE_PRECISION (TREE_TYPE (@1)) <= TYPE_PRECISION (TREE_TYPE (@2))
+ && TYPE_PRECISION (TREE_TYPE (@0)) <= TYPE_PRECISION (TREE_TYPE (@1)))
+ (with
+ { tree operand_type = TREE_TYPE (@2); }
+ (convert (rotate:operand_type @2 @3))))))
Is that really safe when the conversion from @2 to @1 is narrowing? I
would expect something closer to
(convert (rotate (convert:type_of_1 @2) @3))
so the rotation is done in a type of the same precision as the original.
Or
(convert (rotate:type_of_1 (convert @2) @3))
if you prefer specifying the type there (I don't), and note that you
need the 'convert' inside or specifying the type on rotate doesn't work.
I have a slight preference for element_precision over TYPE_PRECISION
(which for vectors is the number of elements), but I don't think it can
currently cause issues for these particular transformations.
I don't know if we might want some :c / single_use restrictions, maybe
on the outer convert and the rshift/rotate.
--
Marc Glisse