| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature | ||
| // REQUIRES: webassembly-registered-target | ||
|
|
||
| // Simple calls to known variadic functions that are completely elided when | ||
| // optimisations are on This is a functional check that the expand-variadic pass | ||
| // is consistent with clang's va_arg handling | ||
|
|
||
| // When expand-variadics is added to the default pipeline, clang -O1 will | ||
| // suffice here -Wno-varargs avoids warning second argument to 'va_start' is not | ||
| // the last named parameter | ||
|
|
||
| // RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -Wno-varargs -O1 -emit-llvm -o - | opt - -S --passes='module(expand-variadics,default<O1>)' --expand-variadics-override=optimize -o - | FileCheck %s | ||
|
|
||
| #include <stdarg.h> | ||
| #include <stdint.h> | ||
|
|
||
| template <typename X, typename Y> static X first(...) { | ||
| va_list va; | ||
| __builtin_va_start(va, 0); | ||
| X r = va_arg(va, X); | ||
| va_end(va); | ||
| return r; | ||
| } | ||
|
|
||
| template <typename X, typename Y> static Y second(...) { | ||
| va_list va; | ||
| __builtin_va_start(va, 0); | ||
| va_arg(va, X); | ||
| Y r = va_arg(va, Y); | ||
| va_end(va); | ||
| return r; | ||
| } | ||
|
|
||
| extern "C" { | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@first_pair_i32 | ||
| // CHECK-SAME: (i32 noundef returned [[X:%.*]], i32 noundef [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret i32 [[X]] | ||
| // | ||
| int first_pair_i32(int x, int y) { return first<int, int>(x, y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@second_pair_i32 | ||
| // CHECK-SAME: (i32 noundef [[X:%.*]], i32 noundef returned [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret i32 [[Y]] | ||
| // | ||
| int second_pair_i32(int x, int y) { return second<int, int>(x, y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@first_pair_f64 | ||
| // CHECK-SAME: (double noundef returned [[X:%.*]], double noundef [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret double [[X]] | ||
| // | ||
| double first_pair_f64(double x, double y) { | ||
| return first<double, double>(x, y); | ||
| } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@second_pair_f64 | ||
| // CHECK-SAME: (double noundef [[X:%.*]], double noundef returned [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret double [[Y]] | ||
| // | ||
| double second_pair_f64(double x, double y) { | ||
| return second<double, double>(x, y); | ||
| } | ||
| } | ||
|
|
||
| extern "C" { | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@first_i32_f64 | ||
| // CHECK-SAME: (i32 noundef returned [[X:%.*]], double noundef [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret i32 [[X]] | ||
| // | ||
| int first_i32_f64(int x, double y) { return first<int, double>(x, y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@second_i32_f64 | ||
| // CHECK-SAME: (i32 noundef [[X:%.*]], double noundef returned [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret double [[Y]] | ||
| // | ||
| double second_i32_f64(int x, double y) { return second<int, double>(x, y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@first_f64_i32 | ||
| // CHECK-SAME: (double noundef returned [[X:%.*]], i32 noundef [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret double [[X]] | ||
| // | ||
| double first_f64_i32(double x, int y) { return first<double, int>(x, y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@second_f64_i32 | ||
| // CHECK-SAME: (double noundef [[X:%.*]], i32 noundef returned [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret i32 [[Y]] | ||
| // | ||
| int second_f64_i32(double x, int y) { return second<double, int>(x, y); } | ||
| } | ||
|
|
||
| extern "C" { | ||
| typedef uint64_t ulong2 __attribute__((__vector_size__(16), __aligned__(16))); | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@first_i32_ulong2 | ||
| // CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret i32 [[X]] | ||
| // | ||
| int first_i32_ulong2(int x, ulong2 *y) { return first<int, ulong2>(x, *y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@second_i32_ulong2 | ||
| // CHECK-SAME: (i32 noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]], ptr nocapture noundef writeonly [[R:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[Y]], align 16, !tbaa [[TBAA2:![0-9]+]] | ||
| // CHECK-NEXT: store <2 x i64> [[TMP0]], ptr [[R]], align 16, !tbaa [[TBAA2]] | ||
| // CHECK-NEXT: ret void | ||
| // | ||
| void second_i32_ulong2(int x, ulong2 *y, ulong2 *r) { | ||
| *r = second<int, ulong2>(x, *y); | ||
| } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@first_ulong2_i32 | ||
| // CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef [[Y:%.*]], ptr nocapture noundef writeonly [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[X]], align 16, !tbaa [[TBAA2]] | ||
| // CHECK-NEXT: store <2 x i64> [[TMP0]], ptr [[R]], align 16, !tbaa [[TBAA2]] | ||
| // CHECK-NEXT: ret void | ||
| // | ||
| void first_ulong2_i32(ulong2 *x, int y, ulong2 *r) { | ||
| *r = first<ulong2, int>(*x, y); | ||
| } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@second_ulong2_i32 | ||
| // CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret i32 [[Y]] | ||
| // | ||
| int second_ulong2_i32(ulong2 *x, int y) { return second<ulong2, int>(*x, y); } | ||
| } | ||
|
|
||
| // ascending alignment | ||
| typedef struct { | ||
| char c; | ||
| short s; | ||
| int i; | ||
| long l; | ||
| float f; | ||
| double d; | ||
| } asc; | ||
|
|
||
| extern "C" { | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@first_i32_asc | ||
| // CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret i32 [[X]] | ||
| // | ||
| int first_i32_asc(int x, asc *y) { return first<int, asc>(x, *y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@second_i32_asc | ||
| // CHECK-SAME: (i32 noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]], ptr nocapture noundef writeonly [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(24) [[R]], ptr noundef nonnull align 1 dereferenceable(24) [[Y]], i32 24, i1 false) | ||
| // CHECK-NEXT: ret void | ||
| // | ||
| void second_i32_asc(int x, asc *y, asc *r) { *r = second<int, asc>(x, *y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@first_asc_i32 | ||
| // CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef [[Y:%.*]], ptr nocapture noundef writeonly [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(24) [[R]], ptr noundef nonnull align 1 dereferenceable(24) [[X]], i32 24, i1 false) | ||
| // CHECK-NEXT: ret void | ||
| // | ||
| void first_asc_i32(asc *x, int y, asc *r) { *r = first<asc, int>(*x, y); } | ||
|
|
||
| // CHECK-LABEL: define {{[^@]+}}@second_asc_i32 | ||
| // CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) | ||
| // CHECK-NEXT: entry: | ||
| // CHECK-NEXT: ret i32 [[Y]] | ||
| // | ||
| int second_asc_i32(asc *x, int y) { return second<asc, int>(*x, y); } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| // RUN: %clang -target aarch64 -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix %s | ||
| // RUN: %clang -target aarch64 -mlittle-endian -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix %s | ||
| // RUN: %clang -target aarch64_be -mlittle-endian -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix %s | ||
| // RUN: %clang -target aarch64 -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix-TUNE %s | ||
| // RUN: %clang -target aarch64 -mlittle-endian -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix-TUNE %s | ||
| // RUN: %clang -target aarch64_be -mlittle-endian -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix-TUNE %s | ||
| // Phoenix: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "oryon-1" "-target-feature" "+v8.6a" | ||
| // Phoenix-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" | ||
|
|
||
| // RUN: %clang -target arm64 -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-Phoenix %s | ||
| // RUN: %clang -target arm64 -mlittle-endian -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-Phoenix %s | ||
| // RUN: %clang -target arm64 -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-Phoenix-TUNE %s | ||
| // RUN: %clang -target arm64 -mlittle-endian -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-Phoenix-TUNE %s | ||
| // ARM64-Phoenix: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "oryon-1" "-target-feature" "+v8.6a" | ||
| // ARM64-Phoenix-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic" | ||
|
|
||
| // RUN: %clang -target aarch64 -mcpu=oryon-1 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-Phoenix %s | ||
| // RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-Phoenix %s | ||
| // MCPU-MTUNE-Phoenix: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "oryon-1" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| // REQUIRES: host-supports-jit | ||
| // UNSUPPORTED: system-aix | ||
| // RUN: cat %s | clang-repl -Xcc -xc | FileCheck %s | ||
| // RUN: cat %s | clang-repl -Xcc -std=c++11 | FileCheck %s | ||
|
|
||
| const char* c_str = "Hello, world!"; c_str | ||
|
|
||
| // CHECK: Not implement yet. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-linux -DSANITIZER_ENABLED -fsanitize=address -fsanitize-address-field-padding=1 %s | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-linux %s | ||
|
|
||
| struct S { | ||
| ~S() {} | ||
| virtual void foo() {} | ||
|
|
||
| int buffer[1]; | ||
| int other_field = 0; | ||
| }; | ||
|
|
||
| union U { | ||
| S s; | ||
| }; | ||
|
|
||
| struct Derived : S {}; | ||
|
|
||
| static_assert(!__is_trivially_copyable(S)); | ||
| #ifdef SANITIZER_ENABLED | ||
| // Don't allow memcpy when the struct has poisoned padding bits. | ||
| // The sanitizer adds posion padding bits to struct S. | ||
| static_assert(sizeof(S) > 16); | ||
| static_assert(!__is_bitwise_cloneable(S)); | ||
| static_assert(sizeof(U) == sizeof(S)); // no padding bit for U. | ||
| static_assert(!__is_bitwise_cloneable(U)); | ||
| static_assert(!__is_bitwise_cloneable(S[2])); | ||
| static_assert(!__is_bitwise_cloneable(Derived)); | ||
| #else | ||
| static_assert(sizeof(S) == 16); | ||
| static_assert(__is_bitwise_cloneable(S)); | ||
| static_assert(__is_bitwise_cloneable(U)); | ||
| static_assert(__is_bitwise_cloneable(S[2])); | ||
| static_assert(__is_bitwise_cloneable(Derived)); | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| // RUN: %clang_cc1 -fsyntax-only -verify %s | ||
| // | ||
| struct DynamicClass { virtual int Foo(); }; | ||
| static_assert(!__is_trivially_copyable(DynamicClass)); | ||
| static_assert(__is_bitwise_cloneable(DynamicClass)); | ||
|
|
||
| struct InComplete; // expected-note{{forward declaration}} | ||
| static_assert(!__is_bitwise_cloneable(InComplete)); // expected-error{{incomplete type 'InComplete' used in type trait expression}} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| // RUN: %clang_cc1 %s -fopenacc -verify | ||
|
|
||
| struct Incomplete; | ||
| enum SomeE{ A }; | ||
| typedef struct IsComplete { | ||
| struct S { int A; } CompositeMember; | ||
| int ScalarMember; | ||
| float ArrayMember[5]; | ||
| enum SomeE EnumMember; | ||
| void *PointerMember; | ||
| } Complete; | ||
|
|
||
| int GlobalInt; | ||
| float GlobalArray[5]; | ||
| short *GlobalPointer; | ||
| Complete GlobalComposite; | ||
|
|
||
| void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { | ||
| int LocalInt; | ||
| short *LocalPointer; | ||
| float LocalArray[5]; | ||
| Complete LocalComposite; | ||
|
|
||
| // Check Appertainment: | ||
| #pragma acc loop private(LocalInt) | ||
| for(;;); | ||
|
|
||
| // Valid cases: | ||
| #pragma acc loop private(LocalInt, LocalPointer, LocalArray) | ||
| for(;;); | ||
| #pragma acc loop private(LocalArray) | ||
| for(;;); | ||
| #pragma acc loop private(LocalArray[:]) | ||
| for(;;); | ||
| #pragma acc loop private(LocalArray[:5]) | ||
| for(;;); | ||
| #pragma acc loop private(LocalArray[2:]) | ||
| for(;;); | ||
| #pragma acc loop private(LocalArray[2:1]) | ||
| for(;;); | ||
| #pragma acc loop private(LocalArray[2]) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.EnumMember) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.ScalarMember) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.ArrayMember) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.ArrayMember[5]) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.PointerMember) | ||
| for(;;); | ||
| #pragma acc loop private(GlobalInt, GlobalArray, GlobalPointer, GlobalComposite) | ||
| for(;;); | ||
| #pragma acc loop private(GlobalArray[2], GlobalPointer[2], GlobalComposite.CompositeMember.A) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite, GlobalComposite) | ||
| for(;;); | ||
| #pragma acc loop private(IntParam, PointerParam, ArrayParam, CompositeParam) | ||
| for(;;); | ||
| #pragma acc loop private(PointerParam[IntParam], ArrayParam[IntParam], CompositeParam.CompositeMember.A) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(LocalArray) private(LocalArray[2]) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(LocalArray, LocalArray[2]) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(LocalComposite, LocalComposite.ScalarMember) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(LocalComposite.CompositeMember.A, LocalComposite.ScalarMember) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(LocalComposite.CompositeMember.A) private(LocalComposite.ScalarMember) | ||
| for(;;); | ||
|
|
||
| Complete LocalComposite2; | ||
| #pragma acc loop private(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) | ||
| for(;;); | ||
|
|
||
| // Invalid cases, arbitrary expressions. | ||
| struct Incomplete *I; | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(*I) | ||
| for(;;); | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(GlobalInt + IntParam) | ||
| for(;;); | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(+GlobalInt) | ||
| for(;;); | ||
|
|
||
| // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} | ||
| #pragma acc loop private(PointerParam[:]) | ||
| for(;;); | ||
| #pragma acc loop private(PointerParam[:5]) | ||
| for(;;); | ||
| #pragma acc loop private(PointerParam[:IntParam]) | ||
| for(;;); | ||
| // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} | ||
| #pragma acc loop private(PointerParam[2:]) | ||
| for(;;); | ||
| #pragma acc loop private(PointerParam[2:5]) | ||
| for(;;); | ||
| #pragma acc loop private(PointerParam[2]) | ||
| for(;;); | ||
| #pragma acc loop private(ArrayParam[:]) | ||
| for(;;); | ||
| #pragma acc loop private(ArrayParam[:5]) | ||
| for(;;); | ||
| #pragma acc loop private(ArrayParam[:IntParam]) | ||
| for(;;); | ||
| #pragma acc loop private(ArrayParam[2:]) | ||
| for(;;); | ||
| // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} | ||
| #pragma acc loop private(ArrayParam[2:5]) | ||
| for(;;); | ||
| #pragma acc loop private(ArrayParam[2]) | ||
| for(;;); | ||
|
|
||
| // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private((float*)ArrayParam[2:5]) | ||
| for(;;); | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private((float)ArrayParam[2]) | ||
| for(;;); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| // RUN: %clang_cc1 %s -fopenacc -verify | ||
|
|
||
| struct Incomplete; | ||
| enum SomeE{}; | ||
| typedef struct IsComplete { | ||
| struct S { int A; } CompositeMember; | ||
| int ScalarMember; | ||
| float ArrayMember[5]; | ||
| SomeE EnumMember; | ||
| char *PointerMember; | ||
| } Complete; | ||
|
|
||
| int GlobalInt; | ||
| float GlobalArray[5]; | ||
| char *GlobalPointer; | ||
| Complete GlobalComposite; | ||
|
|
||
| void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) { | ||
| int LocalInt; | ||
| char *LocalPointer; | ||
| float LocalArray[5]; | ||
| Complete LocalComposite; | ||
|
|
||
| // Check Appertainment: | ||
|
|
||
| #pragma acc loop private(LocalInt) | ||
| for(;;); | ||
|
|
||
| // Valid cases: | ||
| #pragma acc loop private(LocalInt, LocalPointer, LocalArray) | ||
| for(;;); | ||
| #pragma acc loop private(LocalArray) | ||
| for(;;); | ||
| #pragma acc loop private(LocalArray[2]) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.EnumMember) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.ScalarMember) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.ArrayMember) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.ArrayMember[5]) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite.PointerMember) | ||
| for(;;); | ||
| #pragma acc loop private(GlobalInt, GlobalArray, GlobalPointer, GlobalComposite) | ||
| for(;;); | ||
| #pragma acc loop private(GlobalArray[2], GlobalPointer[2], GlobalComposite.CompositeMember.A) | ||
| for(;;); | ||
| #pragma acc loop private(LocalComposite, GlobalComposite) | ||
| for(;;); | ||
| #pragma acc loop private(IntParam, PointerParam, ArrayParam, CompositeParam) private(IntParamRef) | ||
| for(;;); | ||
| #pragma acc loop private(PointerParam[IntParam], ArrayParam[IntParam], CompositeParam.CompositeMember.A) | ||
| for(;;); | ||
|
|
||
|
|
||
| // Invalid cases, arbitrary expressions. | ||
| Incomplete *I; | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(*I) | ||
| for(;;); | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(GlobalInt + IntParam) | ||
| for(;;); | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(+GlobalInt) | ||
| for(;;); | ||
| } | ||
|
|
||
| template<typename T, unsigned I, typename V> | ||
| void TemplUses(T t, T (&arrayT)[I], V TemplComp) { | ||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(+t) | ||
| for(;;); | ||
|
|
||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(+I) | ||
| for(;;); | ||
|
|
||
| // NTTP's are only valid if it is a reference to something. | ||
| // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| // expected-note@#TEMPL_USES_INST{{in instantiation of}} | ||
| #pragma acc loop private(I) | ||
| for(;;); | ||
|
|
||
| // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| #pragma acc loop private(t, I) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(arrayT) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(TemplComp) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(TemplComp.PointerMember[5]) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(TemplComp.PointerMember[5]) private(TemplComp) | ||
| for(;;); | ||
|
|
||
| int *Pointer; | ||
| #pragma acc loop private(Pointer[:I]) | ||
| for(;;); | ||
| #pragma acc loop private(Pointer[:t]) | ||
| for(;;); | ||
| // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} | ||
| #pragma acc loop private(Pointer[1:]) | ||
| for(;;); | ||
| } | ||
|
|
||
| template<unsigned I, auto &NTTP_REF> | ||
| void NTTP() { | ||
| // NTTP's are only valid if it is a reference to something. | ||
| // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} | ||
| // expected-note@#NTTP_INST{{in instantiation of}} | ||
| #pragma acc loop private(I) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(NTTP_REF) | ||
| for(;;); | ||
| } | ||
|
|
||
| struct S { | ||
| int ThisMember; | ||
| int ThisMemberArray[5]; | ||
|
|
||
| void foo(); | ||
| }; | ||
|
|
||
| void S::foo() { | ||
| #pragma acc loop private(ThisMember, this->ThisMemberArray[1]) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(ThisMemberArray[1:2]) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(this) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop private(ThisMember, this->ThisMember) | ||
| for(;;); | ||
| } | ||
|
|
||
| void Inst() { | ||
| static constexpr int NTTP_REFed = 1; | ||
| int i; | ||
| int Arr[5]; | ||
| Complete C; | ||
| TemplUses(i, Arr, C); // #TEMPL_USES_INST | ||
| NTTP<5, NTTP_REFed>(); // #NTTP_INST | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // Test the reduction semantics of fir.do_loop | ||
| // RUN: fir-opt %s | FileCheck %s | ||
|
|
||
| func.func @reduction() { | ||
| %bound = arith.constant 10 : index | ||
| %step = arith.constant 1 : index | ||
| %sum = fir.alloca i32 | ||
| // CHECK: %[[VAL_0:.*]] = fir.alloca i32 | ||
| // CHECK: fir.do_loop %[[VAL_1:.*]] = %[[VAL_2:.*]] to %[[VAL_3:.*]] step %[[VAL_4:.*]] unordered reduce(#fir.reduce_attr<add> -> %[[VAL_0]] : !fir.ref<i32>) { | ||
| fir.do_loop %iv = %step to %bound step %step unordered reduce(#fir.reduce_attr<add> -> %sum : !fir.ref<i32>) { | ||
| %index = fir.convert %iv : (index) -> i32 | ||
| %1 = fir.load %sum : !fir.ref<i32> | ||
| %2 = arith.addi %index, %1 : i32 | ||
| fir.store %2 to %sum : !fir.ref<i32> | ||
| } | ||
| return | ||
| } |