This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: More type narrowing in match.pd


On Wed, 29 Apr 2015, Jeff Law wrote:

This is an incremental improvement to the type narrowing in match.pd. It's largely based on the pattern I added to fix 47477.

Basically if we have

(bit_and (arith_op (convert A) (convert B)) mask)

Where the conversions are widening and the mask turns off all bits outside the original types of A & B, then we can turn that into

(bit_and (arith_op A B) mask)

We may need to convert A & B to an unsigned type with the same width/precision as their original type, but that's still better than a widening conversion.

Bootstrapped and regression tested on x86_64-linux-gnu.

OK for the trunk?

+/* 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)

+  (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.

+    (if (INTEGRAL_TYPE_P (type)

Can this be false, or is it for documentation?

+        /* 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 ;-)

+        && (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.

+        && (tree_int_cst_min_precision (@4, UNSIGNED)
+            <= TYPE_PRECISION (TREE_TYPE (@0))))
+      (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+       (with { tree ntype = TREE_TYPE (@0); }
+         (convert (bit_and (op @0 @1) (convert:ntype @4)))))
+      (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
+       (convert (bit_and (op (convert:utype @0) (convert:utype @1))
+                         (convert:utype @4)))))))


--
Marc Glisse


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]