On Fri, Aug 18, 2017 at 1:04 PM, Richard Sandiford
<richard.sandif...@linaro.org> wrote:
> Richard Biener <richard.guent...@gmail.com> writes:
>> On Fri, Aug 18, 2017 at 10:10 AM, Richard Sandiford
>> <richard.sandif...@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.

>> Does TYPE_PRECISION == GET_MODE_PRECISION
>> imply TYPE_SIZE == GET_MODE_BITSIZE btw?
>
> Good question :-)  You'd know better than me.  The only case I can
> think of is if we ever tried to use BImode for Fortran logicals
> (regardless of kind).  But I guess we wouldn't do that?

OTOH TYPE_SIZE should always be == GET_MODE_BITSIZE and if
not the type should get BLKmode.

Might grep for such checks and replace them with an assert ... ;)

Richard.

> Thanks,
> Richard
>
>>
>> Richard.
>>
>>> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?
>>>
>>> Richard
>>>
>>>
>>> 2017-08-18  Richard Sandiford  <richard.sandif...@linaro.org>
>>>             Alan Hayward  <alan.hayw...@arm.com>
>>>             David Sherwood  <david.sherw...@arm.com>
>>>
>>> gcc/
>>>         * tree.h (scalar_type_is_full_p): New function.
>>>         (full_integral_type_p): Likewise.
>>>         * fold-const.c (fold_single_bit_test_into_sign_test): Likewise.
>>>         * match.pd: Likewise.
>>>         * tree-ssa-forwprop.c (simplify_rotate): Likewise.
>>>         * tree-vect-patterns.c (vect_recog_vector_vector_shift_pattern)
>>>         (vect_recog_mult_pattern, vect_recog_divmod_pattern): Likewise.
>>>         (adjust_bool_pattern): Likewise.
>>>         * tree-vrp.c (register_edge_assert_for_2): Likewise.
>>>         * ubsan.c (instrument_si_overflow): Likewise.
>>>
>>> gcc/c-family/
>>>         * c-ubsan.c (ubsan_instrument_shift): Use full_integral_type_p.
>>>
>>> diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
>>> index b1386db..20f78e7 100644
>>> --- a/gcc/c-family/c-ubsan.c
>>> +++ b/gcc/c-family/c-ubsan.c
>>> @@ -131,8 +131,8 @@ ubsan_instrument_shift (location_t loc, enum tree_code 
>>> code,
>>>
>>>    /* If this is not a signed operation, don't perform overflow checks.
>>>       Also punt on bit-fields.  */
>>> -  if (TYPE_OVERFLOW_WRAPS (type0)
>>> -      || GET_MODE_BITSIZE (TYPE_MODE (type0)) != TYPE_PRECISION (type0)
>>> +  if (!full_integral_type_p (type0)
>>> +      || TYPE_OVERFLOW_WRAPS (type0)
>>>        || !sanitize_flags_p (SANITIZE_SHIFT_BASE))
>>>      ;
>>>
>>> diff --git a/gcc/fold-const.c b/gcc/fold-const.c
>>> index 0a5b168..1985a14 100644
>>> --- a/gcc/fold-const.c
>>> +++ b/gcc/fold-const.c
>>> @@ -6672,8 +6672,7 @@ fold_single_bit_test_into_sign_test (location_t 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))))
>>> +         && full_integral_type_p (TREE_TYPE (arg00)))
>>>         {
>>>           tree stype = signed_type_for (TREE_TYPE (arg00));
>>>           return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
>>> diff --git a/gcc/match.pd b/gcc/match.pd
>>> index 0e36f46..9ad9930 100644
>>> --- a/gcc/match.pd
>>> +++ b/gcc/match.pd
>>> @@ -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))))
>>> +          || !full_integral_type_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))))
>>> +               && full_integral_type_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 (full_integral_type_p (inner_type)
>>>                    && TYPE_PRECISION (inner_type) < prec)
>>>                  {
>>>                    prec = TYPE_PRECISION (inner_type);
>>> @@ -3225,9 +3223,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>>>       ncmp (ge lt)
>>>   (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))))
>>> +  (if (full_integral_type_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)); }
>>> @@ -4021,19 +4017,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>>>  (for op (plus minus)
>>>    (simplify
>>>      (convert (op:s (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))
>>> +    (if (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.  */
>>> -        && (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))
>>> +        && full_integral_type_p (TREE_TYPE (@0))
>>> +        && full_integral_type_p (TREE_TYPE (@1))
>>> +        && full_integral_type_p (type)
>>>          /* The inner conversion must be a widening conversion.  */
>>>          && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE 
>>> (@0))
>>>          && types_match (@0, type)
>>> @@ -4055,19 +4045,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>>>  (for op (minus plus)
>>>   (simplify
>>>    (bit_and (op:s (convert@2 @0) (convert@3 @1)) INTEGER_CST@4)
>>> -  (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))
>>> +  (if (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.  */
>>> -       && (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))
>>> +       && full_integral_type_p (TREE_TYPE (@0))
>>> +       && full_integral_type_p (TREE_TYPE (@1))
>>> +       && full_integral_type_p (type)
>>>         /* The inner conversion must be a widening conversion.  */
>>>         && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
>>>         && types_match (@0, @1)
>>> diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
>>> index 5719b99..20d5c86 100644
>>> --- a/gcc/tree-ssa-forwprop.c
>>> +++ b/gcc/tree-ssa-forwprop.c
>>> @@ -1528,8 +1528,7 @@ simplify_rotate (gimple_stmt_iterator *gsi)
>>>
>>>    /* 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)))
>>> +  if (!full_integral_type_p (rtype))
>>>      return false;
>>>
>>>    for (i = 0; i < 2; i++)
>>> @@ -1606,11 +1605,9 @@ simplify_rotate (gimple_stmt_iterator *gsi)
>>>           defcodefor_name (def_arg2[i], &cdef_code[i],
>>>                            &cdef_arg1[i], &cdef_arg2[i]);
>>>           if (CONVERT_EXPR_CODE_P (cdef_code[i])
>>> -             && INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))
>>> +             && full_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]))))
>>> +                > floor_log2 (TYPE_PRECISION (rtype)))
>>>             {
>>>               def_arg2_alt[i] = cdef_arg1[i];
>>>               defcodefor_name (def_arg2_alt[i], &cdef_code[i],
>>> @@ -1636,11 +1633,9 @@ simplify_rotate (gimple_stmt_iterator *gsi)
>>>               }
>>>             defcodefor_name (cdef_arg2[i], &code, &tem, NULL);
>>>             if (CONVERT_EXPR_CODE_P (code)
>>> -               && INTEGRAL_TYPE_P (TREE_TYPE (tem))
>>> +               && full_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)))
>>>                 && (tem == def_arg2[1 - i]
>>>                     || tem == def_arg2_alt[1 - i]))
>>>               {
>>> @@ -1664,11 +1659,9 @@ simplify_rotate (gimple_stmt_iterator *gsi)
>>>
>>>             defcodefor_name (cdef_arg1[i], &code, &tem, NULL);
>>>             if (CONVERT_EXPR_CODE_P (code)
>>> -               && INTEGRAL_TYPE_P (TREE_TYPE (tem))
>>> +               && full_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))))
>>> +                > floor_log2 (TYPE_PRECISION (rtype)))
>>>               defcodefor_name (tem, &code, &tem, NULL);
>>>
>>>             if (code == NEGATE_EXPR)
>>> @@ -1680,11 +1673,9 @@ simplify_rotate (gimple_stmt_iterator *gsi)
>>>                   }
>>>                 defcodefor_name (tem, &code, &tem, NULL);
>>>                 if (CONVERT_EXPR_CODE_P (code)
>>> -                   && INTEGRAL_TYPE_P (TREE_TYPE (tem))
>>> +                   && full_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)))
>>>                     && (tem == def_arg2[1 - i]
>>>                         || tem == def_arg2_alt[1 - i]))
>>>                   {
>>> diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
>>> index 17d1083..a96f784 100644
>>> --- a/gcc/tree-vect-patterns.c
>>> +++ b/gcc/tree-vect-patterns.c
>>> @@ -2067,8 +2067,7 @@ vect_recog_vector_vector_shift_pattern (vec<gimple *> 
>>> *stmts,
>>>    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)))
>>> +      || !full_integral_type_p (TREE_TYPE (oprnd1))
>>>        || TYPE_PRECISION (TREE_TYPE (lhs))
>>>          != TYPE_PRECISION (TREE_TYPE (oprnd0)))
>>>      return NULL;
>>> @@ -2469,8 +2468,7 @@ vect_recog_mult_pattern (vec<gimple *> *stmts,
>>>
>>>    if (TREE_CODE (oprnd0) != SSA_NAME
>>>        || TREE_CODE (oprnd1) != INTEGER_CST
>>> -      || !INTEGRAL_TYPE_P (itype)
>>> -      || TYPE_PRECISION (itype) != GET_MODE_PRECISION (TYPE_MODE (itype)))
>>> +      || !full_integral_type_p (itype))
>>>      return NULL;
>>>
>>>    vectype = get_vectype_for_scalar_type (itype);
>>> @@ -2584,8 +2582,7 @@ vect_recog_divmod_pattern (vec<gimple *> *stmts,
>>>    itype = TREE_TYPE (oprnd0);
>>>    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)))
>>> +      || !full_integral_type_p (itype))
>>>      return NULL;
>>>
>>>    vectype = get_vectype_for_scalar_type (itype);
>>> @@ -3385,9 +3382,8 @@ adjust_bool_pattern (tree var, tree out_type,
>>>      do_compare:
>>>        gcc_assert (TREE_CODE_CLASS (rhs_code) == tcc_comparison);
>>>        if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE
>>> -         || !TYPE_UNSIGNED (TREE_TYPE (rhs1))
>>> -         || (TYPE_PRECISION (TREE_TYPE (rhs1))
>>> -             != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (rhs1)))))
>>> +         || !full_integral_type_p (TREE_TYPE (rhs1))
>>> +         || !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
>>>         {
>>>           machine_mode mode = TYPE_MODE (TREE_TYPE (rhs1));
>>>           itype
>>> diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
>>> index 657a8d1..cfa9a97 100644
>>> --- a/gcc/tree-vrp.c
>>> +++ b/gcc/tree-vrp.c
>>> @@ -5245,7 +5245,7 @@ register_edge_assert_for_2 (tree name, edge 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))))
>>> +             && full_integral_type_p (TREE_TYPE (val)))
>>>             {
>>>               mask = wi::mask (tree_to_uhwi (cst2), false, prec);
>>>               val2 = fold_binary (LSHIFT_EXPR, TREE_TYPE (val), val, cst2);
>>> diff --git a/gcc/tree.h b/gcc/tree.h
>>> index 46debc1..237f234 100644
>>> --- a/gcc/tree.h
>>> +++ b/gcc/tree.h
>>> @@ -5394,4 +5394,25 @@ struct builtin_structptr_type
>>>    const char *str;
>>>  };
>>>  extern const builtin_structptr_type builtin_structptr_types[6];
>>> +
>>> +/* Return true if the mode underlying scalar type T has the same number
>>> +   of bits as T does.  Examples of when this is false include bitfields
>>> +   that are narrower than the mode that contains them.  */
>>> +
>>> +inline bool
>>> +scalar_type_is_full_p (const_tree t)
>>> +{
>>> +  return (GET_MODE_PRECISION (TYPE_CHECK (t)->type_common.mode)
>>> +         == TYPE_PRECISION (t));
>>> +}
>>> +
>>> +/* Return true if T is an integral type that has the same number of bits
>>> +   as its underlying mode.  */
>>> +
>>> +inline bool
>>> +full_integral_type_p (const_tree t)
>>> +{
>>> +  return INTEGRAL_TYPE_P (t) && scalar_type_is_full_p (t);
>>> +}
>>> +
>>>  #endif  /* GCC_TREE_H  */
>>> diff --git a/gcc/ubsan.c b/gcc/ubsan.c
>>> index 49e38fa..40f5f3e 100644
>>> --- a/gcc/ubsan.c
>>> +++ b/gcc/ubsan.c
>>> @@ -1582,9 +1582,8 @@ instrument_si_overflow (gimple_stmt_iterator gsi)
>>>
>>>    /* If this is not a signed operation, don't instrument anything here.
>>>       Also punt on bit-fields.  */
>>> -  if (!INTEGRAL_TYPE_P (lhsinner)
>>> -      || TYPE_OVERFLOW_WRAPS (lhsinner)
>>> -      || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION 
>>> (lhsinner))
>>> +  if (!full_integral_type_p (lhsinner)
>>> +      || TYPE_OVERFLOW_WRAPS (lhsinner))
>>>      return;
>>>
>>>    switch (code)

Reply via email to