On 04/30/2015 01:17 AM, Marc Glisse wrote:
+/* This is another case of narrowing, specifically when there's an outer
+ BIT_AND_EXPR which masks off bits outside the type of the innermost
+ operands. Like the previous case we have to convert the operands
+ to unsigned types to avoid introducing undefined behaviour for the
+ arithmetic operation. */
+(for op (minus plus)
No mult? or widen_mult with a different pattern? (maybe that's already
done elsewhere)
No mult. When I worked on the pattern for 47477, supporting mult
clearly regressed the generated code -- presumably because we can often
widen the operands for free.
+ (simplify
+ (bit_and (op (convert@2 @0) (convert@3 @1)) INTEGER_CST@4)
Maybe op@5 and then test single_use on @5? If I compute something, and
before using it I test if the result is odd, I may not want to recompute
it.
Sure. That ought to be easy to add.
+ (if (INTEGRAL_TYPE_P (type)
Can this be false, or is it for documentation?
Can't recall a case where we were presented with a non-integral type,
but I haven't even tried to work though what might happen on
non-integral types. Better safe than sorry.
+ /* We check for type compatibility between @0 and @1 below,
+ so there's no need to check that @1/@3 are integral types. */
+ && INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && INTEGRAL_TYPE_P (TREE_TYPE (@2))
+ /* The precision of the type of each operand must match the
+ precision of the mode of each operand, similarly for the
+ result. */
A nicely named helper that does this test would be cool. Every time I
see it I have to think again why it is necessary, and if there was a
function, I could refer to the comment above its definition ;-)
Factoring helpers for this stuff is something I wanted to do a bit
latter as Kai and I build up the necessary patterns to eliminate the
C/C++ specific operand shortening and hopefully the set of helpers
needed becomes clearer.
The type_same_p helper clearly already makes sense as there's these two
shortening patterns and two others that need it. Given that & Richi's
request, I'll go ahead and factor that one out.
+ && (TYPE_PRECISION (TREE_TYPE (@0))
+ == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@0))))
+ && (TYPE_PRECISION (TREE_TYPE (@1))
+ == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@1))))
+ && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
+ /* The inner conversion must be a widening conversion. */
+ && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE
(@0))
+ && ((GENERIC + && (TYPE_MAIN_VARIANT (TREE_TYPE (@0))
+ == TYPE_MAIN_VARIANT (TREE_TYPE (@1))))
+ || (GIMPLE
+ && types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1))))
We don't need to be that strict, but this probably covers the most
common case.
Probably not. The idea was to start with what we know is right &
correct, then extend, particularly as we find/build testcases. THe
obvious extensions are those Richi pointed out in 47477, then again on
this thread. I'd like to tackle them as a follow-up and do so with both
patterns.
[ They weren't tackled as part of 47477 as I wanted to focus on fixing
the regression and didn't want to go much beyond what was necessary
to fix the regression. Obviously with stage1 open, it's time to
tackle the cases Richi pointed out that we can/should handle. ]
jeff