m-happy updated this revision to Diff 229190.
m-happy added a comment.

Updated the syntax as suggested by Michael Kruse, and added functionality to 
specify the number used for alignment instead of just using 32bits.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69897/new/

https://reviews.llvm.org/D69897

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/CodeGen/CGLoopInfo.cpp
  clang/lib/CodeGen/CGLoopInfo.h
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaStmtAttr.cpp
  clang/test/AST/ast-print-pragmas.cpp
  clang/test/CodeGenCXX/pragma-loop-aligned.cpp
  clang/test/Parser/pragma-loop.cpp
  clang/test/Parser/pragma-unroll-and-jam.cpp

Index: clang/test/Parser/pragma-unroll-and-jam.cpp
===================================================================
--- clang/test/Parser/pragma-unroll-and-jam.cpp
+++ 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;
Index: clang/test/Parser/pragma-loop.cpp
===================================================================
--- clang/test/Parser/pragma-loop.cpp
+++ clang/test/Parser/pragma-loop.cpp
@@ -18,42 +18,36 @@
 
 template <int V>
 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 <int I>
 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 <char V>
 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 <bool V>
 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 <int V, int I>
 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 <typename T>
 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)
Index: clang/test/CodeGenCXX/pragma-loop-aligned.cpp
===================================================================
--- /dev/null
+++ 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}
Index: clang/test/AST/ast-print-pragmas.cpp
===================================================================
--- clang/test/AST/ast-print-pragmas.cpp
+++ 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
-
Index: clang/lib/Sema/SemaStmtAttr.cpp
===================================================================
--- clang/lib/Sema/SemaStmtAttr.cpp
+++ 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<LoopHintAttr>(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;
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ 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)
Index: clang/lib/CodeGen/CGLoopInfo.h
===================================================================
--- clang/lib/CodeGen/CGLoopInfo.h
+++ 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; }
 
Index: clang/lib/CodeGen/CGLoopInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGLoopInfo.cpp
+++ 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<Metadata *, 1> 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;
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ 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">;
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ 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
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ 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.");
   }
Index: clang/docs/LanguageExtensions.rst
===================================================================
--- clang/docs/LanguageExtensions.rst
+++ 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
 --------------
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to