[Bug tree-optimization/65084] Lack of type narrowing/widening inhibits good vectorization
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Feb 17 10:47:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65084
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2015-02-17
Ever confirmed|0 |1
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed. Btw, this is just the lack of shorten_* on the GIMPLE level. For
your match.pd pattern it is a matter of simplifying/changing it slightly:
Index: match.pd
===================================================================
--- match.pd (revision 220751)
+++ match.pd (working copy)
@@ -1031,31 +1031,22 @@ (define_operator_list CBRT BUILT_IN_CBRT
operation and convert the result to the desired type. */
(for op (plus minus)
(simplify
- (convert (op (convert@2 @0) (convert@3 @1)))
+ (convert (op:c@4 (convert@2 @0) (convert?@3 @1)))
(if (INTEGRAL_TYPE_P (type)
- /* 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))
+ && INTEGRAL_TYPE_P (TREE_TYPE (@4))
/* The precision of the type of each operand must match the
precision of the mode of each operand, similarly for the
result. */
&& (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)))
- && (TYPE_MAIN_VARIANT (TREE_TYPE (@0))
- == TYPE_MAIN_VARIANT (type)))
- || (GIMPLE
- && types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1))
- && types_compatible_p (TREE_TYPE (@0), type))))
+ /* The final precision should match that of operand @0. */
+ && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0))
+ /* Make sure the wide operation is dead after the transform. */
+ && (TREE_CODE (@4) != SSA_NAME || has_single_use (@4)))
(if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
- (convert (op @0 @1)))
+ (convert (op @0 (convert @1))))
(with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
(convert (op (convert:utype @0) (convert:utype @1)))))))
to allow for constant @1 (where the convert would be folded into the constant
itself). And we then get before vectorization:
<bb 3>:
# i_17 = PHI <i_13(4), 0(2)>
# ivtmp_30 = PHI <ivtmp_29(4), 1024(2)>
_5 = a[i_17];
_6 = (char) _5;
_7 = (unsigned short) _6;
_9 = b[i_17];
_3 = (unsigned short) _9;
_14 = _3 + 17;
_10 = _7 + _14;
_11 = (short int) _10;
a[i_17] = _11;
i_13 = i_17 + 1;
ivtmp_29 = ivtmp_30 - 1;
if (ivtmp_29 != 0)
goto <bb 4>;
and much better code.
I've added a single-use restriction to the arithmetic result and allow
the commutated form to match so we also get at (short)((long long)x + ((long
long)y + 12))).
More information about the Gcc-bugs
mailing list