On Fri, 2018-04-13 at 17:53 -0500, Segher Boessenkool wrote:
> Hi!
> 
> On Fri, Apr 13, 2018 at 03:27:40PM -0700, Carl Love wrote:
> > On Fri, 2018-04-13 at 16:54 -0500, Segher Boessenkool wrote:
> > > On Fri, Apr 13, 2018 at 09:49:25AM -0700, Carl Love wrote:
> > > > diff --git a/gcc/config/rs6000/rs6000.c
> > > > b/gcc/config/rs6000/rs6000.c
> > > > index a0c9b5c..855be43 100644
> > > > --- a/gcc/config/rs6000/rs6000.c
> > > > +++ b/gcc/config/rs6000/rs6000.c
> > > > @@ -16576,8 +16576,9 @@ rs6000_gimple_fold_builtin
> > > > (gimple_stmt_iterator *gsi)
> > > >        {
> > > >          arg0 = gimple_call_arg (stmt, 0);
> > > >          lhs = gimple_call_lhs (stmt);
> > > > -        /* Only fold the vec_splat_*() if arg0 is
> > > > constant.  */
> > > > -        if (TREE_CODE (arg0) != INTEGER_CST)
> > > > +        /* Only fold the vec_splat_*() if arg0 is a 5-bit
> > > > constant.  */
> > > > +        if (TREE_CODE (arg0) != INTEGER_CST
> > > > +            || TREE_INT_CST_LOW (arg0) & ~0x1f)
> > > >            return false;
> > > 
> > > Should this test for *signed* 5-bit constants only?
> > > 
> > >    if (TREE_CODE (arg0) != INTEGER_CST
> > >        || !IN_RANGE (TREE_INT_CST_LOW (arg0), -16, 15))
> > 
> > The buitins for the unsigned vec_splat_u[8, 16,32]  are actually
> > mapped
> > to their corresponding signed version vec_splat_s[8, 16,32] in
> > altivec.h.  Both the vec_splat_u[8, 16,32] and vec_splat_s[8,
> > 16,32]
> > builtins will get you to the case statement
> > 
> >     /* flavors of vec_splat_[us]{8,16,32}.  */
> >     case ALTIVEC_BUILTIN_VSPLTISB:
> >     case ALTIVEC_BUILTIN_VSPLTISH:
> >     case ALTIVEC_BUILTIN_VSPLTISW:
> > 
> > under which the change is being made.  So technically arg0 could be
> > a
> > signed 5-bit or an unsiged 5-bit value.  Either way the 5-bit value
> > is
> > splatted into the vector with sign extension to 8/16/32 bits.  So I
> > would argue that the IN_RANGE test for signed values is maybe
> > misleading as arg0 could represent a signed or unsigned
> > value.  Both
> > tests, the one from the patch or Segher's suggestion, are really
> > just
> > looking to see if any of the upper bits are 1.  From a functional
> > standpoint, I don't see any difference and feel either one would do
> > the
> > job.  Am I missing anything?
> 
> But then the & ~0x1f test is not good either, it does not work for
> values
> -16..-1 ?
> 
> You cannot handle signed and unsigned exactly the same for the test
> for
> allowed values.
> 
Segher:

The VSPLTIS[S|H|W] can only be used if the value in arg0 is a bit
pattern consisting of at most 5-bits.  The issue is the field in the
vector splat instruction is only five bits wide.  So the value of
TREE_INT_CST_LOW (arg0) & ~0x1f) will be non-zero if the value requires
more then 5-bits to represent.  The if statement will thus evaluate to
TRUE and thus the code returns false indicating we can not do the
folding since the constant requires more then a 5-bit field to
represent.  I don't think we really care how the 5-bits are interpreted
as a signed or unsigned value just that the value can be represented by
at most 5-bits.  

The test

if (TREE_CODE (arg0) != INTEGER_CST
             || TREE_INT_CST_LOW (arg0) & ~0x1f)
           return false;

is really checking if the value is not an integer or the value is not a
5-bit constant.  It seems to me this should work fine for signed and
unsigned 5-bit numbers.

                   Carl 

Reply via email to