This is the mail archive of the
mailing list for the GCC project.
Re: [RFC][PR target/39726 P4 regression] match.pd pattern to do type narrowing
- From: Jeff Law <law at redhat dot com>
- To: Joseph Myers <joseph at codesourcery dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sun, 08 Feb 2015 00:42:54 -0700
- Subject: Re: [RFC][PR target/39726 P4 regression] match.pd pattern to do type narrowing
- Authentication-results: sourceware.org; auth=none
- References: <54CC560B dot 8080200 at redhat dot com> <alpine dot DEB dot 2 dot 10 dot 1502010039210 dot 23456 at digraph dot polyomino dot org dot uk> <54CDBDC6 dot 3050000 at redhat dot com> <alpine dot DEB dot 2 dot 10 dot 1502021655230 dot 20528 at digraph dot polyomino dot org dot uk> <54CFBC2E dot 2040602 at redhat dot com> <54D076BC dot 9080504 at redhat dot com> <alpine dot DEB dot 2 dot 10 dot 1502031204440 dot 11494 at digraph dot polyomino dot org dot uk>
On 02/03/15 05:23, Joseph Myers wrote:
On Tue, 3 Feb 2015, Jeff Law wrote:
+/* Given a bit-wise operation performed in mode P1 on operands
+ in some narrower type P2 that feeds an outer masking operation.
+ See if the mask turns off all the bits outside P2, and if so
+ perform the all the operations in P2 and just convert the final
+ result from P1 to P2. */
+(for inner_op (bit_and bit_ior bit_xor)
+ (bit_and (inner_op (convert @0) (convert @1)) INTEGER_CST@3)
+ (if ((TREE_INT_CST_LOW (@3) & ~GET_MODE_MASK (TYPE_MODE (TREE_TYPE (@0)))) == 0
Are you sure about checking TREE_INT_CST_LOW here? What if the inner type
is wider than HOST_WIDE_INT? (That could occur with bit-fields of type
__int128, for example.) I think the check for what bits are set needs to
be written in a wide-int-safe way - maybe something like tree_int_cst_sgn
(@3) > 0 && tree_int_cst_min_precision (@3, UNSIGNED) <= TYPE_PRECISION
It's a WIP :-)
+ && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1))
+ && TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@1))
+ && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0)))
+ (convert (bit_and (inner_op @0 @1) (convert @3))))))
I still don't think this is safe. Suppose @0 and @1 are -128 in type
int8_t and @3 is 128 in a wider type and the operation is AND. Then the
original expression has result 128. But if you convert @3 to int8_t you
get -128 and this would result in -128 from the simplified expression.
FWIW I did figure out how to get at an expression's type (you can
capture them just like individual operands). This is important because
if we introduce that signed->unsigned conversions, we have to avoid
infinite recursion of the pattern and the easiest way is actually to
look at the various types.
If the inner values are signed and the mask includes the sign bit of the
inner type, you have to zero-extend to the wider type (e.g. convert the
inner values to unsigned), not sign-extend.
(If the inner values are signed, it's *also* valid to optimize with a mask
where both the sign bit of the inner type and all higher bits are set,
such as a mask of -128 above; in that case, you do need to sign-extend.
If the inner values are unsigned, no check on the mask value is needed at
all as all higher bits in the mask can just be discarded. Both of these
statements only apply for bitwise operations, not arithmetic.)
Thanks. I'm going to go through another iteration on this stuff. I'm
less concerned about this particular PR, but the knowledge gained here
looks to be helpful for 45397 which looks like it might be solveable
with match.pd patterns too.