diff mbox

Add a full_integral_type_p helper function

Message ID 87d17pdyxx.fsf@linaro.org
State New
Headers show

Commit Message

Richard Sandiford Aug. 21, 2017, 9:58 a.m. UTC
Richard Biener <richard.guenther@gmail.com> writes:
> On Fri, Aug 18, 2017 at 1:04 PM, Richard Sandiford
> <richard.sandiford@linaro.org> wrote:
>> Richard Biener <richard.guenther@gmail.com> writes:
>>> On Fri, Aug 18, 2017 at 10:10 AM, Richard Sandiford
>>> <richard.sandiford@linaro.org> wrote:
>>>> There are several places that test whether:
>>>>
>>>>     TYPE_PRECISION (t) == GET_MODE_PRECISION (TYPE_MODE (t))
>>>>
>>>> for some integer type T.  With SVE variable-length modes, this would
>>>> need to become:
>>>>
>>>>     TYPE_PRECISION (t) == GET_MODE_PRECISION (SCALAR_TYPE_MODE (t))
>>>>
>>>> (or SCALAR_INT_TYPE_MODE, it doesn't matter which in this case).
>>>> But rather than add the "SCALAR_" everywhere, it seemed neater to
>>>> introduce a new helper function that tests whether T is an integral
>>>> type that has the same number of bits as its underlying mode.  This
>>>> patch does that, calling it full_integral_type_p.
>>>>
>>>> It isn't possible to use TYPE_MODE in tree.h because vector_type_mode
>>>> is defined in stor-layout.h, so for now the function accesses the mode
>>>> field directly.  After the 77-patch machine_mode series (thanks again
>>>> Jeff for the reviews) it would use SCALAR_TYPE_MODE instead.
>>>>
>>>> Of the changes that didn't previously have an INTEGRAL_TYPE_P check:
>>>>
>>>> - for fold_single_bit_test_into_sign_test it is obvious from the
>>>>   integer_foop tests that this is restricted to integral types.
>>>>
>>>> - vect_recog_vector_vector_shift_pattern is inherently restricted
>>>>   to integral types.
>>>>
>>>> - the register_edge_assert_for_2 hunk is dominated by:
>>>>
>>>>       TREE_CODE (val) == INTEGER_CST
>>>>
>>>> - the ubsan_instrument_shift hunk is preceded by an early exit:
>>>>
>>>>       if (!INTEGRAL_TYPE_P (type0))
>>>>         return NULL_TREE;
>>>>
>>>> - the second and third match.pd hunks are from:
>>>>
>>>>     /* Fold (X << C1) & C2 into (X << C1) & (C2 | ((1 << C1) - 1))
>>>>             (X >> C1) & C2 into (X >> C1) & (C2 | ~((type) -1 >> C1))
>>>>        if the new mask might be further optimized.  */
>>>>
>>>> I'm a bit confused about:
>>>>
>>>> /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST))
>>>>    when profitable.
>>>>    For bitwise binary operations apply operand conversions to the
>>>>    binary operation result instead of to the operands.  This allows
>>>>    to combine successive conversions and bitwise binary operations.
>>>>    We combine the above two cases by using a conditional convert.  */
>>>> (for bitop (bit_and bit_ior bit_xor)
>>>>  (simplify
>>>>   (bitop (convert @0) (convert? @1))
>>>>   (if (((TREE_CODE (@1) == INTEGER_CST
>>>>          && INTEGRAL_TYPE_P (TREE_TYPE (@0))
>>>>          && int_fits_type_p (@1, TREE_TYPE (@0)))
>>>>         || types_match (@0, @1))
>>>>        /* ???  This transform conflicts with fold-const.c doing
>>>>           Convert (T)(x & c) into (T)x & (T)c, if c is an integer
>>>>           constants (if x has signed type, the sign bit cannot be set
>>>>           in c).  This folds extension into the BIT_AND_EXPR.
>>>>           Restrict it to GIMPLE to avoid endless recursions.  */
>>>>        && (bitop != BIT_AND_EXPR || GIMPLE)
>>>>        && (/* That's a good idea if the conversion widens the operand, thus
>>>> after hoisting the conversion the operation will be narrower.  */
>>>>            TYPE_PRECISION (TREE_TYPE (@0)) < TYPE_PRECISION (type)
>>>>            /* It's also a good idea if the conversion is to a non-integer
>>>>               mode.  */
>>>>            || GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT
>>>>            /* Or if the precision of TO is not the same as the precision
>>>>               of its mode.  */
>>>> || TYPE_PRECISION (type) != GET_MODE_PRECISION (TYPE_MODE (type))))
>>>>    (convert (bitop @0 (convert @1))))))
>>>>
>>>> though.  The "INTEGRAL_TYPE_P (TREE_TYPE (@0))" suggests that we can't
>>>> rely on @0 and @1 being integral (although conversions from float would
>>>> use FLOAT_EXPR), but then what is:
>>>
>>> bit_and is valid on POINTER_TYPE and vector integer types
>>>
>>>>
>>>>            /* It's also a good idea if the conversion is to a non-integer
>>>>               mode.  */
>>>>            || GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT
>>>>
>>>> letting through?  MODE_PARTIAL_INT maybe, but that's a sort of integer
>>>> mode too.  MODE_COMPLEX_INT or MODE_VECTOR_INT?  I thought for those
>>>> it would be better to apply the scalar rules to the element type.
>>>
>>> I suppose extra caution ;)  I think I have seen BLKmode for not naturally
>>> aligned integer types at least on strict-align targets?  The code is
>>> a copy from original code in tree-ssa-forwprop.c.
>>>
>>>> Either way, having allowed all non-INT modes, using full_integral_type_p
>>>> for the remaining condition seems correct.
>>>>
>>>> If the feeling is that this isn't a useful abstraction, I can just update
>>>> each site individually to cope with variable-sized modes.
>>>
>>> I think "full_integral_type_p" is a name from which I cannot infer
>>> its meaning.  Maybe type_has_mode_precision_p?  Or
>>> type_matches_mode_p?
>>
>> type_has_mode_precision_p sounds good.  With that name I guess it
>> should be written to cope with all types (even those with variable-
>> width modes), so I think we'd need to continue using TYPE_MODE.
>> The VECTOR_MODE_P check should get optimised away in most of
>> the cases touched by the patch though.
>>
>> Would it be OK to move the declaration of vector_type_mode to tree.h
>> so that type_has_mode_precision_p can be inline?
>
> Just move the implementation to tree.c then.

OK, I posted that as: https://gcc.gnu.org/ml/gcc-patches/2017-08/msg01184.html

Here's the patch to add type_has_mode_precision_p.  Tested on
aarch64-linux-gnu and x86_64-linux-gnu, and by diffing the before and
after testsuite assembly for one target per CPU (there were no differences).
OK to install?

Thanks,
Richard


2017-08-21  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* tree.h (type_has_mode_precision_p): New function.
	* convert.c (convert_to_integer_1): Use it.
	* expr.c (expand_expr_real_2): Likewise.
	(expand_expr_real_1): Likewise.
	* fold-const.c (fold_single_bit_test_into_sign_test): Likewise.
	* match.pd: Likewise.
	* tree-ssa-forwprop.c (simplify_rotate): Likewise.
	* tree-ssa-math-opts.c (convert_mult_to_fma): Likewise.
	* tree-tailcall.c (process_assignment): Likewise.
	* tree-vect-loop.c (vectorizable_reduction): Likewise.
	* tree-vect-patterns.c (vect_recog_vector_vector_shift_pattern)
	(vect_recog_mult_pattern, vect_recog_divmod_pattern): Likewise.
	* tree-vect-stmts.c (vectorizable_conversion): Likewise.
	(vectorizable_assignment): Likewise.
	(vectorizable_shift): Likewise.
	(vectorizable_operation): Likewise.
	* tree-vrp.c (register_edge_assert_for_2): Likewise.

Comments

Richard Biener Aug. 21, 2017, 12:55 p.m. UTC | #1
On Mon, Aug 21, 2017 at 11:58 AM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> Richard Biener <richard.guenther@gmail.com> writes:
>> On Fri, Aug 18, 2017 at 1:04 PM, Richard Sandiford
>> <richard.sandiford@linaro.org> wrote:
>>> Richard Biener <richard.guenther@gmail.com> writes:
>>>> On Fri, Aug 18, 2017 at 10:10 AM, Richard Sandiford
>>>> <richard.sandiford@linaro.org> wrote:
>>>>> There are several places that test whether:
>>>>>
>>>>>     TYPE_PRECISION (t) == GET_MODE_PRECISION (TYPE_MODE (t))
>>>>>
>>>>> for some integer type T.  With SVE variable-length modes, this would
>>>>> need to become:
>>>>>
>>>>>     TYPE_PRECISION (t) == GET_MODE_PRECISION (SCALAR_TYPE_MODE (t))
>>>>>
>>>>> (or SCALAR_INT_TYPE_MODE, it doesn't matter which in this case).
>>>>> But rather than add the "SCALAR_" everywhere, it seemed neater to
>>>>> introduce a new helper function that tests whether T is an integral
>>>>> type that has the same number of bits as its underlying mode.  This
>>>>> patch does that, calling it full_integral_type_p.
>>>>>
>>>>> It isn't possible to use TYPE_MODE in tree.h because vector_type_mode
>>>>> is defined in stor-layout.h, so for now the function accesses the mode
>>>>> field directly.  After the 77-patch machine_mode series (thanks again
>>>>> Jeff for the reviews) it would use SCALAR_TYPE_MODE instead.
>>>>>
>>>>> Of the changes that didn't previously have an INTEGRAL_TYPE_P check:
>>>>>
>>>>> - for fold_single_bit_test_into_sign_test it is obvious from the
>>>>>   integer_foop tests that this is restricted to integral types.
>>>>>
>>>>> - vect_recog_vector_vector_shift_pattern is inherently restricted
>>>>>   to integral types.
>>>>>
>>>>> - the register_edge_assert_for_2 hunk is dominated by:
>>>>>
>>>>>       TREE_CODE (val) == INTEGER_CST
>>>>>
>>>>> - the ubsan_instrument_shift hunk is preceded by an early exit:
>>>>>
>>>>>       if (!INTEGRAL_TYPE_P (type0))
>>>>>         return NULL_TREE;
>>>>>
>>>>> - the second and third match.pd hunks are from:
>>>>>
>>>>>     /* Fold (X << C1) & C2 into (X << C1) & (C2 | ((1 << C1) - 1))
>>>>>             (X >> C1) & C2 into (X >> C1) & (C2 | ~((type) -1 >> C1))
>>>>>        if the new mask might be further optimized.  */
>>>>>
>>>>> I'm a bit confused about:
>>>>>
>>>>> /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST))
>>>>>    when profitable.
>>>>>    For bitwise binary operations apply operand conversions to the
>>>>>    binary operation result instead of to the operands.  This allows
>>>>>    to combine successive conversions and bitwise binary operations.
>>>>>    We combine the above two cases by using a conditional convert.  */
>>>>> (for bitop (bit_and bit_ior bit_xor)
>>>>>  (simplify
>>>>>   (bitop (convert @0) (convert? @1))
>>>>>   (if (((TREE_CODE (@1) == INTEGER_CST
>>>>>          && INTEGRAL_TYPE_P (TREE_TYPE (@0))
>>>>>          && int_fits_type_p (@1, TREE_TYPE (@0)))
>>>>>         || types_match (@0, @1))
>>>>>        /* ???  This transform conflicts with fold-const.c doing
>>>>>           Convert (T)(x & c) into (T)x & (T)c, if c is an integer
>>>>>           constants (if x has signed type, the sign bit cannot be set
>>>>>           in c).  This folds extension into the BIT_AND_EXPR.
>>>>>           Restrict it to GIMPLE to avoid endless recursions.  */
>>>>>        && (bitop != BIT_AND_EXPR || GIMPLE)
>>>>>        && (/* That's a good idea if the conversion widens the operand, thus
>>>>> after hoisting the conversion the operation will be narrower.  */
>>>>>            TYPE_PRECISION (TREE_TYPE (@0)) < TYPE_PRECISION (type)
>>>>>            /* It's also a good idea if the conversion is to a non-integer
>>>>>               mode.  */
>>>>>            || GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT
>>>>>            /* Or if the precision of TO is not the same as the precision
>>>>>               of its mode.  */
>>>>> || TYPE_PRECISION (type) != GET_MODE_PRECISION (TYPE_MODE (type))))
>>>>>    (convert (bitop @0 (convert @1))))))
>>>>>
>>>>> though.  The "INTEGRAL_TYPE_P (TREE_TYPE (@0))" suggests that we can't
>>>>> rely on @0 and @1 being integral (although conversions from float would
>>>>> use FLOAT_EXPR), but then what is:
>>>>
>>>> bit_and is valid on POINTER_TYPE and vector integer types
>>>>
>>>>>
>>>>>            /* It's also a good idea if the conversion is to a non-integer
>>>>>               mode.  */
>>>>>            || GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT
>>>>>
>>>>> letting through?  MODE_PARTIAL_INT maybe, but that's a sort of integer
>>>>> mode too.  MODE_COMPLEX_INT or MODE_VECTOR_INT?  I thought for those
>>>>> it would be better to apply the scalar rules to the element type.
>>>>
>>>> I suppose extra caution ;)  I think I have seen BLKmode for not naturally
>>>> aligned integer types at least on strict-align targets?  The code is
>>>> a copy from original code in tree-ssa-forwprop.c.
>>>>
>>>>> Either way, having allowed all non-INT modes, using full_integral_type_p
>>>>> for the remaining condition seems correct.
>>>>>
>>>>> If the feeling is that this isn't a useful abstraction, I can just update
>>>>> each site individually to cope with variable-sized modes.
>>>>
>>>> I think "full_integral_type_p" is a name from which I cannot infer
>>>> its meaning.  Maybe type_has_mode_precision_p?  Or
>>>> type_matches_mode_p?
>>>
>>> type_has_mode_precision_p sounds good.  With that name I guess it
>>> should be written to cope with all types (even those with variable-
>>> width modes), so I think we'd need to continue using TYPE_MODE.
>>> The VECTOR_MODE_P check should get optimised away in most of
>>> the cases touched by the patch though.
>>>
>>> Would it be OK to move the declaration of vector_type_mode to tree.h
>>> so that type_has_mode_precision_p can be inline?
>>
>> Just move the implementation to tree.c then.
>
> OK, I posted that as: https://gcc.gnu.org/ml/gcc-patches/2017-08/msg01184.html
>
> Here's the patch to add type_has_mode_precision_p.  Tested on
> aarch64-linux-gnu and x86_64-linux-gnu, and by diffing the before and
> after testsuite assembly for one target per CPU (there were no differences).
> OK to install?

Ok.

Richard.

> Thanks,
> Richard
>
>
> 2017-08-21  Richard Sandiford  <richard.sandiford@linaro.org>
>
> gcc/
>         * tree.h (type_has_mode_precision_p): New function.
>         * convert.c (convert_to_integer_1): Use it.
>         * expr.c (expand_expr_real_2): Likewise.
>         (expand_expr_real_1): Likewise.
>         * fold-const.c (fold_single_bit_test_into_sign_test): Likewise.
>         * match.pd: Likewise.
>         * tree-ssa-forwprop.c (simplify_rotate): Likewise.
>         * tree-ssa-math-opts.c (convert_mult_to_fma): Likewise.
>         * tree-tailcall.c (process_assignment): Likewise.
>         * tree-vect-loop.c (vectorizable_reduction): Likewise.
>         * tree-vect-patterns.c (vect_recog_vector_vector_shift_pattern)
>         (vect_recog_mult_pattern, vect_recog_divmod_pattern): Likewise.
>         * tree-vect-stmts.c (vectorizable_conversion): Likewise.
>         (vectorizable_assignment): Likewise.
>         (vectorizable_shift): Likewise.
>         (vectorizable_operation): Likewise.
>         * tree-vrp.c (register_edge_assert_for_2): Likewise.
>
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h  2017-08-21 10:52:43.717019857 +0100
> +++ gcc/tree.h  2017-08-21 10:55:12.419951940 +0100
> @@ -5414,4 +5414,13 @@ struct builtin_structptr_type
>    const char *str;
>  };
>  extern const builtin_structptr_type builtin_structptr_types[6];
> +
> +/* Return true if type T has the same precision as its underlying mode.  */
> +
> +inline bool
> +type_has_mode_precision_p (const_tree t)
> +{
> +  return TYPE_PRECISION (t) == GET_MODE_PRECISION (TYPE_MODE (t));
> +}
> +
>  #endif  /* GCC_TREE_H  */
> Index: gcc/convert.c
> ===================================================================
> --- gcc/convert.c       2017-08-21 10:41:51.158103275 +0100
> +++ gcc/convert.c       2017-08-21 10:55:12.412951940 +0100
> @@ -711,8 +711,7 @@ convert_to_integer_1 (tree type, tree ex
>              the signed-to-unsigned case the high-order bits have to
>              be cleared.  */
>           if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
> -             && (TYPE_PRECISION (TREE_TYPE (expr))
> -                 != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (expr)))))
> +             && !type_has_mode_precision_p (TREE_TYPE (expr)))
>             code = CONVERT_EXPR;
>           else
>             code = NOP_EXPR;
> Index: gcc/expr.c
> ===================================================================
> --- gcc/expr.c  2017-08-21 10:41:51.158103275 +0100
> +++ gcc/expr.c  2017-08-21 10:55:12.413951940 +0100
> @@ -8244,7 +8244,7 @@ #define REDUCE_BIT_FIELD(expr)    (reduce_b
>       result to be reduced to the precision of the bit-field type,
>       which is narrower than that of the type's mode.  */
>    reduce_bit_field = (INTEGRAL_TYPE_P (type)
> -                     && GET_MODE_PRECISION (mode) > TYPE_PRECISION (type));
> +                     && !type_has_mode_precision_p (type));
>
>    if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
>      target = 0;
> @@ -9097,8 +9097,7 @@ #define REDUCE_BIT_FIELD(expr)    (reduce_b
>      case LROTATE_EXPR:
>      case RROTATE_EXPR:
>        gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
> -                 || (GET_MODE_PRECISION (TYPE_MODE (type))
> -                     == TYPE_PRECISION (type)));
> +                 || type_has_mode_precision_p (type));
>        /* fall through */
>
>      case LSHIFT_EXPR:
> @@ -9671,7 +9670,7 @@ expand_expr_real_1 (tree exp, rtx target
>       which is narrower than that of the type's mode.  */
>    reduce_bit_field = (!ignore
>                       && INTEGRAL_TYPE_P (type)
> -                     && GET_MODE_PRECISION (mode) > TYPE_PRECISION (type));
> +                     && !type_has_mode_precision_p (type));
>
>    /* If we are going to ignore this result, we need only do something
>       if there is a side-effect somewhere in the expression.  If there
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c    2017-08-21 10:41:51.265103275 +0100
> +++ gcc/fold-const.c    2017-08-21 10:55:12.414951940 +0100
> @@ -6638,8 +6638,7 @@ fold_single_bit_test_into_sign_test (loc
>        if (arg00 != NULL_TREE
>           /* This is only a win if casting to a signed type is cheap,
>              i.e. when arg00's type is not a partial mode.  */
> -         && TYPE_PRECISION (TREE_TYPE (arg00))
> -            == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (arg00))))
> +         && type_has_mode_precision_p (TREE_TYPE (arg00)))
>         {
>           tree stype = signed_type_for (TREE_TYPE (arg00));
>           return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
> Index: gcc/match.pd
> ===================================================================
> --- gcc/match.pd        2017-08-21 10:41:51.265103275 +0100
> +++ gcc/match.pd        2017-08-21 10:55:12.414951940 +0100
> @@ -992,7 +992,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>            || GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT
>            /* Or if the precision of TO is not the same as the precision
>               of its mode.  */
> -          || TYPE_PRECISION (type) != GET_MODE_PRECISION (TYPE_MODE (type))))
> +          || !type_has_mode_precision_p (type)))
>     (convert (bitop @0 (convert @1))))))
>
>  (for bitop (bit_and bit_ior)
> @@ -1920,8 +1920,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>         if (shift == LSHIFT_EXPR)
>          zerobits = ((HOST_WIDE_INT_1U << shiftc) - 1);
>         else if (shift == RSHIFT_EXPR
> -               && (TYPE_PRECISION (shift_type)
> -                   == GET_MODE_PRECISION (TYPE_MODE (shift_type))))
> +               && type_has_mode_precision_p (shift_type))
>          {
>            prec = TYPE_PRECISION (TREE_TYPE (@3));
>            tree arg00 = @0;
> @@ -1931,8 +1930,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>                && TYPE_UNSIGNED (TREE_TYPE (@0)))
>              {
>                tree inner_type = TREE_TYPE (@0);
> -              if ((TYPE_PRECISION (inner_type)
> -                   == GET_MODE_PRECISION (TYPE_MODE (inner_type)))
> +              if (type_has_mode_precision_p (inner_type)
>                    && TYPE_PRECISION (inner_type) < prec)
>                  {
>                    prec = TYPE_PRECISION (inner_type);
> @@ -3226,8 +3224,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>   (simplify
>    (cmp (bit_and (convert?@2 @0) integer_pow2p@1) integer_zerop)
>    (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
> -       && (TYPE_PRECISION (TREE_TYPE (@0))
> -          == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@0))))
> +       && type_has_mode_precision_p (TREE_TYPE (@0))
>         && element_precision (@2) >= element_precision (@0)
>         && wi::only_sign_bit_p (@1, element_precision (@0)))
>     (with { tree stype = signed_type_for (TREE_TYPE (@0)); }
> @@ -4029,11 +4026,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>          /* 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))
> +        && type_has_mode_precision_p (TREE_TYPE (@0))
> +        && type_has_mode_precision_p (TREE_TYPE (@1))
> +        && type_has_mode_precision_p (type)
>          /* The inner conversion must be a widening conversion.  */
>          && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
>          && types_match (@0, type)
> @@ -4063,11 +4058,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>         /* 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))
> +       && type_has_mode_precision_p (TREE_TYPE (@0))
> +       && type_has_mode_precision_p (TREE_TYPE (@1))
> +       && type_has_mode_precision_p (type)
>         /* The inner conversion must be a widening conversion.  */
>         && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
>         && types_match (@0, @1)
> Index: gcc/tree-ssa-forwprop.c
> ===================================================================
> --- gcc/tree-ssa-forwprop.c     2017-08-21 10:41:51.265103275 +0100
> +++ gcc/tree-ssa-forwprop.c     2017-08-21 10:55:12.415951940 +0100
> @@ -1529,7 +1529,7 @@ simplify_rotate (gimple_stmt_iterator *g
>    /* Only create rotates in complete modes.  Other cases are not
>       expanded properly.  */
>    if (!INTEGRAL_TYPE_P (rtype)
> -      || TYPE_PRECISION (rtype) != GET_MODE_PRECISION (TYPE_MODE (rtype)))
> +      || !type_has_mode_precision_p (rtype))
>      return false;
>
>    for (i = 0; i < 2; i++)
> @@ -1609,8 +1609,7 @@ simplify_rotate (gimple_stmt_iterator *g
>               && INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))
>               && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
>                  > floor_log2 (TYPE_PRECISION (rtype))
> -             && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
> -                == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (cdef_arg1[i]))))
> +             && type_has_mode_precision_p (TREE_TYPE (cdef_arg1[i])))
>             {
>               def_arg2_alt[i] = cdef_arg1[i];
>               defcodefor_name (def_arg2_alt[i], &cdef_code[i],
> @@ -1639,8 +1638,7 @@ simplify_rotate (gimple_stmt_iterator *g
>                 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
>                 && TYPE_PRECISION (TREE_TYPE (tem))
>                  > floor_log2 (TYPE_PRECISION (rtype))
> -               && TYPE_PRECISION (TREE_TYPE (tem))
> -                == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
> +               && type_has_mode_precision_p (TREE_TYPE (tem))
>                 && (tem == def_arg2[1 - i]
>                     || tem == def_arg2_alt[1 - i]))
>               {
> @@ -1667,8 +1665,7 @@ simplify_rotate (gimple_stmt_iterator *g
>                 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
>                 && TYPE_PRECISION (TREE_TYPE (tem))
>                  > floor_log2 (TYPE_PRECISION (rtype))
> -               && TYPE_PRECISION (TREE_TYPE (tem))
> -                == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem))))
> +               && type_has_mode_precision_p (TREE_TYPE (tem)))
>               defcodefor_name (tem, &code, &tem, NULL);
>
>             if (code == NEGATE_EXPR)
> @@ -1683,8 +1680,7 @@ simplify_rotate (gimple_stmt_iterator *g
>                     && INTEGRAL_TYPE_P (TREE_TYPE (tem))
>                     && TYPE_PRECISION (TREE_TYPE (tem))
>                        > floor_log2 (TYPE_PRECISION (rtype))
> -                   && TYPE_PRECISION (TREE_TYPE (tem))
> -                      == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
> +                   && type_has_mode_precision_p (TREE_TYPE (tem))
>                     && (tem == def_arg2[1 - i]
>                         || tem == def_arg2_alt[1 - i]))
>                   {
> Index: gcc/tree-ssa-math-opts.c
> ===================================================================
> --- gcc/tree-ssa-math-opts.c    2017-08-21 10:41:51.158103275 +0100
> +++ gcc/tree-ssa-math-opts.c    2017-08-21 10:55:12.415951940 +0100
> @@ -3564,8 +3564,7 @@ convert_mult_to_fma (gimple *mul_stmt, t
>
>    /* We don't want to do bitfield reduction ops.  */
>    if (INTEGRAL_TYPE_P (type)
> -      && (TYPE_PRECISION (type)
> -         != GET_MODE_PRECISION (TYPE_MODE (type))))
> +      && !type_has_mode_precision_p (type))
>      return false;
>
>    /* If the target doesn't support it, don't generate it.  We assume that
> Index: gcc/tree-tailcall.c
> ===================================================================
> --- gcc/tree-tailcall.c 2017-08-21 10:41:51.158103275 +0100
> +++ gcc/tree-tailcall.c 2017-08-21 10:55:12.415951940 +0100
> @@ -289,8 +289,7 @@ process_assignment (gassign *stmt,
>              type is smaller than mode's precision,
>              reduce_to_bit_field_precision would generate additional code.  */
>           if (INTEGRAL_TYPE_P (TREE_TYPE (dest))
> -             && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (dest)))
> -                 > TYPE_PRECISION (TREE_TYPE (dest))))
> +             && !type_has_mode_precision_p (TREE_TYPE (dest)))
>             return FAIL;
>         }
>
> Index: gcc/tree-vect-loop.c
> ===================================================================
> --- gcc/tree-vect-loop.c        2017-08-21 10:41:51.158103275 +0100
> +++ gcc/tree-vect-loop.c        2017-08-21 10:55:12.416951940 +0100
> @@ -5848,8 +5848,7 @@ vectorizable_reduction (gimple *stmt, gi
>      return false;
>
>    /* Do not try to vectorize bit-precision reductions.  */
> -  if ((TYPE_PRECISION (scalar_type)
> -       != GET_MODE_PRECISION (TYPE_MODE (scalar_type))))
> +  if (!type_has_mode_precision_p (scalar_type))
>      return false;
>
>    /* All uses but the last are expected to be defined in the loop.
> Index: gcc/tree-vect-patterns.c
> ===================================================================
> --- gcc/tree-vect-patterns.c    2017-08-21 10:41:51.265103275 +0100
> +++ gcc/tree-vect-patterns.c    2017-08-21 10:55:12.416951940 +0100
> @@ -2067,8 +2067,7 @@ vect_recog_vector_vector_shift_pattern (
>    if (TREE_CODE (oprnd0) != SSA_NAME
>        || TREE_CODE (oprnd1) != SSA_NAME
>        || TYPE_MODE (TREE_TYPE (oprnd0)) == TYPE_MODE (TREE_TYPE (oprnd1))
> -      || TYPE_PRECISION (TREE_TYPE (oprnd1))
> -        != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (oprnd1)))
> +      || !type_has_mode_precision_p (TREE_TYPE (oprnd1))
>        || TYPE_PRECISION (TREE_TYPE (lhs))
>          != TYPE_PRECISION (TREE_TYPE (oprnd0)))
>      return NULL;
> @@ -2470,7 +2469,7 @@ vect_recog_mult_pattern (vec<gimple *> *
>    if (TREE_CODE (oprnd0) != SSA_NAME
>        || TREE_CODE (oprnd1) != INTEGER_CST
>        || !INTEGRAL_TYPE_P (itype)
> -      || TYPE_PRECISION (itype) != GET_MODE_PRECISION (TYPE_MODE (itype)))
> +      || !type_has_mode_precision_p (itype))
>      return NULL;
>
>    vectype = get_vectype_for_scalar_type (itype);
> @@ -2585,7 +2584,7 @@ vect_recog_divmod_pattern (vec<gimple *>
>    if (TREE_CODE (oprnd0) != SSA_NAME
>        || TREE_CODE (oprnd1) != INTEGER_CST
>        || TREE_CODE (itype) != INTEGER_TYPE
> -      || TYPE_PRECISION (itype) != GET_MODE_PRECISION (TYPE_MODE (itype)))
> +      || !type_has_mode_precision_p (itype))
>      return NULL;
>
>    vectype = get_vectype_for_scalar_type (itype);
> Index: gcc/tree-vect-stmts.c
> ===================================================================
> --- gcc/tree-vect-stmts.c       2017-08-21 10:42:51.088530428 +0100
> +++ gcc/tree-vect-stmts.c       2017-08-21 10:55:12.417951940 +0100
> @@ -4098,11 +4098,9 @@ vectorizable_conversion (gimple *stmt, g
>
>    if (!VECTOR_BOOLEAN_TYPE_P (vectype_out)
>        && ((INTEGRAL_TYPE_P (lhs_type)
> -          && (TYPE_PRECISION (lhs_type)
> -              != GET_MODE_PRECISION (TYPE_MODE (lhs_type))))
> +          && !type_has_mode_precision_p (lhs_type))
>           || (INTEGRAL_TYPE_P (rhs_type)
> -             && (TYPE_PRECISION (rhs_type)
> -                 != GET_MODE_PRECISION (TYPE_MODE (rhs_type))))))
> +             && !type_has_mode_precision_p (rhs_type))))
>      {
>        if (dump_enabled_p ())
>         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> @@ -4696,10 +4694,8 @@ vectorizable_assignment (gimple *stmt, g
>    if ((CONVERT_EXPR_CODE_P (code)
>         || code == VIEW_CONVERT_EXPR)
>        && INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
> -      && ((TYPE_PRECISION (TREE_TYPE (scalar_dest))
> -          != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
> -         || ((TYPE_PRECISION (TREE_TYPE (op))
> -              != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op))))))
> +      && (!type_has_mode_precision_p (TREE_TYPE (scalar_dest))
> +         || !type_has_mode_precision_p (TREE_TYPE (op)))
>        /* But a conversion that does not change the bit-pattern is ok.  */
>        && !((TYPE_PRECISION (TREE_TYPE (scalar_dest))
>             > TYPE_PRECISION (TREE_TYPE (op)))
> @@ -4875,8 +4871,7 @@ vectorizable_shift (gimple *stmt, gimple
>
>    scalar_dest = gimple_assign_lhs (stmt);
>    vectype_out = STMT_VINFO_VECTYPE (stmt_info);
> -  if (TYPE_PRECISION (TREE_TYPE (scalar_dest))
> -      != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
> +  if (!type_has_mode_precision_p (TREE_TYPE (scalar_dest)))
>      {
>        if (dump_enabled_p ())
>          dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> @@ -5264,8 +5259,7 @@ vectorizable_operation (gimple *stmt, gi
>    /* Most operations cannot handle bit-precision types without extra
>       truncations.  */
>    if (!VECTOR_BOOLEAN_TYPE_P (vectype_out)
> -      && (TYPE_PRECISION (TREE_TYPE (scalar_dest))
> -         != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
> +      && !type_has_mode_precision_p (TREE_TYPE (scalar_dest))
>        /* Exception are bitwise binary operations.  */
>        && code != BIT_IOR_EXPR
>        && code != BIT_XOR_EXPR
> Index: gcc/tree-vrp.c
> ===================================================================
> --- gcc/tree-vrp.c      2017-08-21 10:41:51.265103275 +0100
> +++ gcc/tree-vrp.c      2017-08-21 10:55:12.418951940 +0100
> @@ -5247,7 +5247,7 @@ register_edge_assert_for_2 (tree name, e
>               && tree_fits_uhwi_p (cst2)
>               && INTEGRAL_TYPE_P (TREE_TYPE (name2))
>               && IN_RANGE (tree_to_uhwi (cst2), 1, prec - 1)
> -             && prec == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (val))))
> +             && type_has_mode_precision_p (TREE_TYPE (val)))
>             {
>               mask = wi::mask (tree_to_uhwi (cst2), false, prec);
>               val2 = fold_binary (LSHIFT_EXPR, TREE_TYPE (val), val, cst2);
diff mbox

Patch

Index: gcc/tree.h
===================================================================
--- gcc/tree.h	2017-08-21 10:52:43.717019857 +0100
+++ gcc/tree.h	2017-08-21 10:55:12.419951940 +0100
@@ -5414,4 +5414,13 @@  struct builtin_structptr_type
   const char *str;
 };
 extern const builtin_structptr_type builtin_structptr_types[6];
+
+/* Return true if type T has the same precision as its underlying mode.  */
+
+inline bool
+type_has_mode_precision_p (const_tree t)
+{
+  return TYPE_PRECISION (t) == GET_MODE_PRECISION (TYPE_MODE (t));
+}
+
 #endif  /* GCC_TREE_H  */
Index: gcc/convert.c
===================================================================
--- gcc/convert.c	2017-08-21 10:41:51.158103275 +0100
+++ gcc/convert.c	2017-08-21 10:55:12.412951940 +0100
@@ -711,8 +711,7 @@  convert_to_integer_1 (tree type, tree ex
 	     the signed-to-unsigned case the high-order bits have to
 	     be cleared.  */
 	  if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
-	      && (TYPE_PRECISION (TREE_TYPE (expr))
-		  != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (expr)))))
+	      && !type_has_mode_precision_p (TREE_TYPE (expr)))
 	    code = CONVERT_EXPR;
 	  else
 	    code = NOP_EXPR;
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	2017-08-21 10:41:51.158103275 +0100
+++ gcc/expr.c	2017-08-21 10:55:12.413951940 +0100
@@ -8244,7 +8244,7 @@  #define REDUCE_BIT_FIELD(expr)	(reduce_b
      result to be reduced to the precision of the bit-field type,
      which is narrower than that of the type's mode.  */
   reduce_bit_field = (INTEGRAL_TYPE_P (type)
-		      && GET_MODE_PRECISION (mode) > TYPE_PRECISION (type));
+		      && !type_has_mode_precision_p (type));
 
   if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
     target = 0;
@@ -9097,8 +9097,7 @@  #define REDUCE_BIT_FIELD(expr)	(reduce_b
     case LROTATE_EXPR:
     case RROTATE_EXPR:
       gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
-		  || (GET_MODE_PRECISION (TYPE_MODE (type))
-		      == TYPE_PRECISION (type)));
+		  || type_has_mode_precision_p (type));
       /* fall through */
 
     case LSHIFT_EXPR:
@@ -9671,7 +9670,7 @@  expand_expr_real_1 (tree exp, rtx target
      which is narrower than that of the type's mode.  */
   reduce_bit_field = (!ignore
 		      && INTEGRAL_TYPE_P (type)
-		      && GET_MODE_PRECISION (mode) > TYPE_PRECISION (type));
+		      && !type_has_mode_precision_p (type));
 
   /* If we are going to ignore this result, we need only do something
      if there is a side-effect somewhere in the expression.  If there
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	2017-08-21 10:41:51.265103275 +0100
+++ gcc/fold-const.c	2017-08-21 10:55:12.414951940 +0100
@@ -6638,8 +6638,7 @@  fold_single_bit_test_into_sign_test (loc
       if (arg00 != NULL_TREE
 	  /* This is only a win if casting to a signed type is cheap,
 	     i.e. when arg00's type is not a partial mode.  */
-	  && TYPE_PRECISION (TREE_TYPE (arg00))
-	     == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (arg00))))
+	  && type_has_mode_precision_p (TREE_TYPE (arg00)))
 	{
 	  tree stype = signed_type_for (TREE_TYPE (arg00));
 	  return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	2017-08-21 10:41:51.265103275 +0100
+++ gcc/match.pd	2017-08-21 10:55:12.414951940 +0100
@@ -992,7 +992,7 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	   || GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT
 	   /* Or if the precision of TO is not the same as the precision
 	      of its mode.  */
-	   || TYPE_PRECISION (type) != GET_MODE_PRECISION (TYPE_MODE (type))))
+	   || !type_has_mode_precision_p (type)))
    (convert (bitop @0 (convert @1))))))
 
 (for bitop (bit_and bit_ior)
@@ -1920,8 +1920,7 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        if (shift == LSHIFT_EXPR)
 	 zerobits = ((HOST_WIDE_INT_1U << shiftc) - 1);
        else if (shift == RSHIFT_EXPR
-		&& (TYPE_PRECISION (shift_type)
-		    == GET_MODE_PRECISION (TYPE_MODE (shift_type))))
+		&& type_has_mode_precision_p (shift_type))
 	 {
 	   prec = TYPE_PRECISION (TREE_TYPE (@3));
 	   tree arg00 = @0;
@@ -1931,8 +1930,7 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	       && TYPE_UNSIGNED (TREE_TYPE (@0)))
 	     {
 	       tree inner_type = TREE_TYPE (@0);
-	       if ((TYPE_PRECISION (inner_type)
-		    == GET_MODE_PRECISION (TYPE_MODE (inner_type)))
+	       if (type_has_mode_precision_p (inner_type)
 		   && TYPE_PRECISION (inner_type) < prec)
 		 {
 		   prec = TYPE_PRECISION (inner_type);
@@ -3226,8 +3224,7 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (simplify
   (cmp (bit_and (convert?@2 @0) integer_pow2p@1) integer_zerop)
   (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
-       && (TYPE_PRECISION (TREE_TYPE (@0))
-	   == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@0))))
+       && type_has_mode_precision_p (TREE_TYPE (@0))
        && element_precision (@2) >= element_precision (@0)
        && wi::only_sign_bit_p (@1, element_precision (@0)))
    (with { tree stype = signed_type_for (TREE_TYPE (@0)); }
@@ -4029,11 +4026,9 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	 /* 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))
+	 && type_has_mode_precision_p (TREE_TYPE (@0))
+	 && type_has_mode_precision_p (TREE_TYPE (@1))
+	 && type_has_mode_precision_p (type)
 	 /* The inner conversion must be a widening conversion.  */
 	 && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
 	 && types_match (@0, type)
@@ -4063,11 +4058,9 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        /* 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))
+       && type_has_mode_precision_p (TREE_TYPE (@0))
+       && type_has_mode_precision_p (TREE_TYPE (@1))
+       && type_has_mode_precision_p (type)
        /* The inner conversion must be a widening conversion.  */
        && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
        && types_match (@0, @1)
Index: gcc/tree-ssa-forwprop.c
===================================================================
--- gcc/tree-ssa-forwprop.c	2017-08-21 10:41:51.265103275 +0100
+++ gcc/tree-ssa-forwprop.c	2017-08-21 10:55:12.415951940 +0100
@@ -1529,7 +1529,7 @@  simplify_rotate (gimple_stmt_iterator *g
   /* Only create rotates in complete modes.  Other cases are not
      expanded properly.  */
   if (!INTEGRAL_TYPE_P (rtype)
-      || TYPE_PRECISION (rtype) != GET_MODE_PRECISION (TYPE_MODE (rtype)))
+      || !type_has_mode_precision_p (rtype))
     return false;
 
   for (i = 0; i < 2; i++)
@@ -1609,8 +1609,7 @@  simplify_rotate (gimple_stmt_iterator *g
 	      && INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))
 	      && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
 		 > floor_log2 (TYPE_PRECISION (rtype))
-	      && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
-		 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (cdef_arg1[i]))))
+	      && type_has_mode_precision_p (TREE_TYPE (cdef_arg1[i])))
 	    {
 	      def_arg2_alt[i] = cdef_arg1[i];
 	      defcodefor_name (def_arg2_alt[i], &cdef_code[i],
@@ -1639,8 +1638,7 @@  simplify_rotate (gimple_stmt_iterator *g
 		&& INTEGRAL_TYPE_P (TREE_TYPE (tem))
 		&& TYPE_PRECISION (TREE_TYPE (tem))
 		 > floor_log2 (TYPE_PRECISION (rtype))
-		&& TYPE_PRECISION (TREE_TYPE (tem))
-		 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
+		&& type_has_mode_precision_p (TREE_TYPE (tem))
 		&& (tem == def_arg2[1 - i]
 		    || tem == def_arg2_alt[1 - i]))
 	      {
@@ -1667,8 +1665,7 @@  simplify_rotate (gimple_stmt_iterator *g
 		&& INTEGRAL_TYPE_P (TREE_TYPE (tem))
 		&& TYPE_PRECISION (TREE_TYPE (tem))
 		 > floor_log2 (TYPE_PRECISION (rtype))
-		&& TYPE_PRECISION (TREE_TYPE (tem))
-		 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem))))
+		&& type_has_mode_precision_p (TREE_TYPE (tem)))
 	      defcodefor_name (tem, &code, &tem, NULL);
 
 	    if (code == NEGATE_EXPR)
@@ -1683,8 +1680,7 @@  simplify_rotate (gimple_stmt_iterator *g
 		    && INTEGRAL_TYPE_P (TREE_TYPE (tem))
 		    && TYPE_PRECISION (TREE_TYPE (tem))
 		       > floor_log2 (TYPE_PRECISION (rtype))
-		    && TYPE_PRECISION (TREE_TYPE (tem))
-		       == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
+		    && type_has_mode_precision_p (TREE_TYPE (tem))
 		    && (tem == def_arg2[1 - i]
 			|| tem == def_arg2_alt[1 - i]))
 		  {
Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	2017-08-21 10:41:51.158103275 +0100
+++ gcc/tree-ssa-math-opts.c	2017-08-21 10:55:12.415951940 +0100
@@ -3564,8 +3564,7 @@  convert_mult_to_fma (gimple *mul_stmt, t
 
   /* We don't want to do bitfield reduction ops.  */
   if (INTEGRAL_TYPE_P (type)
-      && (TYPE_PRECISION (type)
-	  != GET_MODE_PRECISION (TYPE_MODE (type))))
+      && !type_has_mode_precision_p (type))
     return false;
 
   /* If the target doesn't support it, don't generate it.  We assume that
Index: gcc/tree-tailcall.c
===================================================================
--- gcc/tree-tailcall.c	2017-08-21 10:41:51.158103275 +0100
+++ gcc/tree-tailcall.c	2017-08-21 10:55:12.415951940 +0100
@@ -289,8 +289,7 @@  process_assignment (gassign *stmt,
 	     type is smaller than mode's precision,
 	     reduce_to_bit_field_precision would generate additional code.  */
 	  if (INTEGRAL_TYPE_P (TREE_TYPE (dest))
-	      && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (dest)))
-		  > TYPE_PRECISION (TREE_TYPE (dest))))
+	      && !type_has_mode_precision_p (TREE_TYPE (dest)))
 	    return FAIL;
 	}
 
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	2017-08-21 10:41:51.158103275 +0100
+++ gcc/tree-vect-loop.c	2017-08-21 10:55:12.416951940 +0100
@@ -5848,8 +5848,7 @@  vectorizable_reduction (gimple *stmt, gi
     return false;
 
   /* Do not try to vectorize bit-precision reductions.  */
-  if ((TYPE_PRECISION (scalar_type)
-       != GET_MODE_PRECISION (TYPE_MODE (scalar_type))))
+  if (!type_has_mode_precision_p (scalar_type))
     return false;
 
   /* All uses but the last are expected to be defined in the loop.
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c	2017-08-21 10:41:51.265103275 +0100
+++ gcc/tree-vect-patterns.c	2017-08-21 10:55:12.416951940 +0100
@@ -2067,8 +2067,7 @@  vect_recog_vector_vector_shift_pattern (
   if (TREE_CODE (oprnd0) != SSA_NAME
       || TREE_CODE (oprnd1) != SSA_NAME
       || TYPE_MODE (TREE_TYPE (oprnd0)) == TYPE_MODE (TREE_TYPE (oprnd1))
-      || TYPE_PRECISION (TREE_TYPE (oprnd1))
-	 != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (oprnd1)))
+      || !type_has_mode_precision_p (TREE_TYPE (oprnd1))
       || TYPE_PRECISION (TREE_TYPE (lhs))
 	 != TYPE_PRECISION (TREE_TYPE (oprnd0)))
     return NULL;
@@ -2470,7 +2469,7 @@  vect_recog_mult_pattern (vec<gimple *> *
   if (TREE_CODE (oprnd0) != SSA_NAME
       || TREE_CODE (oprnd1) != INTEGER_CST
       || !INTEGRAL_TYPE_P (itype)
-      || TYPE_PRECISION (itype) != GET_MODE_PRECISION (TYPE_MODE (itype)))
+      || !type_has_mode_precision_p (itype))
     return NULL;
 
   vectype = get_vectype_for_scalar_type (itype);
@@ -2585,7 +2584,7 @@  vect_recog_divmod_pattern (vec<gimple *>
   if (TREE_CODE (oprnd0) != SSA_NAME
       || TREE_CODE (oprnd1) != INTEGER_CST
       || TREE_CODE (itype) != INTEGER_TYPE
-      || TYPE_PRECISION (itype) != GET_MODE_PRECISION (TYPE_MODE (itype)))
+      || !type_has_mode_precision_p (itype))
     return NULL;
 
   vectype = get_vectype_for_scalar_type (itype);
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c	2017-08-21 10:42:51.088530428 +0100
+++ gcc/tree-vect-stmts.c	2017-08-21 10:55:12.417951940 +0100
@@ -4098,11 +4098,9 @@  vectorizable_conversion (gimple *stmt, g
 
   if (!VECTOR_BOOLEAN_TYPE_P (vectype_out)
       && ((INTEGRAL_TYPE_P (lhs_type)
-	   && (TYPE_PRECISION (lhs_type)
-	       != GET_MODE_PRECISION (TYPE_MODE (lhs_type))))
+	   && !type_has_mode_precision_p (lhs_type))
 	  || (INTEGRAL_TYPE_P (rhs_type)
-	      && (TYPE_PRECISION (rhs_type)
-		  != GET_MODE_PRECISION (TYPE_MODE (rhs_type))))))
+	      && !type_has_mode_precision_p (rhs_type))))
     {
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4696,10 +4694,8 @@  vectorizable_assignment (gimple *stmt, g
   if ((CONVERT_EXPR_CODE_P (code)
        || code == VIEW_CONVERT_EXPR)
       && INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
-      && ((TYPE_PRECISION (TREE_TYPE (scalar_dest))
-	   != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
-	  || ((TYPE_PRECISION (TREE_TYPE (op))
-	       != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op))))))
+      && (!type_has_mode_precision_p (TREE_TYPE (scalar_dest))
+	  || !type_has_mode_precision_p (TREE_TYPE (op)))
       /* But a conversion that does not change the bit-pattern is ok.  */
       && !((TYPE_PRECISION (TREE_TYPE (scalar_dest))
 	    > TYPE_PRECISION (TREE_TYPE (op)))
@@ -4875,8 +4871,7 @@  vectorizable_shift (gimple *stmt, gimple
 
   scalar_dest = gimple_assign_lhs (stmt);
   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
-  if (TYPE_PRECISION (TREE_TYPE (scalar_dest))
-      != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
+  if (!type_has_mode_precision_p (TREE_TYPE (scalar_dest)))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5264,8 +5259,7 @@  vectorizable_operation (gimple *stmt, gi
   /* Most operations cannot handle bit-precision types without extra
      truncations.  */
   if (!VECTOR_BOOLEAN_TYPE_P (vectype_out)
-      && (TYPE_PRECISION (TREE_TYPE (scalar_dest))
-	  != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
+      && !type_has_mode_precision_p (TREE_TYPE (scalar_dest))
       /* Exception are bitwise binary operations.  */
       && code != BIT_IOR_EXPR
       && code != BIT_XOR_EXPR
Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	2017-08-21 10:41:51.265103275 +0100
+++ gcc/tree-vrp.c	2017-08-21 10:55:12.418951940 +0100
@@ -5247,7 +5247,7 @@  register_edge_assert_for_2 (tree name, e
 	      && tree_fits_uhwi_p (cst2)
 	      && INTEGRAL_TYPE_P (TREE_TYPE (name2))
 	      && IN_RANGE (tree_to_uhwi (cst2), 1, prec - 1)
-	      && prec == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (val))))
+	      && type_has_mode_precision_p (TREE_TYPE (val)))
 	    {
 	      mask = wi::mask (tree_to_uhwi (cst2), false, prec);
 	      val2 = fold_binary (LSHIFT_EXPR, TREE_TYPE (val), val, cst2);