Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
      2 
      3 // Verify while loop is recognized after sequence of pragma clang loop directives.
      4 void while_test(int *List, int Length) {
      5   // CHECK: define {{.*}} @_Z10while_test
      6   int i = 0;
      7 
      8 #pragma clang loop vectorize(enable)
      9 #pragma clang loop interleave_count(4)
     10 #pragma clang loop vectorize_width(4)
     11 #pragma clang loop unroll(enable)
     12   while (i < Length) {
     13     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
     14     List[i] = i * 2;
     15     i++;
     16   }
     17 }
     18 
     19 // Verify do loop is recognized after multi-option pragma clang loop directive.
     20 void do_test(int *List, int Length) {
     21   int i = 0;
     22 
     23 #pragma clang loop vectorize_width(8) interleave_count(4) unroll(disable)
     24   do {
     25     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
     26     List[i] = i * 2;
     27     i++;
     28   } while (i < Length);
     29 }
     30 
     31 // Verify for loop is recognized after sequence of pragma clang loop directives.
     32 void for_test(int *List, int Length) {
     33 #pragma clang loop interleave(enable)
     34 #pragma clang loop interleave_count(4)
     35 #pragma clang loop unroll_count(8)
     36   for (int i = 0; i < Length; i++) {
     37     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
     38     List[i] = i * 2;
     39   }
     40 }
     41 
     42 // Verify c++11 for range loop is recognized after
     43 // sequence of pragma clang loop directives.
     44 void for_range_test() {
     45   double List[100];
     46 
     47 #pragma clang loop vectorize_width(2) interleave_count(2)
     48   for (int i : List) {
     49     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
     50     List[i] = i;
     51   }
     52 }
     53 
     54 // Verify disable pragma clang loop directive generates correct metadata
     55 void disable_test(int *List, int Length) {
     56 #pragma clang loop vectorize(disable) unroll(disable)
     57   for (int i = 0; i < Length; i++) {
     58     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
     59     List[i] = i * 2;
     60   }
     61 }
     62 
     63 #define VECWIDTH 2
     64 #define INTCOUNT 2
     65 #define UNROLLCOUNT 8
     66 
     67 // Verify defines are correctly resolved in pragma clang loop directive
     68 void for_define_test(int *List, int Length, int Value) {
     69 #pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
     70 #pragma clang loop unroll_count(UNROLLCOUNT)
     71   for (int i = 0; i < Length; i++) {
     72     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
     73     List[i] = i * Value;
     74   }
     75 }
     76 
     77 // Verify metadata is generated when template is used.
     78 template <typename A>
     79 void for_template_test(A *List, int Length, A Value) {
     80 
     81 #pragma clang loop vectorize_width(8) interleave_count(8) unroll_count(8)
     82   for (int i = 0; i < Length; i++) {
     83     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
     84     List[i] = i * Value;
     85   }
     86 }
     87 
     88 // Verify define is resolved correctly when template is used.
     89 template <typename A>
     90 void for_template_define_test(A *List, int Length, A Value) {
     91 #pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
     92 #pragma clang loop unroll_count(UNROLLCOUNT)
     93   for (int i = 0; i < Length; i++) {
     94     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_8:.*]]
     95     List[i] = i * Value;
     96   }
     97 }
     98 
     99 #undef VECWIDTH
    100 #undef INTCOUNT
    101 #undef UNROLLCOUNT
    102 
    103 // Use templates defined above. Test verifies metadata is generated correctly.
    104 void template_test(double *List, int Length) {
    105   double Value = 10;
    106 
    107   for_template_test<double>(List, Length, Value);
    108   for_template_define_test<double>(List, Length, Value);
    109 }
    110 
    111 // CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLLENABLE_1:.*]], metadata ![[WIDTH_4:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[INTENABLE_1:.*]]}
    112 // CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 true}
    113 // CHECK: ![[WIDTH_4]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 4}
    114 // CHECK: ![[INTERLEAVE_4]] = metadata !{metadata !"llvm.loop.vectorize.unroll", i32 4}
    115 // CHECK: ![[INTENABLE_1]] = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
    116 // CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[WIDTH_8:.*]]}
    117 // CHECK: ![[UNROLLENABLE_0]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 false}
    118 // CHECK: ![[WIDTH_8]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 8}
    119 // CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[ENABLE_1:.*]]}
    120 // CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loop.unroll.count", i32 8}
    121 // CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
    122 // CHECK: ![[INTERLEAVE_2]] = metadata !{metadata !"llvm.loop.vectorize.unroll", i32 2}
    123 // CHECK: ![[WIDTH_2]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 2}
    124 // CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[WIDTH_1:.*]]}
    125 // CHECK: ![[WIDTH_1]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
    126 // CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
    127 // CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_8:.*]], metadata ![[WIDTH_8:.*]]}
    128 // CHECK: ![[INTERLEAVE_8]] = metadata !{metadata !"llvm.loop.vectorize.unroll", i32 8}
    129 // CHECK: ![[LOOP_8]] = metadata !{metadata ![[LOOP_8]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
    130