Richard Biener <richard.guent...@gmail.com> writes:
> On Tue, Nov 10, 2015 at 1:09 AM, Bernd Schmidt <bschm...@redhat.com> wrote:
>> On 11/07/2015 01:46 PM, Richard Sandiford wrote:
>>>
>>> @@ -3814,8 +3817,8 @@ extract_range_basic (value_range *vr, gimple *stmt)
>>>           break;
>>>           /* Both __builtin_ffs* and __builtin_popcount return
>>>              [0, prec].  */
>>> -       CASE_INT_FN (BUILT_IN_FFS):
>>> -       CASE_INT_FN (BUILT_IN_POPCOUNT):
>>> +       CASE_CFN_FFS:
>>> +       CASE_CFN_POPCOUNT:
>>>           arg = gimple_call_arg (stmt, 0);
>>>           prec = TYPE_PRECISION (TREE_TYPE (arg));
>>>           mini = 0;
>>
>>
>> So let me see if I understood this. From what we discussed the purpose of
>> these new internal functions is that they can have vector types. If so,
>> isn't this code (here and elsewhere) which expects integers potentially
>> going to be confused?
>
> We indeed need to add additional checks to most users of CASE_CFN_* to cover
> the bigger freedom that exists with respect to types.

The code above is OK because it's only handling integral types.
A vector popcount or vector ffs must return a vector result.

> Richard, please audit all the cases you change for that.

I had another look and the only problematical uses I could see are the
match.pd ones.  E.g.:

 /* Optimize logN(func()) for various exponential functions.  We
    want to determine the value "x" and the power "exponent" in
    order to transform logN(x**exponent) into exponent*logN(x).  */
 (for logs (LOG  LOG   LOG   LOG2 LOG2  LOG2  LOG10 LOG10)
      exps (EXP2 EXP10 POW10 EXP  EXP10 POW10 EXP   EXP2)
  (simplify
   (logs (exps @0))
   (with {
     tree x;
     switch (exps)
       {
       CASE_CFN_EXP:
         /* Prepare to do logN(exp(exponent)) -> exponent*logN(e).  */
         x = build_real_truncate (type, dconst_e ());
         break;
       CASE_CFN_EXP2:
         /* Prepare to do logN(exp2(exponent)) -> exponent*logN(2).  */
         x = build_real (type, dconst2);
         break;
       CASE_CFN_EXP10:
       CASE_CFN_POW10:
         /* Prepare to do logN(exp10(exponent)) -> exponent*logN(10).  */
         {
           REAL_VALUE_TYPE dconst10;
           real_from_integer (&dconst10, VOIDmode, 10, SIGNED);
           x = build_real (type, dconst10);
         }
         break;
       default:
         gcc_unreachable ();
       }
     }
    (mult (logs { x; }) @0))))

Here we could either add a SCALAR_FLOAT_TYPE_P check or extend
build_real to handle vector types.  Which do you think would be best?

Thanks,
Richard

Reply via email to