blob: 283f5883c907dd20d5c5018b4c9b26f311422f92 [file] [log] [blame] [edit]
// Check no warnings/errors
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -std=c++20 -fopenmp-version=60 -fsyntax-only -verify %s
// expected-no-diagnostics
// Check AST and unparsing
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -std=c++20 -fopenmp-version=60 -ast-dump %s | FileCheck %s --check-prefix=DUMP
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -std=c++20 -fopenmp-version=60 -ast-print %s | FileCheck %s --check-prefix=PRINT
// Check same results after serialization round-trip
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -std=c++20 -fopenmp-version=60 -emit-pch -o %t %s
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -std=c++20 -fopenmp-version=60 -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -std=c++20 -fopenmp-version=60 -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT
#ifndef HEADER
#define HEADER
// placeholder for loop body code
extern "C" void body(...);
// PRINT-LABEL: void foo1(
// DUMP-LABEL: FunctionDecl {{.*}} foo1
void foo1() {
// PRINT: #pragma omp fuse
// DUMP: OMPFuseDirective
#pragma omp fuse
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (int i = 0; i < 10; i += 2)
// DUMP: ForStmt
for (int i = 0; i < 10; i += 2)
// PRINT: body(i)
// DUMP: CallExpr
body(i);
// PRINT: for (int j = 10; j > 0; --j)
// DUMP: ForStmt
for (int j = 10; j > 0; --j)
// PRINT: body(j)
// DUMP: CallExpr
body(j);
// PRINT: for (int k = 0; k <= 10; ++k)
// DUMP: ForStmt
for (int k = 0; k <= 10; ++k)
// PRINT: body(k)
// DUMP: CallExpr
body(k);
}
}
// PRINT-LABEL: void foo2(
// DUMP-LABEL: FunctionDecl {{.*}} foo2
void foo2() {
// PRINT: #pragma omp unroll partial(4)
// DUMP: OMPUnrollDirective
// DUMP-NEXT: OMPPartialClause
// DUMP-NEXT: ConstantExpr
// DUMP-NEXT: value: Int 4
// DUMP-NEXT: IntegerLiteral {{.*}} 4
#pragma omp unroll partial(4)
// PRINT: #pragma omp fuse
// DUMP-NEXT: OMPFuseDirective
#pragma omp fuse
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (int i = 0; i < 10; i += 2)
// DUMP: ForStmt
for (int i = 0; i < 10; i += 2)
// PRINT: body(i)
// DUMP: CallExpr
body(i);
// PRINT: for (int j = 10; j > 0; --j)
// DUMP: ForStmt
for (int j = 10; j > 0; --j)
// PRINT: body(j)
// DUMP: CallExpr
body(j);
}
}
//PRINT-LABEL: void foo3(
//DUMP-LABEL: FunctionTemplateDecl {{.*}} foo3
template<int Factor1, int Factor2>
void foo3() {
// PRINT: #pragma omp fuse
// DUMP: OMPFuseDirective
#pragma omp fuse
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: #pragma omp unroll partial(Factor1)
// DUMP: OMPUnrollDirective
#pragma omp unroll partial(Factor1)
// PRINT: for (int i = 0; i < 12; i += 1)
// DUMP: ForStmt
for (int i = 0; i < 12; i += 1)
// PRINT: body(i)
// DUMP: CallExpr
body(i);
// PRINT: #pragma omp unroll partial(Factor2)
// DUMP: OMPUnrollDirective
#pragma omp unroll partial(Factor2)
// PRINT: for (int k = 0; k <= 10; ++k)
// DUMP: ForStmt
for (int k = 0; k <= 10; ++k)
// PRINT: body(k)
// DUMP: CallExpr
body(k);
}
}
// Also test instantiating the template.
void tfoo3() {
foo3<4,2>();
}
//PRINT-LABEL: void foo4(
//DUMP-LABEL: FunctionTemplateDecl {{.*}} foo4
template<typename T, T Step>
void foo4(int start, int end) {
// PRINT: #pragma omp fuse
// DUMP: OMPFuseDirective
#pragma omp fuse
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (T i = start; i < end; i += Step)
// DUMP: ForStmt
for (T i = start; i < end; i += Step)
// PRINT: body(i)
// DUMP: CallExpr
body(i);
// PRINT: for (T j = end; j > start; j -= Step)
// DUMP: ForStmt
for (T j = end; j > start; j -= Step) {
// PRINT: body(j)
// DUMP: CallExpr
body(j);
}
}
}
// Also test instantiating the template.
void tfoo4() {
foo4<int, 4>(0, 64);
}
// PRINT-LABEL: void foo5(
// DUMP-LABEL: FunctionDecl {{.*}} foo5
void foo5() {
double arr[128], arr2[128];
// PRINT: #pragma omp fuse
// DUMP: OMPFuseDirective
#pragma omp fuse
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT-NEXT: for (auto &&a : arr)
// DUMP-NEXT: CXXForRangeStmt
for (auto &&a: arr)
// PRINT: body(a)
// DUMP: CallExpr
body(a);
// PRINT: for (double v = 42; auto &&b : arr)
// DUMP: CXXForRangeStmt
for (double v = 42; auto &&b: arr)
// PRINT: body(b, v);
// DUMP: CallExpr
body(b, v);
// PRINT: for (auto &&c : arr2)
// DUMP: CXXForRangeStmt
for (auto &&c: arr2)
// PRINT: body(c)
// DUMP: CallExpr
body(c);
}
}
// PRINT-LABEL: void foo6(
// DUMP-LABEL: FunctionDecl {{.*}} foo6
void foo6() {
// PRINT: #pragma omp fuse
// DUMP: OMPFuseDirective
#pragma omp fuse
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: #pragma omp fuse
// DUMP: OMPFuseDirective
#pragma omp fuse
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (int i = 0; i <= 10; ++i)
// DUMP: ForStmt
for (int i = 0; i <= 10; ++i)
body(i);
// PRINT: for (int j = 0; j < 100; ++j)
// DUMP: ForStmt
for(int j = 0; j < 100; ++j)
body(j);
}
// PRINT: #pragma omp unroll partial(4)
// DUMP: OMPUnrollDirective
#pragma omp unroll partial(4)
// PRINT: for (int k = 0; k < 250; ++k)
// DUMP: ForStmt
for (int k = 0; k < 250; ++k)
body(k);
}
}
// PRINT-LABEL: void foo7(
// DUMP-LABEL: FunctionDecl {{.*}} foo7
void foo7() {
// PRINT: #pragma omp fuse
// DUMP: OMPFuseDirective
#pragma omp fuse
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (int i = 0; i < 10; i += 2)
// DUMP: ForStmt
for (int i = 0; i < 10; i += 2)
// PRINT: body(i)
// DUMP: CallExpr
body(i);
// PRINT: for (int j = 10; j > 0; --j)
// DUMP: ForStmt
for (int j = 10; j > 0; --j)
// PRINT: body(j)
// DUMP: CallExpr
body(j);
}
}
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (int k = 0; k <= 10; ++k)
// DUMP: ForStmt
for (int k = 0; k <= 10; ++k)
// PRINT: body(k)
// DUMP: CallExpr
body(k);
}
}
}
}
}
// PRINT-LABEL: void foo8(
// DUMP-LABEL: FunctionDecl {{.*}} foo8
void foo8() {
// PRINT: #pragma omp fuse looprange(2,2)
// DUMP: OMPFuseDirective
// DUMP: OMPLooprangeClause
#pragma omp fuse looprange(2,2)
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (int i = 0; i < 10; i += 2)
// DUMP: ForStmt
for (int i = 0; i < 10; i += 2)
// PRINT: body(i)
// DUMP: CallExpr
body(i);
// PRINT: for (int j = 10; j > 0; --j)
// DUMP: ForStmt
for (int j = 10; j > 0; --j)
// PRINT: body(j)
// DUMP: CallExpr
body(j);
// PRINT: for (int k = 0; k <= 10; ++k)
// DUMP: ForStmt
for (int k = 0; k <= 10; ++k)
// PRINT: body(k)
// DUMP: CallExpr
body(k);
}
}
//PRINT-LABEL: void foo9(
//DUMP-LABEL: FunctionTemplateDecl {{.*}} foo9
//DUMP-LABEL: NonTypeTemplateParmDecl {{.*}} F
//DUMP-LABEL: NonTypeTemplateParmDecl {{.*}} C
template<int F, int C>
void foo9() {
// PRINT: #pragma omp fuse looprange(F,C)
// DUMP: OMPFuseDirective
// DUMP: OMPLooprangeClause
#pragma omp fuse looprange(F,C)
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (int i = 0; i < 10; i += 2)
// DUMP: ForStmt
for (int i = 0; i < 10; i += 2)
// PRINT: body(i)
// DUMP: CallExpr
body(i);
// PRINT: for (int j = 10; j > 0; --j)
// DUMP: ForStmt
for (int j = 10; j > 0; --j)
// PRINT: body(j)
// DUMP: CallExpr
body(j);
}
}
// Also test instantiating the template.
void tfoo9() {
foo9<1, 2>();
}
// PRINT-LABEL: void foo10(
// DUMP-LABEL: FunctionDecl {{.*}} foo10
void foo10() {
// PRINT: #pragma omp fuse looprange(2,2)
// DUMP: OMPFuseDirective
// DUMP: OMPLooprangeClause
#pragma omp fuse looprange(2,2)
// PRINT: {
// DUMP: CompoundStmt
{
// PRINT: for (int i = 0; i < 10; i += 2)
// DUMP: ForStmt
for (int i = 0; i < 10; i += 2)
// PRINT: body(i)
// DUMP: CallExpr
body(i);
// PRINT: for (int ii = 0; ii < 10; ii += 2)
// DUMP: ForStmt
for (int ii = 0; ii < 10; ii += 2)
// PRINT: body(ii)
// DUMP: CallExpr
body(ii);
// PRINT: #pragma omp fuse looprange(2,2)
// DUMP: OMPFuseDirective
// DUMP: OMPLooprangeClause
#pragma omp fuse looprange(2,2)
{
// PRINT: for (int j = 10; j > 0; --j)
// DUMP: ForStmt
for (int j = 10; j > 0; --j)
// PRINT: body(j)
// DUMP: CallExpr
body(j);
// PRINT: for (int jj = 10; jj > 0; --jj)
// DUMP: ForStmt
for (int jj = 10; jj > 0; --jj)
// PRINT: body(jj)
// DUMP: CallExpr
body(jj);
// PRINT: for (int k = 0; k <= 10; ++k)
// DUMP: ForStmt
for (int k = 0; k <= 10; ++k)
// PRINT: body(k)
// DUMP: CallExpr
body(k);
// PRINT: for (int kk = 0; kk <= 10; ++kk)
// DUMP: ForStmt
for (int kk = 0; kk <= 10; ++kk)
// PRINT: body(kk)
// DUMP: CallExpr
body(kk);
}
}
}
#endif