Hi Richard,
> -----Original Message-----
> From: Richard Biener [mailto:[email protected]]
> Sent: Wednesday, August 05, 2015 2:21 PM
> To: Kumar, Venkataramanan
> Cc: Jeff Law; Jakub Jelinek; [email protected]
> Subject: Re: [RFC] [Patch]: Try and vectorize with shift for mult expr with
> power 2 integer constant.
>
> On Tue, Aug 4, 2015 at 6:49 PM, Kumar, Venkataramanan
> <[email protected]> wrote:
> > Hi Richard,
> >
> >
> >> -----Original Message-----
> >> From: Richard Biener [mailto:[email protected]]
> >> Sent: Tuesday, August 04, 2015 4:07 PM
> >> To: Kumar, Venkataramanan
> >> Cc: Jeff Law; Jakub Jelinek; [email protected]
> >> Subject: Re: [RFC] [Patch]: Try and vectorize with shift for mult
> >> expr with power 2 integer constant.
> >>
> >> On Tue, Aug 4, 2015 at 10:52 AM, Kumar, Venkataramanan
> >> <[email protected]> wrote:
> >> > Hi Jeff,
> >> >
> >> >> -----Original Message-----
> >> >> From: [email protected] [mailto:gcc-patches-
> >> >> [email protected]] On Behalf Of Jeff Law
> >> >> Sent: Monday, August 03, 2015 11:42 PM
> >> >> To: Kumar, Venkataramanan; Jakub Jelinek
> >> >> Cc: Richard Beiner ([email protected]);
> >> >> [email protected]
> >> >> Subject: Re: [RFC] [Patch]: Try and vectorize with shift for mult
> >> >> expr with power 2 integer constant.
> >> >>
> >> >> On 08/02/2015 05:03 AM, Kumar, Venkataramanan wrote:
> >> >> > Hi Jakub,
> >> >> >
> >> >> > Thank you for reviewing the patch.
> >> >> >
> >> >> > I have incorporated your comments in the attached patch.
> >> >> Note Jakub is on PTO for the next 3 weeks.
> >> >
> >> > Thank you for this information.
> >> >
> >> >>
> >> >>
> >> >> >
> >> >> >
> >> >> >
> >> >> > vectorize_mults_via_shift.diff.txt
> >> >> >
> >> >> >
> >> >> > diff --git a/gcc/testsuite/gcc.dg/vect/vect-mult-patterns.c
> >> >> > b/gcc/testsuite/gcc.dg/vect/vect-mult-patterns.c
> >> >> Jakub would probably like more testcases :-)
> >> >>
> >> >> The most obvious thing to test would be other shift factors.
> >> >>
> >> >> A negative test to verify we don't try to turn a multiply by
> >> >> non-constant or multiply by a constant that is not a power of 2 into
> shifts.
> >> >
> >> > I have added negative test in the attached patch.
> >> >
> >> >
> >> >>
> >> >> [ Would it make sense, for example, to turn a multiply by 3 into a
> >> >> shift-add sequence? As Jakub said, choose_mult_variant can be
> >> >> your friend. ]
> >> >
> >> > Yes I will do that in a follow up patch.
> >> >
> >> > The new change log becomes
> >> >
> >> > gcc/ChangeLog
> >> > 2015-08-04 Venkataramanan Kumar
> >> <[email protected]>
> >> > * tree-vect-patterns.c (vect_recog_mult_pattern): New function
> >> > for
> >> vectorizing
> >> > multiplication patterns.
> >> > * tree-vectorizer.h: Adjust the number of patterns.
> >> >
> >> > gcc/testsuite/ChangeLog
> >> > 2015-08-04 Venkataramanan Kumar
> >> <[email protected]>
> >> > * gcc.dg/vect/vect-mult-pattern-1.c: New
> >> > * gcc.dg/vect/vect-mult-pattern-2.c: New
> >> >
> >> > Bootstrapped and reg tested on aarch64-unknown-linux-gnu.
> >> >
> >> > Ok for trunk ?
> >>
> >> + if (TREE_CODE (oprnd0) != SSA_NAME
> >> + || TREE_CODE (oprnd1) != INTEGER_CST
> >> + || TREE_CODE (itype) != INTEGER_TYPE
> >>
> >> INTEGRAL_TYPE_P (itype)
> >>
> >> + optab = optab_for_tree_code (LSHIFT_EXPR, vectype, optab_vector);
> >> + if (!optab
> >> + || optab_handler (optab, TYPE_MODE (vectype)) ==
> >> CODE_FOR_nothing)
> >> + return NULL;
> >> +
> >>
> >> indent of the return stmt looks wrong
> >>
> >> + /* Handle constant operands that are postive or negative powers of 2.
> >> + */ if ( wi::exact_log2 (oprnd1) != -1 ||
> >> + wi::exact_log2 (wi::neg (oprnd1)) != -1)
> >>
> >> no space after (, || goes to the next line.
> >>
> >> + {
> >> + tree shift;
> >> +
> >> + if (wi::exact_log2 (oprnd1) != -1)
> >>
> >> please cache wi::exact_log2
> >>
> >> in fact the first if () looks redundant if you simply put an else
> >> return NULL after a else if (wi::exact_log2 (wi::neg (oprnd1)) != -1)
> >>
> >> Note that the issue with INT_MIN is that wi::neg (INT_MIN) is INT_MIN
> >> again, but it seems that wi::exact_log2 returns -1 in that case so
> >> you are fine (and in fact not handling this case).
> >>
> >
> > I have updated your review comments in the attached patch.
> >
> > For the INT_MIN case, I am getting vectorized output with the patch. I
> believe x86_64 also vectorizes but does not negates the results.
> >
> > #include <limits.h>
> > unsigned long int __attribute__ ((aligned (64)))arr[100];
> >
> > int i;
> > #if 1
> > void test_vector_shifts()
> > {
> > for(i=0; i<=99;i++)
> > arr[i]=arr[i] * INT_MIN;
> > }
> > #endif
> >
> > void test_vectorshift_via_mul()
> > {
> > for(i=0; i<=99;i++)
> > arr[i]=arr[i]*(-INT_MIN);
> >
> > }
> >
> > Before
> > ---------
> > ldr x1, [x0]
> > neg x1, x1, lsl 31
> > str x1, [x0], 8
> > cmp x0, x2
> >
> > After
> > -------
> > ldr q0, [x0]
> > shl v0.2d, v0.2d, 31
> > neg v0.2d, v0.2d
> > str q0, [x0], 16
> > cmp x1, x0
> >
> > is this fine ?
>
> The interesting case is of course LONG_MIN if you are vectorizing a long
> multiplication.
> Also check with arr[] being 'long', not 'unsigned long'. Note that with
> 'long'
> doing
> arr[i]*(-LONG_MIN) invokes undefined behavior.
>
> Richard.
I checked this case
#include<stdlib.h>
#include <limits.h>
long int __attribute__ ((aligned (64))) arr[100]={1};
long int i;
void test_vector_shifts();
void main()
{
test_vector_shifts();
if(!(arr[0] == (long int)(1*-LONG_MIN))) abort();
printf("%x, %x", arr[0], (long int)(1*-LONG_MIN));
}
void test_vector_shifts()
{
for(i=0; i<=99;i++)
arr[i]=arr[i]*-LONG_MIN;
}
X86_64 vectorizes this and later converts to shifts
.L2:
vmovdqa (%rax), %xmm0
addq $16, %rax
vpsllq $63, %xmm0, %xmm0
vmovaps %xmm0, -16(%rax)
cmpq $arr+800, %rax
jne .L2
On Aarch64 without my patch
.L2:
ldr x1, [x0]
lsl x1, x1, 63
str x1, [x0], 8
cmp x0, x2
bne .L2
With my patch
.L2:
ldr q0, [x0]
shl v0.2d, v0.2d, 63
str q0, [x0], 16
cmp x1, x0
bne .L2
All these cases outputs 0 for the above test case.
>
> > > Thanks,
> >> Richard.
> >>
> >> >>
> >> >>
> >> >>
> >> >> > @@ -2147,6 +2152,140 @@ vect_recog_vector_vector_shift_pattern
> >> >> (vec<gimple> *stmts,
> >> >> > return pattern_stmt;
> >> >> > }
> >> >> >
> >> >> > +/* Detect multiplication by constant which are postive or
> >> >> > +negatives of power 2,
> >> >> s/postive/positive/
> >> >>
> >> >>
> >> >> Jeff
> >> >
> >> > Regards,
> >> > Venkat.
> >> >
Regards,
Venkat.