diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -3061,7 +3061,7 @@ The ``#pragma clang loop`` directive is used to specify hints for optimizing the subsequent for, while, do-while, or c++11 range-based for loop. The directive -provides options for vectorization, interleaving, predication, unrolling and +provides options for vectorization, interleaving, predication, aligning, unrolling and distribution. Loop hints can be specified before any loop and will be ignored if the optimization is not safe to apply. @@ -3124,6 +3124,17 @@ might be more efficient when vector predication is efficiently supported by the target platform. +Alignment of references inside loop is enabled by ``vectorize_assume_aligned(_value_)`` where _value_ is the alignment specified and it should be a multiple of 2, for example: + +.. code-block::c++ + #pragma clang loop vectorize_assume_alignment(32) + for(...) { + ... + } + +This predicates all the references inside the loop to be aligned to the specified alignment value. The aligned access to them can increase fetch time and increase the performance. + + Loop Unrolling -------------- diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3010,11 +3010,13 @@ ["vectorize", "vectorize_width", "interleave", "interleave_count", "unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count", "pipeline", "pipeline_initiation_interval", "distribute", - "vectorize_predicate"], + "vectorize_predicate", + "vectorize_assume_alignment"], ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount", "Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount", "PipelineDisabled", "PipelineInitiationInterval", "Distribute", - "VectorizePredicate"]>, + "VectorizePredicate", + "VectorizeAssumeAlignment"]>, EnumArgument<"State", "LoopHintState", ["enable", "disable", "numeric", "assume_safety", "full"], ["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>, @@ -3035,6 +3037,7 @@ case PipelineInitiationInterval: return "pipeline_initiation_interval"; case Distribute: return "distribute"; case VectorizePredicate: return "vectorize_predicate"; + case VectorizeAssumeAlignment: return "vectorize_assume_alignment"; } llvm_unreachable("Unhandled LoopHint option."); } diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -2755,7 +2755,7 @@ let Content = [{ The ``#pragma clang loop`` directive allows loop optimization hints to be specified for the subsequent loop. The directive allows pipelining to be -disabled, or vectorization, vector predication, interleaving, and unrolling to +disabled, or vectorization, vector predication, vectorize_assume_alignment, interleaving, and unrolling to be enabled or disabled. Vector width, vector predication, interleave count, unrolling count, and the initiation interval for pipelining can be explicitly specified. See `language extensions diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1210,7 +1210,7 @@ def err_pragma_loop_invalid_option : Error< "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, " "vectorize_width, interleave, interleave_count, unroll, unroll_count, " - "pipeline, pipeline_initiation_interval, vectorize_predicate, or distribute">; + "pipeline, pipeline_initiation_interval, vectorize_predicate, vectorize_assume_alignment, or distribute">; def err_pragma_fp_invalid_option : Error< "%select{invalid|missing}0 option%select{ %1|}0; expected contract">; diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h --- a/clang/lib/CodeGen/CGLoopInfo.h +++ b/clang/lib/CodeGen/CGLoopInfo.h @@ -54,6 +54,9 @@ /// Value for llvm.loop.vectorize.predicate metadata LVEnableState VectorizePredicateEnable; + /// Value of llvm.loop.vectorize_assume_aligned metadata + unsigned VectorizeAssumeAlignment; + /// Value for llvm.loop.vectorize.width metadata. unsigned VectorizeWidth; @@ -250,6 +253,11 @@ StagedAttrs.UnrollAndJamEnable = State; } + /// Set the next pushed loop 'vectorize_assume_aligned' + void setVectorizeAssumeAlignment(unsigned A) { + StagedAttrs.VectorizeAssumeAlignment = A; + } + /// Set the vectorize width for the next loop pushed. void setVectorizeWidth(unsigned W) { StagedAttrs.VectorizeWidth = W; } diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -219,6 +219,7 @@ Enabled = false; else if (Attrs.VectorizeEnable != LoopAttributes::Unspecified || Attrs.VectorizePredicateEnable != LoopAttributes::Unspecified || + Attrs.VectorizeAssumeAlignment != 0 || Attrs.InterleaveCount != 0 || Attrs.VectorizeWidth != 0) Enabled = true; @@ -268,6 +269,15 @@ Args.push_back(MDNode::get(Ctx, Vals)); } + // Setting vectorize_assume_alignment + if (Attrs.VectorizeAssumeAlignment > 0) { + + Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize_assume_alignment"), + ConstantAsMetadata::get(ConstantInt::get( + llvm::Type::getInt32Ty(Ctx), + Attrs.VectorizeAssumeAlignment))}; + Args.push_back(MDNode::get(Ctx, Vals)); + } // Setting vectorize.width if (Attrs.VectorizeWidth > 0) { Metadata *Vals[] = { @@ -432,7 +442,8 @@ : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified), UnrollEnable(LoopAttributes::Unspecified), UnrollAndJamEnable(LoopAttributes::Unspecified), - VectorizePredicateEnable(LoopAttributes::Unspecified), VectorizeWidth(0), + VectorizePredicateEnable(LoopAttributes::Unspecified), + VectorizeAssumeAlignment(0), VectorizeWidth(0), InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0), DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false), PipelineInitiationInterval(0) {} @@ -443,6 +454,7 @@ InterleaveCount = 0; UnrollCount = 0; UnrollAndJamCount = 0; + VectorizeAssumeAlignment = 0; VectorizeEnable = LoopAttributes::Unspecified; UnrollEnable = LoopAttributes::Unspecified; UnrollAndJamEnable = LoopAttributes::Unspecified; @@ -468,6 +480,7 @@ Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 && Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled && Attrs.PipelineInitiationInterval == 0 && + Attrs.VectorizeAssumeAlignment == 0 && Attrs.VectorizePredicateEnable == LoopAttributes::Unspecified && Attrs.VectorizeEnable == LoopAttributes::Unspecified && Attrs.UnrollEnable == LoopAttributes::Unspecified && @@ -504,6 +517,7 @@ BeforeJam.VectorizeEnable = Attrs.VectorizeEnable; BeforeJam.DistributeEnable = Attrs.DistributeEnable; BeforeJam.VectorizePredicateEnable = Attrs.VectorizePredicateEnable; + BeforeJam.VectorizeAssumeAlignment = Attrs.VectorizeAssumeAlignment; switch (Attrs.UnrollEnable) { case LoopAttributes::Unspecified: @@ -519,6 +533,7 @@ break; } + AfterJam.VectorizeAssumeAlignment = Attrs.VectorizeAssumeAlignment; AfterJam.VectorizePredicateEnable = Attrs.VectorizePredicateEnable; AfterJam.UnrollCount = Attrs.UnrollCount; AfterJam.PipelineDisabled = Attrs.PipelineDisabled; @@ -542,6 +557,7 @@ SmallVector BeforeLoopProperties; if (BeforeJam.VectorizeEnable != LoopAttributes::Unspecified || BeforeJam.VectorizePredicateEnable != LoopAttributes::Unspecified || + BeforeJam.VectorizeAssumeAlignment != 0 || BeforeJam.InterleaveCount != 0 || BeforeJam.VectorizeWidth != 0) BeforeLoopProperties.push_back( MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized"))); @@ -642,6 +658,7 @@ case LoopHintAttr::UnrollAndJamCount: case LoopHintAttr::VectorizeWidth: case LoopHintAttr::InterleaveCount: + case LoopHintAttr::VectorizeAssumeAlignment: case LoopHintAttr::PipelineInitiationInterval: llvm_unreachable("Options cannot be disabled."); break; @@ -668,6 +685,7 @@ case LoopHintAttr::UnrollCount: case LoopHintAttr::UnrollAndJamCount: case LoopHintAttr::VectorizeWidth: + case LoopHintAttr::VectorizeAssumeAlignment: case LoopHintAttr::InterleaveCount: case LoopHintAttr::PipelineDisabled: case LoopHintAttr::PipelineInitiationInterval: @@ -686,6 +704,7 @@ case LoopHintAttr::Unroll: case LoopHintAttr::UnrollAndJam: case LoopHintAttr::VectorizePredicate: + case LoopHintAttr::VectorizeAssumeAlignment: case LoopHintAttr::UnrollCount: case LoopHintAttr::UnrollAndJamCount: case LoopHintAttr::VectorizeWidth: @@ -715,6 +734,7 @@ case LoopHintAttr::PipelineDisabled: case LoopHintAttr::PipelineInitiationInterval: case LoopHintAttr::VectorizePredicate: + case LoopHintAttr::VectorizeAssumeAlignment: llvm_unreachable("Options cannot be used with 'full' hint."); break; } @@ -727,6 +747,9 @@ case LoopHintAttr::InterleaveCount: setInterleaveCount(ValueInt); break; + case LoopHintAttr::VectorizeAssumeAlignment: + setVectorizeAssumeAlignment(ValueInt); + break; case LoopHintAttr::UnrollCount: setUnrollCount(ValueInt); break; diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -2821,6 +2821,7 @@ /// 'interleave' '(' loop-hint-keyword ')' /// 'unroll' '(' unroll-hint-keyword ')' /// 'vectorize_predicate' '(' loop-hint-keyword ')' +/// 'vectorize_assume_alignment' '(' loop-hint-value')' /// 'vectorize_width' '(' loop-hint-value ')' /// 'interleave_count' '(' loop-hint-value ')' /// 'unroll_count' '(' loop-hint-value ')' @@ -2883,6 +2884,7 @@ .Case("unroll", true) .Case("distribute", true) .Case("vectorize_predicate", true) + .Case("vectorize_assume_alignment", true) .Case("vectorize_width", true) .Case("interleave_count", true) .Case("unroll_count", true) diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -1,3 +1,4 @@ + //===--- SemaStmtAttr.cpp - Statement Attribute Handling ------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -134,6 +135,7 @@ .Case("vectorize_width", LoopHintAttr::VectorizeWidth) .Case("interleave", LoopHintAttr::Interleave) .Case("vectorize_predicate", LoopHintAttr::VectorizePredicate) + .Case("vectorize_assume_alignment", LoopHintAttr::VectorizeAssumeAlignment) .Case("interleave_count", LoopHintAttr::InterleaveCount) .Case("unroll", LoopHintAttr::Unroll) .Case("unroll_count", LoopHintAttr::UnrollCount) @@ -145,6 +147,7 @@ if (Option == LoopHintAttr::VectorizeWidth || Option == LoopHintAttr::InterleaveCount || Option == LoopHintAttr::UnrollCount || + Option == LoopHintAttr::VectorizeAssumeAlignment || Option == LoopHintAttr::PipelineInitiationInterval) { assert(ValueExpr && "Attribute must have a valid value expression."); if (S.CheckLoopHintExpr(ValueExpr, St->getBeginLoc())) @@ -192,7 +195,7 @@ const LoopHintAttr *NumericAttr; } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, - {nullptr, nullptr}}; + {nullptr, nullptr}, {nullptr, nullptr}}; for (const auto *I : Attrs) { const LoopHintAttr *LH = dyn_cast(I); @@ -209,7 +212,8 @@ UnrollAndJam, Distribute, Pipeline, - VectorizePredicate + VectorizePredicate, + Alignment } Category; switch (Option) { case LoopHintAttr::Vectorize: @@ -220,6 +224,9 @@ case LoopHintAttr::InterleaveCount: Category = Interleave; break; + case LoopHintAttr::VectorizeAssumeAlignment: + Category = Alignment; + break; case LoopHintAttr::Unroll: case LoopHintAttr::UnrollCount: Category = Unroll; diff --git a/clang/test/AST/ast-print-pragmas.cpp b/clang/test/AST/ast-print-pragmas.cpp --- a/clang/test/AST/ast-print-pragmas.cpp +++ b/clang/test/AST/ast-print-pragmas.cpp @@ -8,37 +8,38 @@ int i = 0; #pragma clang loop vectorize_width(4) #pragma clang loop interleave_count(8) -// CHECK-NEXT: while (i < Length) +#pragma clang loop vectorize_assume_alignment(32) + // CHECK-NEXT: while (i < Length) while (i < Length) { List[i] = i * 2; i++; } -// CHECK: #pragma clang loop distribute(disable) -// CHECK-NEXT: #pragma clang loop vectorize(enable) -// CHECK-NEXT: #pragma clang loop interleave(disable) -// CHECK-NEXT: #pragma clang loop vectorize_predicate(disable) + // CHECK: #pragma clang loop distribute(disable) + // CHECK-NEXT: #pragma clang loop vectorize(enable) + // CHECK-NEXT: #pragma clang loop interleave(disable) + // CHECK-NEXT: #pragma clang loop vectorize_predicate(disable) #pragma clang loop distribute(disable) #pragma clang loop vectorize(enable) #pragma clang loop interleave(disable) #pragma clang loop vectorize_predicate(disable) -// CHECK-NEXT: while (i - 1 < Length) + // CHECK-NEXT: while (i - 1 < Length) while (i - 1 < Length) { List[i] = i * 2; i++; } -// CHECK: #pragma clang loop distribute(enable) -// CHECK-NEXT: #pragma clang loop vectorize(disable) -// CHECK-NEXT: #pragma clang loop interleave(enable) -// CHECK-NEXT: #pragma clang loop vectorize_predicate(enable) + // CHECK: #pragma clang loop distribute(enable) + // CHECK-NEXT: #pragma clang loop vectorize(disable) + // CHECK-NEXT: #pragma clang loop interleave(enable) + // CHECK-NEXT: #pragma clang loop vectorize_predicate(enable) #pragma clang loop distribute(enable) #pragma clang loop vectorize(disable) #pragma clang loop interleave(enable) #pragma clang loop vectorize_predicate(enable) -// CHECK-NEXT: while (i - 2 < Length) + // CHECK-NEXT: while (i - 2 < Length) while (i - 2 < Length) { List[i] = i * 2; i++; @@ -66,4 +67,3 @@ // MS-EXT-NEXT: int x = 3 __declspec(thread); int __declspec(thread) x = 3; #endif //MS_EXT - diff --git a/clang/test/CodeGenCXX/pragma-loop-aligned.cpp b/clang/test/CodeGenCXX/pragma-loop-aligned.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/pragma-loop-aligned.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s + +void test0(int *List, int Length) { +// CHECK-LABEL: @{{.*}}test0{{.*}}( +// CHECK: br label {{.*}}, !llvm.loop ![[LOOP0:.*]] + + #pragma clang loop vectorize(enable) + for (int i = 0; i < Length; i++) + List[i] = i * 2; +} + +void test1(int *List, int Length) { +// CHECK-LABEL: @{{.*}}test1{{.*}}( +// CHECK: br label {{.*}}, !llvm.loop ![[LOOP1:.*]] + + #pragma clang loop vectorize(enable) vectorize_assume_alignment(32) + for (int i = 0; i < Length; i++) + List[i] = i * 2; +} + +void test2(int *List, int Length) { +// CHECK-LABEL: @{{.*}}test2{{.*}}( +// CHECK: br label {{.*}}, !llvm.loop ![[LOOP2:.*]] + + #pragma clang loop vectorize_assume_alignment(32) + for (int i = 0; i < Length; i++) + List[i] = i * 2; +} + +// vectorize_predicate(enable) implies vectorize(enable) +void test3(int *List, int Length) { +// CHECK-LABEL: @{{.*}}test3{{.*}}( +// CHECK: br label {{.*}}, !llvm.loop ![[LOOP3:.*]] + + #pragma clang loop vectorize_assume_alignment(32) + for (int i = 0; i < Length; i++) + List[i] = i * 2; +} + +// Check that disabling vectorization means a vectorization width of 1, and +// also that vectorization_predicate isn't enabled. +void test4(int *List, int Length) { +// CHECK-LABEL: @{{.*}}test4{{.*}}( +// CHECK: br label {{.*}}, !llvm.loop ![[LOOP4:.*]] + + #pragma clang loop vectorize(disable) + for (int i = 0; i < Length; i++) + List[i] = i * 2; +} + +// Check that vectorize and aligned are disabled. +void test5(int *List, int Length) { +// CHECK-LABEL: @{{.*}}test5{{.*}}( +// CHECK: br label {{.*}}, !llvm.loop ![[LOOP5:.*]] + + #pragma clang loop vectorize(disable) vectorize_assume_alignment(32) + for (int i = 0; i < Length; i++) + List[i] = i * 2; +} + + +// CHECK: ![[LOOP0]] = distinct !{![[LOOP0]], !3} +// CHECK-NEXT: !3 = !{!"llvm.loop.vectorize.enable", i1 true} + +// CHECK-NEXT: ![[LOOP1]] = distinct !{![[LOOP1]], !5, !3} +// CHECK-NEXT: !5 = !{!"llvm.loop.vectorize_assume_alignment", i32 32} + +// CHECK-NEXT: ![[LOOP2]] = distinct !{![[LOOP2]], !7, !3} +// CHECK-NEXT: !7 = !{!"llvm.loop.vectorize_assume_alignment", i32 32} + +// CHECK-NEXT: ![[LOOP3]] = distinct !{![[LOOP3]], !5, !3} + +// CHECK-NEXT: ![[LOOP4]] = distinct !{![[LOOP4]], !10} +// CHECK-NEXT: !10 = !{!"llvm.loop.vectorize.width", i32 1} + +// CHECK-NEXT: ![[LOOP5]] = distinct !{![[LOOP5]], !10} diff --git a/clang/test/Parser/pragma-loop.cpp b/clang/test/Parser/pragma-loop.cpp --- a/clang/test/Parser/pragma-loop.cpp +++ b/clang/test/Parser/pragma-loop.cpp @@ -18,42 +18,36 @@ template void test_nontype_template_vectorize(int *List, int Length) { - /* expected-error {{invalid value '-1'; must be positive}} */ #pragma clang loop vectorize_width(V) - for (int i = 0; i < Length; i++) { + /* expected-error {{invalid value '-1'; must be positive}} */ #pragma clang loop vectorize_width(V) for (int i = 0; i < Length; i++) { List[i] = i; } - /* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop vectorize_width(V / 2) - for (int i = 0; i < Length; i++) { + /* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop vectorize_width(V / 2) for (int i = 0; i < Length; i++) { List[i] += i; } } template void test_nontype_template_interleave(int *List, int Length) { - /* expected-error {{invalid value '-1'; must be positive}} */ #pragma clang loop interleave_count(I) - for (int i = 0; i < Length; i++) { + /* expected-error {{invalid value '-1'; must be positive}} */ #pragma clang loop interleave_count(I) for (int i = 0; i < Length; i++) { List[i] = i; } - /* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop interleave_count(2 % I) - for (int i = 0; i < Length; i++) { + /* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop interleave_count(2 % I) for (int i = 0; i < Length; i++) { List[i] = i; } } template void test_nontype_template_char(int *List, int Length) { - /* expected-error {{invalid argument of type 'char'; expected an integer type}} */ #pragma clang loop vectorize_width(V) - for (int i = 0; i < Length; i++) { + /* expected-error {{invalid argument of type 'char'; expected an integer type}} */ #pragma clang loop vectorize_width(V) for (int i = 0; i < Length; i++) { List[i] = i; } } template void test_nontype_template_bool(int *List, int Length) { - /* expected-error {{invalid argument of type 'bool'; expected an integer type}} */ #pragma clang loop vectorize_width(V) - for (int i = 0; i < Length; i++) { + /* expected-error {{invalid argument of type 'bool'; expected an integer type}} */ #pragma clang loop vectorize_width(V) for (int i = 0; i < Length; i++) { List[i] = i; } } @@ -61,8 +55,8 @@ template void test_nontype_template_badarg(int *List, int Length) { /* expected-error {{use of undeclared identifier 'Vec'}} */ #pragma clang loop vectorize_width(Vec) interleave_count(I) - /* expected-error {{use of undeclared identifier 'Int'}} */ #pragma clang loop vectorize_width(V) interleave_count(Int) - for (int i = 0; i < Length; i++) { + /* expected-error {{use of undeclared identifier 'Int'}} */ #pragma clang loop + vectorize_width(V) interleave_count(Int) for (int i = 0; i < Length; i++) { List[i] = i; } } @@ -70,8 +64,7 @@ template void test_type_template_vectorize(int *List, int Length) { const T Value = -1; - /* expected-error {{invalid value '-1'; must be positive}} */ #pragma clang loop vectorize_width(Value) - for (int i = 0; i < Length; i++) { + /* expected-error {{invalid value '-1'; must be positive}} */ #pragma clang loop vectorize_width(Value) for (int i = 0; i < Length; i++) { List[i] = i; } } @@ -90,6 +83,7 @@ #pragma clang loop vectorize_width(4) #pragma clang loop interleave_count(8) #pragma clang loop unroll_count(16) +#pragma clang loop vectorize_assume_alignment(32) while (i < Length) { List[i] = i; } @@ -102,7 +96,7 @@ List[i] = i; } -#pragma clang loop vectorize_width(4) interleave_count(8) unroll_count(16) +#pragma clang loop vectorize_width(4) interleave_count(8) unroll_count(16) vectorize_assume_alignment(32) while (i - 2 < Length) { List[i] = i; } @@ -113,7 +107,7 @@ } int VList[Length]; -#pragma clang loop vectorize(disable) interleave(disable) unroll(disable) vectorize_predicate(disable) +#pragma clang loop vectorize(disable) interleave(disable) unroll(disable) vectorize_predicate(disable) aligned(disable) for (int j : VList) { VList[j] = List[j]; } @@ -145,13 +139,15 @@ /* expected-error {{expected ')'}} */ #pragma clang loop vectorize_width(4 /* expected-error {{expected ')'}} */ #pragma clang loop interleave_count(4 /* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4 +/* expected-error {{expected ')'}} */ #pragma clang loop vectorize_assume_alignment(32 /* expected-error {{missing argument; expected 'enable', 'assume_safety' or 'disable'}} */ #pragma clang loop vectorize() /* expected-error {{missing argument; expected an integer value}} */ #pragma clang loop interleave_count() +/* expected-error {{missing argument; expected an integer value}} */ #pragma clang loop vectorize_assume_alignment() /* expected-error {{missing argument; expected 'enable', 'full' or 'disable'}} */ #pragma clang loop unroll() /* expected-error {{missing argument; expected 'enable' or 'disable'}} */ #pragma clang loop distribute() -/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, vectorize_predicate, or distribute}} */ #pragma clang loop +/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, vectorize_predicate, aligned, or distribute}} */ #pragma clang loop /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword(enable) /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop vectorize(enable) badkeyword(4) @@ -161,6 +157,7 @@ } /* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop vectorize_width(0) +/* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop vectorize_assume_alignment(0) /* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop interleave_count(0) /* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop unroll_count(0) @@ -181,6 +178,7 @@ /* expected-error {{value '3000000000' is too large}} */ #pragma clang loop vectorize_width(3000000000) /* expected-error {{value '3000000000' is too large}} */ #pragma clang loop interleave_count(3000000000) +/* expected-error {{value '3000000000' is too large}} */ #pragma clang loop vectorize_assume_alignment(3000000000) /* expected-error {{value '3000000000' is too large}} */ #pragma clang loop unroll_count(3000000000) while (i-6 < Length) { List[i] = i; @@ -216,6 +214,7 @@ /* expected-error {{invalid argument; expected 'enable', 'full' or 'disable'}} */ #pragma clang loop unroll(=) /* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop distribute(+) /* expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}} */ #pragma clang loop vectorize_width(^) +/* expected-error {{expected expression}} expected-error {{expected expression}} */ #pragma clang loop vectorize_assume_alignment(/) /* expected-error {{expected expression}} expected-error {{expected expression}} */ #pragma clang loop interleave_count(/) /* expected-error {{expected expression}} expected-error {{expected expression}} */ #pragma clang loop unroll_count(==) while (i-8 < Length) { @@ -272,6 +271,8 @@ #pragma clang loop vectorize_width(8) /* expected-error {{duplicate directives 'vectorize_width(8)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize_width(4) +#pragma clang loop vectorize_assume_alignment(32) +/* expected-error {{duplicate directives 'vectorize_width(8)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize_assume_alignment(4) #pragma clang loop interleave_count(8) /* expected-error {{duplicate directives 'interleave_count(8)' and 'interleave_count(4)'}} */ #pragma clang loop interleave_count(4) #pragma clang loop unroll_count(8) diff --git a/clang/test/Parser/pragma-unroll-and-jam.cpp b/clang/test/Parser/pragma-unroll-and-jam.cpp --- a/clang/test/Parser/pragma-unroll-and-jam.cpp +++ b/clang/test/Parser/pragma-unroll-and-jam.cpp @@ -67,7 +67,7 @@ } // pragma clang unroll_and_jam is disabled for the moment -/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, vectorize_predicate, or distribute}} */ #pragma clang loop unroll_and_jam(4) +/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, vectorize_predicate, vectorize_assume_alignment, or distribute}} */ #pragma clang loop unroll_and_jam(4) for (int i = 0; i < Length; i++) { for (int j = 0; j < Length; j++) { List[i * Length + j] = Value;