This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH]: fix for PR middle-end/38250
On Thu, Nov 27, 2008 at 2:22 PM, Tomas Bily <tbily@suse.cz> wrote:
> Hi,
>
> re-organized.
>
>> On Wed, Nov 26, 2008 at 4:43 PM, Tomas Bily <tbily@suse.cz> wrote:
>> > Hi,
>> >
>> > The PR is caused by two problems:
>> >
>> > In tree-loop-distribution.c (generate_memset_zero):
>> >
>> > 1. It can be DR_STEP(dr) NULL. But it is passed into fold_build2 that
>> > expect two non null expressions.
>> >
>> > 2. If program flow goes to end: due to goto then temporary variables created
>> > during force_gimple_operand are added to referenced vars. But this variables
>> > have not def bb. So later checks fails.
>> >
>> > This patch add check for DR_STEP and remove newly generated stmts if
>> > generating of memset fails.
>> >
>> > Tested and bootsraped on x86_64-unknown-linux-gnu.
>> >
>> > OK for mainline ?
>>
>> Please re-organize the function instead to not add the stmts until needed.
>> This looks trivially possible.
>>
>> Thanks,
>> Richard.
>>
>> > Greetings
>> > Tomas
>> >
>
> Tested and bootsraped on x86_64-unknown-linux-gnu.
> OK for mainline ?
It looks like dr_analyze_innermost should rather return a boolean
result indicating whether it failed or not. Instead of testing DR_STEP
for NULL you should then test the result of dr_analyze_innermost.
Please also update the other caller in tree-predcom.c.
Otherwise the patch is ok.
Thanks,
Richard.
> Greetings
> Tomas
>
> Changelog:
>
> PR middle-end/38250
> * tree-loop-distribution.c (build_size_arg): New function.
> (generate_memset_zero): Checks if DR_STEP(de) is NULL.
> Reorganized generating of stmts.
>
> Index: tree-loop-distribution.c
> ===================================================================
> --- tree-loop-distribution.c (revision 142159)
> +++ tree-loop-distribution.c (working copy)
> @@ -216,13 +216,30 @@ generate_loops_for_partition (struct loo
> return true;
> }
>
> +/* Build size argument. */
> +
> +static inline tree
> +build_size_arg (tree nb_iter, tree op, gimple_seq* stmt_list)
> +{
> + tree nb_bytes;
> + gimple_seq stmts = NULL;
> +
> + nb_bytes = fold_build2 (MULT_EXPR, TREE_TYPE (nb_iter),
> + nb_iter, TYPE_SIZE_UNIT (TREE_TYPE (op)));
> + nb_bytes = force_gimple_operand (nb_bytes, &stmts, true, NULL);
> + gimple_seq_add_seq (stmt_list, stmts);
> +
> + return nb_bytes;
> +}
> +
> /* Generate a call to memset. Return true when the operation succeeded. */
>
> static bool
> generate_memset_zero (gimple stmt, tree op0, tree nb_iter,
> gimple_stmt_iterator bsi)
> {
> - tree t, nb_bytes, addr_base;
> + tree t, addr_base;
> + tree nb_bytes = NULL;
> bool res = false;
> gimple_seq stmts = NULL, stmt_list = NULL;
> gimple fn_call;
> @@ -231,15 +248,13 @@ generate_memset_zero (gimple stmt, tree
> ssa_op_iter iter;
> struct data_reference *dr = XCNEW (struct data_reference);
>
> - nb_bytes = fold_build2 (MULT_EXPR, TREE_TYPE (nb_iter),
> - nb_iter, TYPE_SIZE_UNIT (TREE_TYPE (op0)));
> - nb_bytes = force_gimple_operand (nb_bytes, &stmts, true, NULL);
> - gimple_seq_add_seq (&stmt_list, stmts);
> -
> DR_STMT (dr) = stmt;
> DR_REF (dr) = op0;
> dr_analyze_innermost (dr);
>
> + if (!DR_STEP (dr))
> + goto end;
> +
> /* Test for a positive stride, iterating over every element. */
> if (integer_zerop (fold_build2 (MINUS_EXPR, integer_type_node, DR_STEP (dr),
> TYPE_SIZE_UNIT (TREE_TYPE (op0)))))
> @@ -253,6 +268,7 @@ generate_memset_zero (gimple stmt, tree
> TYPE_SIZE_UNIT (TREE_TYPE (op0)),
> DR_STEP (dr))))
> {
> + nb_bytes = build_size_arg (nb_iter, op0, &stmt_list);
> addr_base = size_binop (PLUS_EXPR, DR_OFFSET (dr), DR_INIT (dr));
> addr_base = fold_build2 (MINUS_EXPR, sizetype, addr_base, nb_bytes);
> addr_base = force_gimple_operand (addr_base, &stmts, true, NULL);
> @@ -272,6 +288,8 @@ generate_memset_zero (gimple stmt, tree
> fntype = TREE_TYPE (fndecl);
> fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
>
> + if (!nb_bytes)
> + nb_bytes = build_size_arg (nb_iter, op0, &stmt_list);
> fn_call = gimple_build_call (fn, 3, mem, integer_zero_node, nb_bytes);
> gimple_seq_add_stmt (&stmt_list, fn_call);
>
> Index: testsuite/gcc.dg/tree-ssa/pr38250.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/pr38250.c (revision 0)
> +++ testsuite/gcc.dg/tree-ssa/pr38250.c (revision 0)
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -ftree-loop-distribution" } */
> +
> +typedef long unsigned int size_t;
> +typedef struct {
> + long dat[2];
> +} gsl_complex_long_double;
> +typedef struct {
> + size_t size;
> + size_t stride;
> + long *data;
> +} gsl_vector_complex_long_double;
> +
> +void gsl_vector_complex_long_double_set_zero (gsl_vector_complex_long_double * v)
> +{
> + long * const data = v->data;
> + const size_t n = v->size;
> + const size_t stride = v->stride;
> + const gsl_complex_long_double zero = { { 0,0} } ;
> + size_t i;
> + for (i = 0; i < n; i++)
> + *(gsl_complex_long_double *) (data + 2 * i * stride) = zero;
> +}
> +
>