Skip to content

Conversation

fhahn
Copy link
Contributor

@fhahn fhahn commented Jun 25, 2025

Adds initial unit tests for early-exit vectorization covering a variation of auto-vectorization and forced interleaving with pragmas.

The interleaving variant is currently mis-compiled and needs

We should probably extend the tests to make sure we cover various other scenarios, including returning the loaded element for the early exit, different index types and array sizes.

Adds initial unit tests for early-exit vectorization covering a
variation of auto-vectorization and forced interleaving with pragmas.

The interleaving variant is currently mis-compiled and needs
 * llvm/llvm-project#145340
 * llvm/llvm-project#145394.

We should probably extend the tests to make sure we cover various other
scenarios, including returning the loaded element for the early exit,
different index types and array sizes.
@fhahn fhahn force-pushed the test-suite-early-exit-vec branch from b349e09 to 28ae6ea Compare June 25, 2025 18:26
@@ -1,3 +1,12 @@

# Enable matrix types extension tests for compilers supporting -fenable-matrix.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the comment doesn't match the code below?

}; \
auto InterleavedFn = [](std::function<void(int *)> II) -> unsigned { \
Init II(Src); \
_Pragma("clang loop vectorize(enable) interleave_count(4)") Loop \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this PR cannot be merged until the pragma has handled correctly.

/// * one where VF is picked automatically and interleaving is forced.
#define DEFINE_SCALAR_AND_VECTOR_EARLY_EXIT(Init, Src, Loop) \
auto ScalarFn = [](std::function<void(int *)> II) -> unsigned { \
Init II(Src); \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty confusing as it looks like constructing a variable. Can you split this out over different lines so it's clearer, i.e.

  InitSrc;
  II(Src);

// for to zero.
auto Init1 = [IdxToFind](int *Arr) {
std::fill_n(Arr, N, 1);
if (IdxToFind < N)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a risk that a future compiler optimisation basically figures out the answer based on this init code (after inlining) and just optimises ScalarFn to return a constant before we even reach the loop vectoriser? It might be better to have Init1 and Init2 as real functions marked as noinline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants