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

Reply via email to