vect, omp: inbranch simdclone dropping const

The const attribute is ignored when simdclone's are used inbranch. This is due
to the fact that when analyzing a MASK_CALL we were not looking at the targeted
function for flags, but instead only at the internal function call itself.
This patch adds code to make sure we look at the target function to check for
the const attribute and enables the autovectorization of inbranch const
simdclones without needing the loop to be adorned the 'openmp simd' pragma.

gcc/ChangeLog:

	* tree-data-ref.cc (include calls.h): Add new include.
	(get_references_in_stmt): Correctly handle IFN_MASK_CALL.

gcc/testsuite/ChangeLog:

	* gcc.dg/vect/vect-simd-clone-19.c: New test.
This commit is contained in:
Andre Vieira 2023-09-27 11:05:40 +01:00
parent f7d7e26f10
commit b31218bc93
2 changed files with 37 additions and 2 deletions

View file

@ -0,0 +1,22 @@
/* { dg-require-effective-target vect_simd_clones } */
/* { dg-do compile } */
int __attribute__ ((__simd__, const)) fn (int);
void test (int * __restrict__ a, int * __restrict__ b, int n)
{
for (int i = 0; i < n; ++i)
{
int a_;
if (b[i] > 0)
a_ = fn (b[i]);
else
a_ = b[i] + 5;
a[i] = a_;
}
}
/* { dg-final { scan-tree-dump-not {loop contains function calls or data references} "vect" } } */
/* The LTO test produces two dump files and we scan the wrong one. */
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */

View file

@ -100,6 +100,7 @@ along with GCC; see the file COPYING3. If not see
#include "vr-values.h"
#include "range-op.h"
#include "tree-ssa-loop-ivopts.h"
#include "calls.h"
static struct datadep_stats
{
@ -5816,6 +5817,15 @@ get_references_in_stmt (gimple *stmt, vec<data_ref_loc, va_heap> *references)
}
case IFN_MASK_LOAD:
case IFN_MASK_STORE:
break;
case IFN_MASK_CALL:
{
tree orig_fndecl
= gimple_call_addr_fndecl (gimple_call_arg (stmt, 0));
if (!orig_fndecl
|| (flags_from_decl_or_type (orig_fndecl) & ECF_CONST) == 0)
clobbers_memory = true;
}
break;
default:
clobbers_memory = true;
@ -5852,7 +5862,7 @@ get_references_in_stmt (gimple *stmt, vec<data_ref_loc, va_heap> *references)
}
else if (stmt_code == GIMPLE_CALL)
{
unsigned i, n;
unsigned i = 0, n;
tree ptr, type;
unsigned int align;
@ -5879,13 +5889,16 @@ get_references_in_stmt (gimple *stmt, vec<data_ref_loc, va_heap> *references)
ptr);
references->safe_push (ref);
return false;
case IFN_MASK_CALL:
i = 1;
gcc_fallthrough ();
default:
break;
}
op0 = gimple_call_lhs (stmt);
n = gimple_call_num_args (stmt);
for (i = 0; i < n; i++)
for (; i < n; i++)
{
op1 = gimple_call_arg (stmt, i);