On Fri, 16 Apr 2021, Jakub Jelinek wrote: > Hi! > > The following testcase ICEs because disabling of DCE means there are dead > stmts in the loop (though, in theory they could become dead only shortly > before if-conv through some optimization), ifcvt which goes through all > stmts in the loop if-converts them into .COND_DIV etc. internal fn calls > in the copy of the loop meant for vectorization only, the loop is > successfully vectorized but the particular .COND_* call is not because > it isn't a live statement and the scalar .COND_* remains in the IL until > expansion where it ICEs because these ifns only support vectors and not > scalars. > > These ifns are similar to .MASK_{LOAD,STORE} in this behavior. > > One possible fix could be to expand scalar versions of them during > expansion, basically undoing what if-conv did to create them, i.e. > expand them as the lhs = else; if (mask) { lhs = statement; } or so. > > For .MASK_LOAD we have code to replace them in vect_transform_loop already > though (not needed for .MASK_STORE, as stores should be always live > and thus always vectorized), so this patch instead replaces .COND_* > similarly to .MASK_LOAD in that loop, with the small difference > that lhs = .MASK_LOAD (...); is replaced by lhs = 0; while > lhs = .COND_* (..., else_arg); is replaced by lhs = else_arg. > The statement must be dead, otherwise it would be vectorized, so I think > it is not a big deal we don't turn it back into multiple basic blocks etc. > (and it might be not possible to do that at that point). > > Bootstrapped/regtested on {x86_64,i686,aarch64}-linux, ok for trunk?
OK. Thanks, Richard. > 2021-04-16 Jakub Jelinek <ja...@redhat.com> > > PR target/99767 > * tree-vect-loop.c (vect_transform_loop): Don't remove just > dead scalar .MASK_LOAD calls, but also dead .COND_* calls - replace > them by their last argument. > > * gcc.target/aarch64/pr99767.c: New test. > > --- gcc/tree-vect-loop.c.jj 2021-04-07 12:35:13.000000000 +0200 > +++ gcc/tree-vect-loop.c 2021-04-15 17:21:58.750101894 +0200 > @@ -9676,7 +9676,10 @@ vect_transform_loop (loop_vec_info loop_ > !gsi_end_p (gsi); gsi_next (&gsi)) > { > gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi)); > - if (call && gimple_call_internal_p (call, IFN_MASK_LOAD)) > + if (!call || !gimple_call_internal_p (call)) > + continue; > + internal_fn ifn = gimple_call_internal_fn (call); > + if (ifn == IFN_MASK_LOAD) > { > tree lhs = gimple_get_lhs (call); > if (!VECTOR_TYPE_P (TREE_TYPE (lhs))) > @@ -9686,6 +9689,17 @@ vect_transform_loop (loop_vec_info loop_ > gsi_replace (&gsi, new_stmt, true); > } > } > + else if (conditional_internal_fn_code (ifn) != ERROR_MARK) > + { > + tree lhs = gimple_get_lhs (call); > + if (!VECTOR_TYPE_P (TREE_TYPE (lhs))) > + { > + tree else_arg > + = gimple_call_arg (call, gimple_call_num_args (call) - 1); > + gimple *new_stmt = gimple_build_assign (lhs, else_arg); > + gsi_replace (&gsi, new_stmt, true); > + } > + } > } > } /* BBs in loop */ > > --- gcc/testsuite/gcc.target/aarch64/pr99767.c.jj 2021-04-15 > 17:28:10.466928380 +0200 > +++ gcc/testsuite/gcc.target/aarch64/pr99767.c 2021-04-15 > 17:28:45.653533566 +0200 > @@ -0,0 +1,16 @@ > +/* PR target/99767 */ > +/* { dg-do compile } */ > +/* { dg-options " -O1 -fopenmp-simd -fno-tree-dce -march=armv8-a+sve" } */ > + > +int a[1024], b[1024]; > + > +void > +foo (void) > +{ > + #pragma omp simd > + for (int i = 0; i < 1024; i++) > + if (b[i] > 23) { > + a[i] = b[i] + 1; > + int v = 1 / 0; /* { dg-warning "division by zero" } */ > + } > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)