Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5237,8 +5237,8 @@ width/count of the set of target architectures supported by your application.
...
}

Specifying a width/count of 1 disables the optimization, and is equivalent to
``vectorize(disable)`` or ``interleave(disable)``.
Copy link
Member

Choose a reason for hiding this comment

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

Should be read as:

Specifying a vector width of 1 disables vectorization, and is equivalent to vectorize(disable). Specifying a interleave count of 1 disables interlaving, and is equivalent to interleave(disable).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I understand now, thanks (IMHO this could be a bit confusing).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've been thinking about this for a while, and now I think it triggers ambiguity in the pragma interpretation if we consider vectorize(disable) and vectorize_width(1) to be equivalent.vectorize(disable) vectorize_width(scalable) is an example of such a case. The document says:

Pragmas setting transformation options imply the transformation is enabled, as if it was enabled via the corresponding transformation pragma (e.g. vectorize(enable)). If the transformation is disabled (e.g. vectorize(disable)), that takes precedence over transformations option pragmas implying that transformation.

In this perspective, I think it is correct to ignore vectorize_width(scalable) and disable vectorization, since it falls under "transformations option pragmas implying that transformation". However, it also makes sense to consider vectorize(disable) vectorize_width(scalable) as vectorize_width(1, scalable) if vectorize(disable) is equivalent to vectorize_width(1). In this case, we should process vectorization, as mentioned in the previous review comment.

I think we should stop interpreting vectorize(disable) and vectorize_width(1) as equivalent, but it might break some compatibilities. So, what do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I in princeiple I agree, but considereing that vectorize(disable) vectorize_width(scalable) is being rejected, where is the ambiguity? Is vectorize_width(1) vectorize_width(scalable) the issue? I don't think that it should be interpreted as vectorize_width(1, scalable), it is just conflicting information for the same setting.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct. The previous my comment were written before noticing the fact that vectorize(disable) vectorize_width(scalable) is being rejected. Sorry for confusion, I also don't think that there are any ambiguities.

Specifying a *non-scalable* width/count of 1 disables the optimization, and is
Copy link
Contributor

Choose a reason for hiding this comment

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

This raises the question what it means to specify scalable/non-scalable width/counts. Should this say without the pragma to enable scalable vectorization?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In my understanding, explicitly specifying scalable/non-scalable(fixed) forces vectorizer to use it. Without this pragma allows vectorizer can use either scalable/non-scalable. Does this answer your question?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discarded the documentation changes for now.

equivalent to ``vectorize(disable)`` or ``interleave(disable)``.

Vector predication is enabled by ``vectorize_predicate(enable)``, for example:

Expand Down
13 changes: 9 additions & 4 deletions clang/lib/CodeGen/CGLoopInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,14 @@ LoopInfo::createLoopVectorizeMetadata(const LoopAttributes &Attrs,
LLVMContext &Ctx = Header->getContext();

std::optional<bool> Enabled;
if (Attrs.VectorizeEnable == LoopAttributes::Disable)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps this condition has never been met.


// Vectorization is disabled if:
// 1) it is disabled explicitly, or
// 2) it is implied when vectorize.width is set to 1 and scalable
// vectorization is not specified explicitly.
if (Attrs.VectorizeEnable == LoopAttributes::Disable ||
(Attrs.VectorizeWidth == 1 &&
Attrs.VectorizeScalable != LoopAttributes::Enable))
Enabled = false;
else if (Attrs.VectorizeEnable != LoopAttributes::Unspecified ||
Attrs.VectorizePredicateEnable != LoopAttributes::Unspecified ||
Expand Down Expand Up @@ -643,9 +650,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
case LoopHintAttr::Disable:
switch (Option) {
case LoopHintAttr::Vectorize:
// Disable vectorization by specifying a width of 1.
setVectorizeWidth(1);
setVectorizeScalable(LoopAttributes::Unspecified);
setVectorizeEnable(false);
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't this also disable interleaving?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I haven’t fixed it yet… For now, I’ve added WIP to the PR title.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

break;
case LoopHintAttr::Interleave:
// Disable interleaving by speciyfing a count of 1.
Expand Down
12 changes: 6 additions & 6 deletions clang/test/CodeGenCXX/pragma-loop-pr27643.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ void loop4(int *List, int Length) {
List[i] = i * 2;
}

// CHECK: ![[LOOP1]] = distinct !{![[LOOP1]], [[MP:![0-9]+]], ![[VEC_WIDTH_1:.*]], ![[FIXED_WIDTH:.*]], ![[VEC_ENABLE:.*]]}
// CHECK: ![[VEC_WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
// CHECK: ![[FIXED_WIDTH]] = !{!"llvm.loop.vectorize.scalable.enable", i1 false}
// CHECK: ![[VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK: ![[LOOP1]] = distinct !{![[LOOP1]], [[MP:![0-9]+]], ![[VEC_DISABLE:[0-9]+]]}
// CHECK: ![[VEC_DISABLE]] = !{!"llvm.loop.vectorize.enable", i1 false}

// CHECK: ![[LOOP2]] = distinct !{![[LOOP2]], [[MP]], ![[VEC_WIDTH_2:.*]], ![[FIXED_WIDTH:.*]], ![[VEC_ENABLE]]}
// CHECK: ![[LOOP2]] = distinct !{![[LOOP2]], [[MP]], ![[VEC_WIDTH_2:.*]], ![[FIXED_WIDTH:[0-9]+]], ![[VEC_ENABLE:[0-9]+]]}
// CHECK: ![[VEC_WIDTH_2]] = !{!"llvm.loop.vectorize.width", i32 2}
// CHECK: ![[FIXED_WIDTH]] = !{!"llvm.loop.vectorize.scalable.enable", i1 false}
// CHECK: ![[VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true}

// CHECK: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], ![[VEC_WIDTH_1]], ![[FIXED_WIDTH]]}
// CHECK: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], ![[VEC_DISABLE]]}

// CHECK: ![[LOOP4]] = distinct !{![[LOOP4]], [[MP]], ![[VEC_WIDTH_2]], ![[FIXED_WIDTH]], ![[VEC_ENABLE]]}
21 changes: 10 additions & 11 deletions clang/test/CodeGenCXX/pragma-loop-predicate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ void test3(int *List, int Length) {
List[i] = i * 2;
}

// Check that disabling vectorization means a vectorization width of 1, and
// also that vectorization_predicate isn't enabled.
// Check that vectorization is disabled.
void test4(int *List, int Length) {
// CHECK-LABEL: @{{.*}}test4{{.*}}(
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP4:.*]]
Expand All @@ -48,7 +47,7 @@ void test4(int *List, int Length) {
List[i] = i * 2;
}

// Check that vectorize and vectorize_predicate are disabled.
// Check that vectorize is disabled and vectorize_predicate is ignored.
void test5(int *List, int Length) {
// CHECK-LABEL: @{{.*}}test5{{.*}}(
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP5:.*]]
Expand Down Expand Up @@ -114,16 +113,16 @@ void test9(int *List, int Length) {
// CHECK-NEXT: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], [[GEN6]], [[GEN3]]}

// CHECK-NEXT: ![[LOOP4]] = distinct !{![[LOOP4]], [[MP]], [[GEN10:![0-9]+]]}
// CHECK-NEXT: [[GEN10]] = !{!"llvm.loop.vectorize.width", i32 1}
// CHECK-NEXT: [[GEN10]] = !{!"llvm.loop.vectorize.enable", i1 false}

// CHECK-NEXT: ![[LOOP5]] = distinct !{![[LOOP5]], [[MP]], [[GEN6]], [[GEN10]]}
// CHECK-NEXT: ![[LOOP5]] = distinct !{![[LOOP5]], [[MP]], [[GEN10]]}

// CHECK-NEXT: ![[LOOP6]] = distinct !{![[LOOP6]], [[MP]], [[GEN8]], [[GEN10]], [[GEN11:![0-9]+]]}
// CHECK-NEXT: [[GEN11]] = !{!"llvm.loop.vectorize.scalable.enable", i1 false}
// CHECK-NEXT: ![[LOOP6]] = distinct !{![[LOOP6]], [[MP]], [[GEN10]]}

// CHECK-NEXT: ![[LOOP7]] = distinct !{![[LOOP7]], [[MP]], [[GEN8]], [[GEN12:![0-9]+]], [[GEN11]], [[GEN3]]}
// CHECK-NEXT: [[GEN12]] = !{!"llvm.loop.vectorize.width", i32 4}
// CHECK-NEXT: ![[LOOP7]] = distinct !{![[LOOP7]], [[MP]], [[GEN8]], [[GEN11:![0-9]+]], [[GEN12:![0-9]+]], [[GEN3]]}
// CHECK-NEXT: [[GEN11]] = !{!"llvm.loop.vectorize.width", i32 4}
// CHECK-NEXT: [[GEN12]] = !{!"llvm.loop.vectorize.scalable.enable", i1 false}

// CHECK-NEXT: ![[LOOP8]] = distinct !{![[LOOP8]], [[MP]], [[GEN6]], [[GEN10]], [[GEN11]]}
// CHECK-NEXT: ![[LOOP8]] = distinct !{![[LOOP8]], [[MP]], [[GEN10]]}

// CHECK-NEXT: ![[LOOP9]] = distinct !{![[LOOP9]], [[MP]], [[GEN6]], [[GEN12]], [[GEN11]], [[GEN3]]}
// CHECK-NEXT: ![[LOOP9]] = distinct !{![[LOOP9]], [[MP]], [[GEN6]], [[GEN11]], [[GEN12]], [[GEN3]]}
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/pragma-loop-safety.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ void interleave_test(int *List, int Length) {
// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK: ![[ACCESS_GROUP_8]] = distinct !{}
// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], [[MP]], ![[PARALLEL_ACCESSES_11:[0-9]+]], ![[UNROLL_DISABLE]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]]}
// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], [[MP]], ![[PARALLEL_ACCESSES_11:[0-9]+]], ![[UNROLL_DISABLE]], ![[VECTORIZE_DISABLED:[0-9]+]]}
// CHECK: ![[PARALLEL_ACCESSES_11]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_8]]}
// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
// CHECK: ![[VECTORIZE_DISABLED]] = !{!"llvm.loop.vectorize.enable", i1 false}
34 changes: 33 additions & 1 deletion clang/test/CodeGenCXX/pragma-loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,34 @@ void for_test_scalable_1(int *List, int Length) {
}
}

// Verify for loop is not performing vectorization
void for_test_width_1(int *List, int Length) {
#pragma clang loop vectorize_width(1) interleave_count(4) unroll(disable) distribute(disable)
for (int i = 0; i < Length; i++) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_20:.*]]
List[i] = i * 2;
}
}

// Verify for loop is not performing vectorization
void for_test_fixed_1(int *List, int Length) {
#pragma clang loop vectorize_width(1, fixed) interleave_count(4) unroll(disable) distribute(disable)
for (int i = 0; i < Length; i++) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_21:.*]]
List[i] = i * 2;
}
}


// Verify unroll attributes are directly attached to the loop metadata
void for_test_vectorize_disable_unroll(int *List, int Length) {
#pragma clang loop vectorize(disable) unroll_count(8)
for (int i = 0; i < Length; i++) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_22:.*]]
List[i] = i * 2;
}
}

// CHECK-DAG: ![[MP:[0-9]+]] = !{!"llvm.loop.mustprogress"}

// CHECK-DAG: ![[UNROLL_DISABLE:[0-9]+]] = !{!"llvm.loop.unroll.disable"}
Expand All @@ -220,6 +248,7 @@ void for_test_scalable_1(int *List, int Length) {
// CHECK-DAG: ![[INTERLEAVE_16:[0-9]+]] = !{!"llvm.loop.interleave.count", i32 16}

// CHECK-DAG: ![[VECTORIZE_ENABLE:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK-DAG: ![[VECTORIZE_DISABLE:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 false}
// CHECK-DAG: ![[FIXED_VEC:[0-9]+]] = !{!"llvm.loop.vectorize.scalable.enable", i1 false}
// CHECK-DAG: ![[SCALABLE_VEC:[0-9]+]] = !{!"llvm.loop.vectorize.scalable.enable", i1 true}
// CHECK-DAG: ![[WIDTH_1:[0-9]+]] = !{!"llvm.loop.vectorize.width", i32 1}
Expand All @@ -241,7 +270,7 @@ void for_test_scalable_1(int *List, int Length) {

// CHECK-DAG: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[WIDTH_2]], ![[FIXED_VEC]], ![[INTERLEAVE_2]], ![[VECTORIZE_ENABLE]]}

// CHECK-DAG: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[MP]], ![[UNROLL_DISABLE]], ![[DISTRIBUTE_DISABLE]], ![[WIDTH_1]]}
// CHECK-DAG: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[MP]], ![[UNROLL_DISABLE]], ![[DISTRIBUTE_DISABLE]], ![[VECTORIZE_DISABLE]]}

// CHECK-DAG: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[MP]], ![[WIDTH_2]], ![[FIXED_VEC]], ![[INTERLEAVE_2]], ![[VECTORIZE_ENABLE]], ![[FOLLOWUP_VECTOR_3]]}

Expand Down Expand Up @@ -270,3 +299,6 @@ void for_test_scalable_1(int *List, int Length) {
// CHECK-DAG: ![[LOOP_17]] = distinct !{![[LOOP_17]], ![[MP]], ![[UNROLL_DISABLE]], ![[DISTRIBUTE_DISABLE]], ![[FIXED_VEC]], ![[INTERLEAVE_4]], ![[VECTORIZE_ENABLE]]}
// CHECK-DAG: ![[LOOP_18]] = distinct !{![[LOOP_18]], ![[MP]], ![[UNROLL_DISABLE]], ![[DISTRIBUTE_DISABLE]], ![[SCALABLE_VEC]], ![[INTERLEAVE_4]], ![[VECTORIZE_ENABLE]]}
// CHECK-DAG: ![[LOOP_19]] = distinct !{![[LOOP_19]], ![[MP]], ![[UNROLL_DISABLE]], ![[DISTRIBUTE_DISABLE]], ![[WIDTH_1]], ![[SCALABLE_VEC]], ![[INTERLEAVE_4]], ![[VECTORIZE_ENABLE]]}
// CHECK-DAG: ![[LOOP_20]] = distinct !{![[LOOP_20]], ![[MP]], ![[UNROLL_DISABLE]], ![[DISTRIBUTE_DISABLE]], ![[VECTORIZE_DISABLE]]}
// CHECK-DAG: ![[LOOP_21]] = distinct !{![[LOOP_21]], ![[MP]], ![[UNROLL_DISABLE]], ![[DISTRIBUTE_DISABLE]], ![[VECTORIZE_DISABLE]]}
// CHECK-DAG: ![[LOOP_22]] = distinct !{![[LOOP_22]], ![[MP]], ![[VECTORIZE_DISABLE]], ![[UNROLL_8]]}
2 changes: 1 addition & 1 deletion clang/test/OpenMP/omp_with_loop_pragma.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// RUN: %clang_cc1 -verify -x c -emit-llvm %s -triple x86_64-unknown-linux -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
// expected-no-diagnostics

// CHECK: !{{[0-9]+}} = !{!"llvm.loop.vectorize.width", i32 1}
// CHECK: !{{[0-9]+}} = !{!"llvm.loop.vectorize.enable", i1 false}
void sub(double *restrict a, double *restrict b, int n) {
int i;

Expand Down
Loading