> -----Original Message----- > From: Richard Sandiford <richard.sandif...@arm.com> > Sent: Monday, July 12, 2021 11:26 AM > To: Tamar Christina <tamar.christ...@arm.com> > Cc: Richard Biener <rguent...@suse.de>; nd <n...@arm.com>; gcc- > patc...@gcc.gnu.org > Subject: Re: [PATCH 1/4]middle-end Vect: Add support for dot-product > where the sign for the multiplicant changes. > > Tamar Christina <tamar.christ...@arm.com> writes: > >> -----Original Message----- > >> From: Richard Sandiford <richard.sandif...@arm.com> > >> Sent: Monday, July 12, 2021 10:39 AM > >> To: Tamar Christina <tamar.christ...@arm.com> > >> Cc: Richard Biener <rguent...@suse.de>; nd <n...@arm.com>; gcc- > >> patc...@gcc.gnu.org > >> Subject: Re: [PATCH 1/4]middle-end Vect: Add support for dot-product > >> where the sign for the multiplicant changes. > >> > >> Tamar Christina <tamar.christ...@arm.com> writes: > >> > Hi, > >> > > >> >> Richard Sandiford <richard.sandif...@arm.com> writes: > >> >> >> @@ -992,21 +1029,27 @@ vect_recog_dot_prod_pattern (vec_info > >> >> *vinfo, > >> >> >> /* FORNOW. Can continue analyzing the def-use chain when > >> >> >> this stmt in > >> >> a phi > >> >> >> inside the loop (in case we are analyzing an outer-loop). */ > >> >> >> vect_unpromoted_value unprom0[2]; > >> >> >> + enum optab_subtype subtype = optab_vector; > >> >> >> if (!vect_widened_op_tree (vinfo, mult_vinfo, MULT_EXPR, > >> >> WIDEN_MULT_EXPR, > >> >> >> - false, 2, unprom0, &half_type)) > >> >> >> + false, 2, unprom0, &half_type, &subtype)) > >> >> >> + return NULL; > >> >> >> + > >> >> >> + if (subtype == optab_vector_mixed_sign > >> >> >> + && TYPE_UNSIGNED (unprom_mult.type) > >> >> >> + && TYPE_PRECISION (half_type) * 4 > TYPE_PRECISION > >> >> >> + (unprom_mult.type)) > >> >> >> return NULL; > >> >> > > >> >> > Isn't the final condition here instead that TYPE1 is narrower than > TYPE2? > >> >> > I.e. we need to reject the case in which we multiply a signed > >> >> > and an unsigned value to get a (logically) signed result, but > >> >> > then zero-extend it (rather than sign-extend it) to the > >> >> > precision of the > >> addition. > >> >> > > >> >> > That would make the test: > >> >> > > >> >> > if (subtype == optab_vector_mixed_sign > >> >> > && TYPE_UNSIGNED (unprom_mult.type) > >> >> > && TYPE_PRECISION (unprom_mult.type) < TYPE_PRECISION > (type)) > >> >> > return NULL; > >> >> > > >> >> > instead. > >> >> > >> >> And folding that into the existing test gives: > >> >> > >> >> /* If there are two widening operations, make sure they agree on > >> >> the > >> sign > >> >> of the extension. The result of an optab_vector_mixed_sign > operation > >> >> is signed; otherwise, the result has the same sign as the operands. > */ > >> >> if (TYPE_PRECISION (unprom_mult.type) != TYPE_PRECISION (type) > >> >> && (subtype == optab_vector_mixed_sign > >> >> ? TYPE_UNSIGNED (unprom_mult.type) > >> >> : TYPE_SIGN (unprom_mult.type) != TYPE_SIGN (half_type))) > >> >> return NULL; > >> >> > >> > > >> > I went with the first one which doesn't add the extra constraints > >> > for the normal dotproduct as that makes it too restrictive. It's > >> > the type of the multiplication that determines the operation so > >> > dotproduct can be used a bit more than where we currently do. > >> > > >> > This was relaxed in an earlier patch. > >> > >> I didn't mean that we should add extra constraints to the normal case > though. > >> The existing test I was referring to above was: > >> > >> /* If there are two widening operations, make sure they agree on > >> the sign of the extension. */ > >> if (TYPE_PRECISION (unprom_mult.type) != TYPE_PRECISION (type) > >> && TYPE_SIGN (unprom_mult.type) != TYPE_SIGN (half_type)) > >> return NULL; > > > > But as I mentioned, this restriction is unneeded and has been removed > hence why it's not in my patchset's diff. > > It's removed by > > https://gcc.gnu.org/pipermail/gcc-patches/2021-May/569851.html which > Richi conditioned on the rest of these patches being approved. > > > > This change needlessly blocks test vect-reduc-dot-[2,3,6,7].c from > > being dotproducts for instance > > > > It's also part of the deficiency between GCC codegen and Clang > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88492#c6 > > Hmm, OK. Just removing the check regresses: > > unsigned long __attribute__ ((noipa)) > f (signed short *x, signed short *y) > { > unsigned long res = 0; > for (int i = 0; i < 100; ++i) > res += (unsigned int) x[i] * (unsigned int) y[i]; > return res; > } > > int > main (void) > { > signed short x[100], y[100]; > for (int i = 0; i < 100; ++i) > { > x[i] = -1; > y[i] = 1; > } > if (f (x, y) != 0x6400000000ULL - 100) > __builtin_abort (); > return 0; > } > > on SVE. We then use SDOT even though the result of the multiplication is > zero- rather than sign-extended to 64 bits. Does something else in the series > stop that from that happening?
No, and I hadn't noticed it before because it looks like the mid-end tests that are execution test don't turn on dot-product for arm targets :/ I'll look at it separately, for now I've then added the check back in. Ok for trunk now? Thanks, Tamar > > Richard
rb14433.patch
Description: rb14433.patch