This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Make vectoriser use operand_equal_p to compare base addresses


On Tue, Apr 19, 2011 at 4:59 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> In the attached testcase, we treat:
>
> ? ?sum += x[i][0] * x[i][0] + x[i][1] * x[i][1];
>
> as being two independent strided loads: x[i][0] and x[i][1].
> On targets with appropriate support, we therefore use two interleaved
> loads rather than one, then discard one half of each result.
> This does not happen if bar() is compiled on its own.
>
> The code before vectorisation looks like this:
>
> <bb 3>:
> ?i.0_5 = (unsigned int) i_32;
> ?D.3532_6 = i.0_5 * 320;
> ?D.3533_8 = x_7(D) + D.3532_6;
>
> <bb 4>:
> ?i.1_14 = (unsigned int) i_34;
> ?D.3559_15 = i.1_14 * 8;
> ?D.3558_16 = D.3533_8 + D.3559_15;
> ?D.3557_17 = *D.3558_16[0];
> ?D.3555_19 = *D.3558_16[1];
> ?...
>
> The two DR_BASE_ADDRESSES are therefore the expansion of D.3558_8:
>
> ? ?x_7(D) + (unsigned int) i_32 * 320
>
> which we don't think are equal. ?The comment in tree-data-refs.h
> made me think that (unsigned int) i_32 * 320 ought really to be
> in the DR_OFFSET, but that only seems to apply to offsets that
> occur in the memory reference itself.
>
> Fixed by using operand_equal_p to compare base addresses.
> Tested on x86_64-linux-gnu and arm-linux-gnueabi. ?OK to install?
>
> I've not made the test dependent on a target selector because
> it seemed like the message should be printed regardless.

Ok.

Thanks,
Richard.

> Richard
>
>
> gcc/
> ? ? ? ?* tree-vect-data-refs.c (vect_drs_dependent_in_basic_block): Use
> ? ? ? ?operand_equal_p to compare DR_BASE_ADDRESSes.
> ? ? ? ?(vect_check_interleaving): Likewise.
>
> gcc/testsuite/
> ? ? ? ?* gcc.dg/vect/vect-119.c: New test.
>
> Index: gcc/tree-vect-data-refs.c
> ===================================================================
> --- gcc/tree-vect-data-refs.c ? 2011-04-19 14:59:58.000000000 +0100
> +++ gcc/tree-vect-data-refs.c ? 2011-04-19 14:59:58.000000000 +0100
> @@ -353,11 +353,7 @@ vect_drs_dependent_in_basic_block (struc
>
> ? /* Check that the data-refs have same bases and offsets. ?If not, we can't
> ? ? ?determine if they are dependent. ?*/
> - ?if ((DR_BASE_ADDRESS (dra) != DR_BASE_ADDRESS (drb)
> - ? ? ? && (TREE_CODE (DR_BASE_ADDRESS (dra)) != ADDR_EXPR
> - ? ? ? ? ? || TREE_CODE (DR_BASE_ADDRESS (drb)) != ADDR_EXPR
> - ? ? ? ? ? || TREE_OPERAND (DR_BASE_ADDRESS (dra), 0)
> - ? ? ? ? ? != TREE_OPERAND (DR_BASE_ADDRESS (drb),0)))
> + ?if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0)
> ? ? ? || !dr_equal_offsets_p (dra, drb))
> ? ? return true;
>
> @@ -403,11 +399,7 @@ vect_check_interleaving (struct data_ref
>
> ? /* Check that the data-refs have same first location (except init) and they
> ? ? ?are both either store or load (not load and store). ?*/
> - ?if ((DR_BASE_ADDRESS (dra) != DR_BASE_ADDRESS (drb)
> - ? ? ? && (TREE_CODE (DR_BASE_ADDRESS (dra)) != ADDR_EXPR
> - ? ? ? ? ?|| TREE_CODE (DR_BASE_ADDRESS (drb)) != ADDR_EXPR
> - ? ? ? ? ?|| TREE_OPERAND (DR_BASE_ADDRESS (dra), 0)
> - ? ? ? ? ?!= TREE_OPERAND (DR_BASE_ADDRESS (drb),0)))
> + ?if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0)
> ? ? ? || !dr_equal_offsets_p (dra, drb)
> ? ? ? || !tree_int_cst_compare (DR_INIT (dra), DR_INIT (drb))
> ? ? ? || DR_IS_READ (dra) != DR_IS_READ (drb))
> Index: gcc/testsuite/gcc.dg/vect/vect-119.c
> ===================================================================
> --- /dev/null ? 2011-03-23 08:42:11.268792848 +0000
> +++ gcc/testsuite/gcc.dg/vect/vect-119.c ? ? ? ?2011-04-19 14:59:58.000000000 +0100
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +
> +#define OUTER 32
> +#define INNER 40
> +
> +static unsigned int
> +bar (const unsigned int x[INNER][2], unsigned int sum)
> +{
> + ?int i;
> +
> + ?for (i = 0; i < INNER; i++)
> + ? ?sum += x[i][0] * x[i][0] + x[i][1] * x[i][1];
> + ?return sum;
> +}
> +
> +unsigned int foo (const unsigned int x[OUTER][INNER][2])
> +{
> + ?int i;
> + ?unsigned int sum;
> +
> + ?sum = 0.0f;
> + ?for (i = 0; i < OUTER; i++)
> + ? ?sum = bar (x[i], sum);
> + ?return sum;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Detected interleaving of size 2" 1 "vect" } } */
> +/* { dg-final { cleanup-tree-dump "vect" } } */
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]