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