| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s | ||
| // RUN: %clang_cc1 -verify=ref,both %s | ||
|
|
||
|
|
||
| constexpr int dummy = 1; | ||
| constexpr const int *null = nullptr; | ||
|
|
||
| namespace simple { | ||
| __attribute__((nonnull)) | ||
| constexpr int simple1(const int*) { | ||
| return 1; | ||
| } | ||
| static_assert(simple1(&dummy) == 1, ""); | ||
| static_assert(simple1(nullptr) == 1, ""); // both-error {{not an integral constant expression}} \ | ||
| // both-note {{null passed to a callee}} | ||
| static_assert(simple1(null) == 1, ""); // both-error {{not an integral constant expression}} \ | ||
| // both-note {{null passed to a callee}} | ||
|
|
||
| __attribute__((nonnull)) // both-warning {{applied to function with no pointer arguments}} | ||
| constexpr int simple2(const int &a) { | ||
| return 12; | ||
| } | ||
| static_assert(simple2(1) == 12, ""); | ||
| } | ||
|
|
||
| namespace methods { | ||
| struct S { | ||
| __attribute__((nonnull(2))) // both-warning {{only applies to pointer arguments}} | ||
| __attribute__((nonnull(3))) | ||
| constexpr int foo(int a, const void *p) const { | ||
| return 12; | ||
| } | ||
|
|
||
| __attribute__((nonnull(3))) | ||
| constexpr int foo2(...) const { | ||
| return 12; | ||
| } | ||
|
|
||
| __attribute__((nonnull)) | ||
| constexpr int foo3(...) const { | ||
| return 12; | ||
| } | ||
| }; | ||
|
|
||
| constexpr S s{}; | ||
| static_assert(s.foo(8, &dummy) == 12, ""); | ||
|
|
||
| static_assert(s.foo2(nullptr) == 12, ""); | ||
| static_assert(s.foo2(1, nullptr) == 12, ""); // both-error {{not an integral constant expression}} \ | ||
| // both-note {{null passed to a callee}} | ||
|
|
||
| constexpr S *s2 = nullptr; | ||
| static_assert(s2->foo3() == 12, ""); // both-error {{not an integral constant expression}} \ | ||
| // both-note {{member call on dereferenced null pointer}} | ||
| } | ||
|
|
||
| namespace fnptrs { | ||
| __attribute__((nonnull)) | ||
| constexpr int add(int a, const void *p) { | ||
| return a + 1; | ||
| } | ||
| __attribute__((nonnull(3))) | ||
| constexpr int applyBinOp(int a, int b, int (*op)(int, const void *)) { | ||
| return op(a, nullptr); // both-note {{null passed to a callee}} | ||
| } | ||
| static_assert(applyBinOp(10, 20, add) == 11, ""); // both-error {{not an integral constant expression}} \ | ||
| // both-note {{in call to}} | ||
|
|
||
| static_assert(applyBinOp(10, 20, nullptr) == 11, ""); // both-error {{not an integral constant expression}} \ | ||
| // both-note {{null passed to a callee}} | ||
| } | ||
|
|
||
| namespace lambdas { | ||
| auto lstatic = [](const void *P) __attribute__((nonnull)) { return 3; }; | ||
| static_assert(lstatic(nullptr) == 3, ""); // both-error {{not an integral constant expression}} \ | ||
| // both-note {{null passed to a callee}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| // RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s | ||
|
|
||
| struct A { | ||
| static constexpr bool x = true; | ||
| }; | ||
|
|
||
| namespace N0 { | ||
|
|
||
| template<typename T, typename U> | ||
| void f(T, U) noexcept(T::y); // #1 | ||
|
|
||
| template<typename T, typename U> // #2 | ||
| void f(T, U*) noexcept(T::x); | ||
|
|
||
| // Deduction should succeed for both candidates, and #2 should be selected as the primary template. | ||
| // Only the exception specification of #2 should be instantiated. | ||
| template<> | ||
| void f(A, int*) noexcept; | ||
|
|
||
| } | ||
|
|
||
| namespace N1 { | ||
|
|
||
| template<typename T, typename U> | ||
| void f(T, U) noexcept(T::x); // #1 | ||
|
|
||
| template<typename T, typename U> | ||
| void f(T, U*) noexcept(T::y); // #2 | ||
| // expected-error@-1 {{no member named 'y' in 'A'}} | ||
|
|
||
| // Deduction should succeed for both candidates, and #2 should be selected as the primary template. | ||
| // Only the exception specification of #2 should be instantiated. | ||
| template<> | ||
| void f(A, int*) noexcept; // expected-error {{exception specification in declaration does not match previous declaration}} | ||
| // expected-note@-1 {{in instantiation of exception specification for 'f<A, int>' requested here}} | ||
| // expected-note@-2 {{previous declaration is here}} | ||
| } | ||
|
|
||
| namespace N2 { | ||
|
|
||
| template<typename T, typename U> | ||
| void f(T, U) noexcept(T::x); | ||
|
|
||
| template<typename T, typename U> | ||
| void f(T, U*) noexcept(T::x); | ||
|
|
||
| template<typename T, typename U> | ||
| void f(T, U**) noexcept(T::y); // expected-error {{no member named 'y' in 'A'}} | ||
|
|
||
| template<typename T, typename U> | ||
| void f(T, U***) noexcept(T::x); | ||
|
|
||
| template<> | ||
| void f(A, int*) noexcept; // expected-note {{previous declaration is here}} | ||
|
|
||
| template<> | ||
| void f(A, int*); // expected-error {{'f<A, int>' is missing exception specification 'noexcept'}} | ||
|
|
||
| template<> | ||
| void f(A, int**) noexcept; // expected-error {{exception specification in declaration does not match previous declaration}} | ||
| // expected-note@-1 {{in instantiation of exception specification for 'f<A, int>' requested here}} | ||
| // expected-note@-2 {{previous declaration is here}} | ||
|
|
||
| // FIXME: Exception specification is currently set to EST_None if instantiation fails. | ||
| template<> | ||
| void f(A, int**); | ||
|
|
||
| template<> | ||
| void f(A, int***) noexcept; // expected-note {{previous declaration is here}} | ||
|
|
||
| template<> | ||
| void f(A, int***); // expected-error {{'f<A, int>' is missing exception specification 'noexcept'}} | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| // This test verifies that command lines with equivalent -D and -U arguments | ||
| // are canonicalized to the same module variant. | ||
|
|
||
| // RUN: rm -rf %t | ||
| // RUN: split-file %s %t | ||
| // RUN: sed -e "s|DIR|%/t|g" %t/build/compile-commands.json.in > %t/build/compile-commands.json | ||
| // RUN: clang-scan-deps -compilation-database %t/build/compile-commands.json \ | ||
| // RUN: -j 1 -format experimental-full -optimize-args=canonicalize-macros > %t/deps.db | ||
| // RUN: cat %t/deps.db | FileCheck %s -DPREFIX=%/t | ||
|
|
||
| // Verify that there are only two variants and that the expected merges have | ||
| // happened. | ||
|
|
||
| // CHECK: { | ||
| // CHECK-NEXT: "modules": [ | ||
| // CHECK-NEXT: { | ||
| // CHECK-NEXT: "clang-module-deps": [], | ||
| // CHECK-NEXT: "clang-modulemap-file": | ||
| // CHECK-NEXT: "command-line": [ | ||
| // CHECK-NOT: "J=1" | ||
| // CHECK-NOT: "J" | ||
| // CHECK-NOT: "K" | ||
| // CHECK: ], | ||
| // CHECK-NEXT: "context-hash": "{{.*}}", | ||
| // CHECK-NEXT: "file-deps": [ | ||
| // CHECK: ], | ||
| // CHECK-NEXT: "name": "A" | ||
| // CHECK-NEXT: }, | ||
| // CHECK-NEXT: { | ||
| // CHECK-NEXT: "clang-module-deps": [], | ||
| // CHECK-NEXT: "clang-modulemap-file": | ||
| // CHECK-NEXT: "command-line": [ | ||
| // CHECK: "Fඞ" | ||
| // CHECK: 0D9E | ||
| // CHECK: "K" | ||
| // CHECK: "K" | ||
| // CHECK: ], | ||
| // CHECK-NEXT: "context-hash": "{{.*}}", | ||
| // CHECK-NEXT: "file-deps": [ | ||
| // CHECK: ], | ||
| // CHECK-NEXT: "name": "A" | ||
| // CHECK-NEXT: } | ||
| // CHECK-NEXT: ], | ||
| // CHECK-NEXT: "translation-units": [ | ||
| // CHECK: ] | ||
| // CHECK: } | ||
|
|
||
|
|
||
| //--- build/compile-commands.json.in | ||
|
|
||
| [ | ||
| { | ||
| "directory": "DIR", | ||
| "command": "clang -c DIR/tu0.m -DJ=1 -UJ -DJ=2 -DI -DK(x)=x -I modules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-module-maps", | ||
| "file": "DIR/tu0.m" | ||
| }, | ||
| { | ||
| "directory": "DIR", | ||
| "command": "clang -c DIR/tu1.m -DK -DK(x)=x -DI -D \"J=2\" -I modules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-module-maps", | ||
| "file": "DIR/tu1.m" | ||
| }, | ||
| { | ||
| "directory": "DIR", | ||
| "command": "clang -c DIR/tu2.m -I modules/A -DFඞ \"-DF\\\\u{0D9E}\" -DK -DK -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-module-maps", | ||
| "file": "DIR/tu2.m" | ||
| } | ||
| ] | ||
|
|
||
| //--- modules/A/module.modulemap | ||
|
|
||
| module A { | ||
| umbrella header "A.h" | ||
| } | ||
|
|
||
| //--- modules/A/A.h | ||
|
|
||
| //--- tu0.m | ||
|
|
||
| #include <A.h> | ||
|
|
||
| //--- tu1.m | ||
|
|
||
| #include <A.h> | ||
|
|
||
| //--- tu2.m | ||
|
|
||
| #include <A.h> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s | ||
|
|
||
| // CHECK-LABEL: builtin_bool_to_float_type_promotion | ||
| // CHECK: %conv1 = uitofp i1 %tobool to double | ||
| // CHECK: %dx.dot = fmul double %conv, %conv1 | ||
| // CHECK: %conv2 = fptrunc double %dx.dot to float | ||
| // CHECK: ret float %conv2 | ||
| float builtin_bool_to_float_type_promotion ( float p0, bool p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK-LABEL: builtin_bool_to_float_arg1_type_promotion | ||
| // CHECK: %conv = uitofp i1 %tobool to double | ||
| // CHECK: %conv1 = fpext float %1 to double | ||
| // CHECK: %dx.dot = fmul double %conv, %conv1 | ||
| // CHECK: %conv2 = fptrunc double %dx.dot to float | ||
| // CHECK: ret float %conv2 | ||
| float builtin_bool_to_float_arg1_type_promotion ( bool p0, float p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK-LABEL: builtin_dot_int_to_float_promotion | ||
| // CHECK: %conv = fpext float %0 to double | ||
| // CHECK: %conv1 = sitofp i32 %1 to double | ||
| // CHECK: dx.dot = fmul double %conv, %conv1 | ||
| // CHECK: %conv2 = fptrunc double %dx.dot to float | ||
| // CHECK: ret float %conv2 | ||
| float builtin_dot_int_to_float_promotion ( float p0, int p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,265 @@ | ||
| // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ | ||
| // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ | ||
| // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ | ||
| // RUN: --check-prefixes=CHECK,NATIVE_HALF | ||
| // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ | ||
| // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ | ||
| // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF | ||
|
|
||
| #ifdef __HLSL_ENABLE_16_BIT | ||
| // NATIVE_HALF: %dx.dot = mul i16 %0, %1 | ||
| // NATIVE_HALF: ret i16 %dx.dot | ||
| int16_t test_dot_short ( int16_t p0, int16_t p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v2i16(<2 x i16> %0, <2 x i16> %1) | ||
| // NATIVE_HALF: ret i16 %dx.dot | ||
| int16_t test_dot_short2 ( int16_t2 p0, int16_t2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v3i16(<3 x i16> %0, <3 x i16> %1) | ||
| // NATIVE_HALF: ret i16 %dx.dot | ||
| int16_t test_dot_short3 ( int16_t3 p0, int16_t3 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v4i16(<4 x i16> %0, <4 x i16> %1) | ||
| // NATIVE_HALF: ret i16 %dx.dot | ||
| int16_t test_dot_short4 ( int16_t4 p0, int16_t4 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = mul i16 %0, %1 | ||
| // NATIVE_HALF: ret i16 %dx.dot | ||
| uint16_t test_dot_ushort ( uint16_t p0, uint16_t p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v2i16(<2 x i16> %0, <2 x i16> %1) | ||
| // NATIVE_HALF: ret i16 %dx.dot | ||
| uint16_t test_dot_ushort2 ( uint16_t2 p0, uint16_t2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v3i16(<3 x i16> %0, <3 x i16> %1) | ||
| // NATIVE_HALF: ret i16 %dx.dot | ||
| uint16_t test_dot_ushort3 ( uint16_t3 p0, uint16_t3 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v4i16(<4 x i16> %0, <4 x i16> %1) | ||
| // NATIVE_HALF: ret i16 %dx.dot | ||
| uint16_t test_dot_ushort4 ( uint16_t4 p0, uint16_t4 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
| #endif | ||
|
|
||
| // CHECK: %dx.dot = mul i32 %0, %1 | ||
| // CHECK: ret i32 %dx.dot | ||
| int test_dot_int ( int p0, int p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i32 @llvm.dx.dot.v2i32(<2 x i32> %0, <2 x i32> %1) | ||
| // CHECK: ret i32 %dx.dot | ||
| int test_dot_int2 ( int2 p0, int2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i32 @llvm.dx.dot.v3i32(<3 x i32> %0, <3 x i32> %1) | ||
| // CHECK: ret i32 %dx.dot | ||
| int test_dot_int3 ( int3 p0, int3 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i32 @llvm.dx.dot.v4i32(<4 x i32> %0, <4 x i32> %1) | ||
| // CHECK: ret i32 %dx.dot | ||
| int test_dot_int4 ( int4 p0, int4 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = mul i32 %0, %1 | ||
| // CHECK: ret i32 %dx.dot | ||
| uint test_dot_uint ( uint p0, uint p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i32 @llvm.dx.dot.v2i32(<2 x i32> %0, <2 x i32> %1) | ||
| // CHECK: ret i32 %dx.dot | ||
| uint test_dot_uint2 ( uint2 p0, uint2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i32 @llvm.dx.dot.v3i32(<3 x i32> %0, <3 x i32> %1) | ||
| // CHECK: ret i32 %dx.dot | ||
| uint test_dot_uint3 ( uint3 p0, uint3 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i32 @llvm.dx.dot.v4i32(<4 x i32> %0, <4 x i32> %1) | ||
| // CHECK: ret i32 %dx.dot | ||
| uint test_dot_uint4 ( uint4 p0, uint4 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = mul i64 %0, %1 | ||
| // CHECK: ret i64 %dx.dot | ||
| int64_t test_dot_long ( int64_t p0, int64_t p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i64 @llvm.dx.dot.v2i64(<2 x i64> %0, <2 x i64> %1) | ||
| // CHECK: ret i64 %dx.dot | ||
| int64_t test_dot_long2 ( int64_t2 p0, int64_t2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i64 @llvm.dx.dot.v3i64(<3 x i64> %0, <3 x i64> %1) | ||
| // CHECK: ret i64 %dx.dot | ||
| int64_t test_dot_long3 ( int64_t3 p0, int64_t3 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i64 @llvm.dx.dot.v4i64(<4 x i64> %0, <4 x i64> %1) | ||
| // CHECK: ret i64 %dx.dot | ||
| int64_t test_dot_long4 ( int64_t4 p0, int64_t4 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = mul i64 %0, %1 | ||
| // CHECK: ret i64 %dx.dot | ||
| uint64_t test_dot_ulong ( uint64_t p0, uint64_t p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i64 @llvm.dx.dot.v2i64(<2 x i64> %0, <2 x i64> %1) | ||
| // CHECK: ret i64 %dx.dot | ||
| uint64_t test_dot_ulong2 ( uint64_t2 p0, uint64_t2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i64 @llvm.dx.dot.v3i64(<3 x i64> %0, <3 x i64> %1) | ||
| // CHECK: ret i64 %dx.dot | ||
| uint64_t test_dot_ulong3 ( uint64_t3 p0, uint64_t3 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call i64 @llvm.dx.dot.v4i64(<4 x i64> %0, <4 x i64> %1) | ||
| // CHECK: ret i64 %dx.dot | ||
| uint64_t test_dot_ulong4 ( uint64_t4 p0, uint64_t4 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = fmul half %0, %1 | ||
| // NATIVE_HALF: ret half %dx.dot | ||
| // NO_HALF: %dx.dot = fmul float %0, %1 | ||
| // NO_HALF: ret float %dx.dot | ||
| half test_dot_half ( half p0, half p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call half @llvm.dx.dot.v2f16(<2 x half> %0, <2 x half> %1) | ||
| // NATIVE_HALF: ret half %dx.dot | ||
| // NO_HALF: %dx.dot = call float @llvm.dx.dot.v2f32(<2 x float> %0, <2 x float> %1) | ||
| // NO_HALF: ret float %dx.dot | ||
| half test_dot_half2 ( half2 p0, half2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call half @llvm.dx.dot.v3f16(<3 x half> %0, <3 x half> %1) | ||
| // NATIVE_HALF: ret half %dx.dot | ||
| // NO_HALF: %dx.dot = call float @llvm.dx.dot.v3f32(<3 x float> %0, <3 x float> %1) | ||
| // NO_HALF: ret float %dx.dot | ||
| half test_dot_half3 ( half3 p0, half3 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // NATIVE_HALF: %dx.dot = call half @llvm.dx.dot.v4f16(<4 x half> %0, <4 x half> %1) | ||
| // NATIVE_HALF: ret half %dx.dot | ||
| // NO_HALF: %dx.dot = call float @llvm.dx.dot.v4f32(<4 x float> %0, <4 x float> %1) | ||
| // NO_HALF: ret float %dx.dot | ||
| half test_dot_half4 ( half4 p0, half4 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = fmul float %0, %1 | ||
| // CHECK: ret float %dx.dot | ||
| float test_dot_float ( float p0, float p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call float @llvm.dx.dot.v2f32(<2 x float> %0, <2 x float> %1) | ||
| // CHECK: ret float %dx.dot | ||
| float test_dot_float2 ( float2 p0, float2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call float @llvm.dx.dot.v3f32(<3 x float> %0, <3 x float> %1) | ||
| // CHECK: ret float %dx.dot | ||
| float test_dot_float3 ( float3 p0, float3 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call float @llvm.dx.dot.v4f32(<4 x float> %0, <4 x float> %1) | ||
| // CHECK: ret float %dx.dot | ||
| float test_dot_float4 ( float4 p0, float4 p1) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call float @llvm.dx.dot.v2f32(<2 x float> %splat.splat, <2 x float> %1) | ||
| // CHECK: ret float %dx.dot | ||
| float test_dot_float2_splat ( float p0, float2 p1 ) { | ||
| return dot( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call float @llvm.dx.dot.v3f32(<3 x float> %splat.splat, <3 x float> %1) | ||
| // CHECK: ret float %dx.dot | ||
| float test_dot_float3_splat ( float p0, float3 p1 ) { | ||
| return dot( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = call float @llvm.dx.dot.v4f32(<4 x float> %splat.splat, <4 x float> %1) | ||
| // CHECK: ret float %dx.dot | ||
| float test_dot_float4_splat ( float p0, float4 p1 ) { | ||
| return dot( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %conv = sitofp i32 %1 to float | ||
| // CHECK: %splat.splatinsert = insertelement <2 x float> poison, float %conv, i64 0 | ||
| // CHECK: %splat.splat = shufflevector <2 x float> %splat.splatinsert, <2 x float> poison, <2 x i32> zeroinitializer | ||
| // CHECK: %dx.dot = call float @llvm.dx.dot.v2f32(<2 x float> %0, <2 x float> %splat.splat) | ||
| // CHECK: ret float %dx.dot | ||
| float test_builtin_dot_float2_int_splat ( float2 p0, int p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %conv = sitofp i32 %1 to float | ||
| // CHECK: %splat.splatinsert = insertelement <3 x float> poison, float %conv, i64 0 | ||
| // CHECK: %splat.splat = shufflevector <3 x float> %splat.splatinsert, <3 x float> poison, <3 x i32> zeroinitializer | ||
| // CHECK: %dx.dot = call float @llvm.dx.dot.v3f32(<3 x float> %0, <3 x float> %splat.splat) | ||
| // CHECK: ret float %dx.dot | ||
| float test_builtin_dot_float3_int_splat ( float3 p0, int p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %dx.dot = fmul double %0, %1 | ||
| // CHECK: ret double %dx.dot | ||
| double test_dot_double ( double p0, double p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %conv = zext i1 %tobool to i32 | ||
| // CHECK: %dx.dot = mul i32 %conv, %1 | ||
| // CHECK: ret i32 %dx.dot | ||
| int test_dot_bool_scalar_arg0_type_promotion ( bool p0, int p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } | ||
|
|
||
| // CHECK: %conv = zext i1 %tobool to i32 | ||
| // CHECK: %dx.dot = mul i32 %0, %conv | ||
| // CHECK: ret i32 %dx.dot | ||
| int test_dot_bool_scalar_arg1_type_promotion ( int p0, bool p1 ) { | ||
| return dot ( p0, p1 ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s | ||
| void bar(int &Data) {} | ||
| // CHECK: define dso_local void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) % | ||
| void bar2(int &Data) {} | ||
| // CHECK: define dso_local void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) % | ||
| void bar(__attribute__((opencl_local)) int &Data) {} | ||
| // CHECK: define dso_local void @[[LOCAL_REF:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) % | ||
| void foo(int *Data) {} | ||
| // CHECK: define dso_local void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr noundef % | ||
| void foo2(int *Data) {} | ||
| // CHECK: define dso_local void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr noundef % | ||
| void foo(__attribute__((opencl_local)) int *Data) {} | ||
| // CHECK: define dso_local void @[[LOC_PTR:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef % | ||
|
|
||
| template <typename T> | ||
| void tmpl(T t); | ||
| // See Check Lines below. | ||
|
|
||
| void usages() { | ||
| int *NoAS; | ||
| // CHECK: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr, align 8, addrspace(5) | ||
| __attribute__((opencl_global)) int *GLOB; | ||
| // CHECK: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5) | ||
| __attribute__((opencl_local)) int *LOC; | ||
| // CHECK: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3), align 4, addrspace(5) | ||
| __attribute__((opencl_private)) int *PRIV; | ||
| // CHECK: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr addrspace(5), align 4, addrspace(5) | ||
| __attribute__((opencl_global_device)) int *GLOBDEVICE; | ||
| // CHECK: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5) | ||
| __attribute__((opencl_global_host)) int *GLOBHOST; | ||
| // CHECK: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5) | ||
| LOC = nullptr; | ||
| // CHECK: store ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3)), ptr [[LOC]].ascast, align 4 | ||
| GLOB = nullptr; | ||
| // CHECK: store ptr addrspace(1) null, ptr [[GLOB]].ascast, align 8 | ||
| NoAS = (int *)GLOB; | ||
| // CHECK: [[GLOB_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]].ascast, align 8 | ||
| // CHECK: [[GLOB_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD]] to ptr | ||
| // CHECK: store ptr [[GLOB_CAST]], ptr [[NoAS]].ascast, align 8 | ||
| NoAS = (int *)LOC; | ||
| // CHECK: [[LOC_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]].ascast, align 4 | ||
| // CHECK: [[LOC_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(3) [[LOC_LOAD]] to ptr | ||
| // CHECK: store ptr [[LOC_CAST]], ptr [[NoAS]].ascast, align 8 | ||
| NoAS = (int *)PRIV; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr [[PRIV]].ascast, align 4 | ||
| // CHECK: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(5) [[NoAS_LOAD]] to ptr | ||
| // CHECK: store ptr %5, ptr [[NoAS]].ascast, align 8 | ||
| GLOB = (__attribute__((opencl_global)) int *)NoAS; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8 | ||
| // CHECK: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr %6 to ptr addrspace(1) | ||
| // CHECK: store ptr addrspace(1) %7, ptr [[GLOB]].ascast, align 8 | ||
| LOC = (__attribute__((opencl_local)) int *)NoAS; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8 | ||
| // CHECK: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(3) | ||
| // CHECK: store ptr addrspace(3) %9, ptr [[LOC]].ascast, align 4 | ||
| PRIV = (__attribute__((opencl_private)) int *)NoAS; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8 | ||
| // CHECK: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(5) | ||
| // CHECK: store ptr addrspace(5) [[NoAS_CAST]], ptr [[PRIV]].ascast, align 4 | ||
| GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]]DEVICE.ascast, align 8 | ||
| // CHECK: store ptr addrspace(1) [[NoAS_LOAD]], ptr [[GLOB]].ascast, align 8 | ||
| GLOB = (__attribute__((opencl_global)) int *)GLOBHOST; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]]HOST.ascast, align 8 | ||
| // CHECK: tore ptr addrspace(1) [[NoAS_LOAD]], ptr [[GLOB]].ascast, align 8 | ||
| bar(*GLOB); | ||
| // CHECK: [[GLOB_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]].ascast, align 8 | ||
| // CHECK: [[GLOB_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD]] to ptr | ||
| // CHECK: call void @[[RAW_REF]](ptr noundef nonnull align 4 dereferenceable(4) [[GLOB_CAST]]) | ||
| bar2(*GLOB); | ||
| // CHECK: [[GLOB_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]].ascast, align 8 | ||
| // CHECK: [[GLOB_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD]] to ptr | ||
| // CHECK: call void @[[RAW_REF2]](ptr noundef nonnull align 4 dereferenceable(4) [[GLOB_CAST]]) | ||
| bar(*LOC); | ||
| // CHECK: [[LOC_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]].ascast, align 4 | ||
| // CHECK: call void @_Z3barRU3AS3i(ptr addrspace(3) noundef align 4 dereferenceable(4) [[LOC_LOAD]]) | ||
| bar2(*LOC); | ||
| // CHECK: [[LOC_LOAD2:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]].ascast, align 4 | ||
| // CHECK: [[LOC_CAST2:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(3) [[LOC_LOAD2]] to ptr | ||
| // CHECK: call void @_Z4bar2Ri(ptr noundef nonnull align 4 dereferenceable(4) [[LOC_CAST2]]) | ||
| bar(*NoAS); | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8 | ||
| // CHECK: call void @_Z3barRi(ptr noundef nonnull align 4 dereferenceable(4) [[NoAS_LOAD]]) | ||
| bar2(*NoAS); | ||
| // CHECK: [[NoAS_LOAD2:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8 | ||
| // CHECK: call void @_Z4bar2Ri(ptr noundef nonnull align 4 dereferenceable(4) [[NoAS_LOAD2]]) | ||
| foo(GLOB); | ||
| // CHECK: [[GLOB_LOAD3:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]].ascast, align 8 | ||
| // CHECK: [[GLOB_CAST3:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD3]] to ptr | ||
| // CHECK: call void @[[RAW_PTR]](ptr noundef [[GLOB_CAST3]]) | ||
| foo2(GLOB); | ||
| // CHECK: [[GLOB_LOAD4:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]].ascast, align 8 | ||
| // CHECK: [[GLOB_CAST4:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD4]] to ptr | ||
| // CHECK: call void @[[RAW_PTR2]](ptr noundef [[GLOB_CAST4]]) | ||
| foo(LOC); | ||
| // CHECK: [[LOC_LOAD3:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]].ascast, align 4 | ||
| // CHECK: call void @[[LOC_PTR]](ptr addrspace(3) noundef [[LOC_LOAD3]]) | ||
| foo2(LOC); | ||
| // CHECK: [[LOC_LOAD4:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]].ascast, align 4 | ||
| // CHECK: [[LOC_CAST4:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(3) [[LOC_LOAD4]] to ptr | ||
| // CHECK: call void @[[RAW_PTR2]](ptr noundef [[LOC_CAST4]]) | ||
| foo(NoAS); | ||
| // CHECK: [[NoAS_LOAD3:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8 | ||
| // CHECK: call void @[[RAW_PTR]](ptr noundef [[NoAS_LOAD3]]) | ||
| foo2(NoAS); | ||
| // CHECK: [[NoAS_LOAD4:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8 | ||
| // CHECK: call void @[[RAW_PTR2]](ptr noundef [[NoAS_LOAD4]]) | ||
|
|
||
| // Ensure that we still get 3 different template instantiations. | ||
| tmpl(GLOB); | ||
| // CHECK: [[GLOB_LOAD4:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]].ascast, align 8 | ||
| // CHECK: call void @_Z4tmplIPU3AS1iEvT_(ptr addrspace(1) noundef [[GLOB_LOAD4]]) | ||
| tmpl(LOC); | ||
| // CHECK: [[LOC_LOAD5:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]].ascast, align 4 | ||
| // CHECK: call void @_Z4tmplIPU3AS3iEvT_(ptr addrspace(3) noundef [[LOC_LOAD5]]) | ||
| tmpl(PRIV); | ||
| // CHECK: [[PRIV_LOAD5:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr [[PRIV]].ascast, align 4 | ||
| // CHECK: call void @_Z4tmplIPU3AS5iEvT_(ptr addrspace(5) noundef [[PRIV_LOAD5]]) | ||
| tmpl(NoAS); | ||
| // CHECK: [[NoAS_LOAD5:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8 | ||
| // CHECK: call void @_Z4tmplIPiEvT_(ptr noundef [[NoAS_LOAD5]]) | ||
| } | ||
|
|
||
| // CHECK: declare void @_Z4tmplIPU3AS1iEvT_(ptr addrspace(1) noundef) | ||
| // CHECK: declare void @_Z4tmplIPU3AS3iEvT_(ptr addrspace(3) noundef) | ||
| // CHECK: declare void @_Z4tmplIPU3AS5iEvT_(ptr addrspace(5) noundef) | ||
| // CHECK: declare void @_Z4tmplIPiEvT_(ptr noundef) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| // RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s | ||
| void bar(int &Data) {} | ||
| // CHECK: define dso_local void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) % | ||
| void bar2(int &Data) {} | ||
| // CHECK: define dso_local void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) % | ||
| void bar(__attribute__((opencl_local)) int &Data) {} | ||
| // CHECK: define dso_local void @[[LOCAL_REF:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) % | ||
| void foo(int *Data) {} | ||
| // CHECK: define dso_local void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr noundef % | ||
| void foo2(int *Data) {} | ||
| // CHECK: define dso_local void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr noundef % | ||
| void foo(__attribute__((opencl_local)) int *Data) {} | ||
| // CHECK: define dso_local void @[[LOC_PTR:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef % | ||
|
|
||
| template <typename T> | ||
| void tmpl(T t); | ||
| // See Check Lines below. | ||
|
|
||
| void usages() { | ||
| int *NoAS; | ||
| // CHECK: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr, align 8 | ||
| __attribute__((opencl_global)) int *GLOB; | ||
| // CHECK: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8 | ||
| __attribute__((opencl_local)) int *LOC; | ||
| // CHECK: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3), align 8 | ||
| __attribute__((opencl_private)) int *PRIV; | ||
| // CHECK: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr, align 8 | ||
| __attribute__((opencl_global_device)) int *GLOBDEVICE; | ||
| // CHECK: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8 | ||
| __attribute__((opencl_global_host)) int *GLOBHOST; | ||
| // CHECK: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8 | ||
| LOC = nullptr; | ||
| // CHECK: store ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3)), ptr [[LOC]], align 8 | ||
| GLOB = nullptr; | ||
| // CHECK: store ptr addrspace(1) null, ptr [[GLOB]], align 8 | ||
| NoAS = (int *)GLOB; | ||
| // CHECK: [[GLOB_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]], align 8 | ||
| // CHECK: [[GLOB_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD]] to ptr | ||
| // CHECK: store ptr [[GLOB_CAST]], ptr [[NoAS]], align 8 | ||
| NoAS = (int *)LOC; | ||
| // CHECK: [[LOC_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]], align 8 | ||
| // CHECK: [[LOC_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(3) [[LOC_LOAD]] to ptr | ||
| // CHECK: store ptr [[LOC_CAST]], ptr [[NoAS]], align 8 | ||
| NoAS = (int *)PRIV; | ||
| // CHECK: [[LOC_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[PRIV]], align 8 | ||
| // CHECK: store ptr [[LOC_LOAD]], ptr [[NoAS]], align 8 | ||
| GLOB = (__attribute__((opencl_global)) int *)NoAS; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8 | ||
| // CHECK: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(1) | ||
| // CHECK: store ptr addrspace(1) [[NoAS_CAST]], ptr [[GLOB]], align 8 | ||
| LOC = (__attribute__((opencl_local)) int *)NoAS; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8 | ||
| // CHECK: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(3) | ||
| // CHECK: store ptr addrspace(3) [[NoAS_CAST]], ptr [[LOC]], align 8 | ||
| PRIV = (__attribute__((opencl_private)) int *)NoAS; | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8 | ||
| // CHECK: store ptr [[NoAS_LOAD]], ptr [[PRIV]], align 8 | ||
| GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE; | ||
| // CHECK: [[GLOBDEVICE_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB_DEVICE]], align 8 | ||
| // CHECK: store ptr addrspace(1) [[GLOBDEVICE_LOAD]], ptr %GLOB, align 8 | ||
| GLOB = (__attribute__((opencl_global)) int *)GLOBHOST; | ||
| // CHECK: [[GLOB_HOST_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB_HOST]], align 8 | ||
| // CHECK: store ptr addrspace(1) [[GLOB_HOST_LOAD]], ptr [[GLOB]], align 8 | ||
| bar(*GLOB); | ||
| // CHECK: [[GLOB_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]], align 8 | ||
| // CHECK: [[GLOB_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD]] to ptr | ||
| // CHECK: call void @[[RAW_REF]](ptr noundef nonnull align 4 dereferenceable(4) [[GLOB_CAST]]) | ||
| bar2(*GLOB); | ||
| // CHECK: [[GLOB_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]], align 8 | ||
| // CHECK: [[GLOB_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD]] to ptr | ||
| // CHECK: call void @[[RAW_REF2]](ptr noundef nonnull align 4 dereferenceable(4) [[GLOB_CAST]]) | ||
| bar(*LOC); | ||
| // CHECK: [[LOC_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]], align 8 | ||
| // CHECK: call void @[[LOCAL_REF]](ptr addrspace(3) noundef align 4 dereferenceable(4) [[LOC_LOAD]]) | ||
| bar2(*LOC); | ||
| // CHECK: [[LOC_LOAD2:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]], align 8 | ||
| // CHECK: [[LOC_CAST2:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(3) [[LOC_LOAD2]] to ptr | ||
| // CHECK: call void @[[RAW_REF2]](ptr noundef nonnull align 4 dereferenceable(4) [[LOC_CAST2]]) | ||
| bar(*NoAS); | ||
| // CHECK: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8 | ||
| // CHECK: call void @[[RAW_REF]](ptr noundef nonnull align 4 dereferenceable(4) [[NoAS_LOAD]]) | ||
| bar2(*NoAS); | ||
| // CHECK: [[NoAS_LOAD2:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8 | ||
| // CHECK: call void @[[RAW_REF2]](ptr noundef nonnull align 4 dereferenceable(4) [[NoAS_LOAD2]]) | ||
| foo(GLOB); | ||
| // CHECK: [[GLOB_LOAD3:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]], align 8 | ||
| // CHECK: [[GLOB_CAST3:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD3]] to ptr | ||
| // CHECK: call void @[[RAW_PTR]](ptr noundef [[GLOB_CAST3]]) | ||
| foo2(GLOB); | ||
| // CHECK: [[GLOB_LOAD4:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]], align 8 | ||
| // CHECK: [[GLOB_CAST4:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(1) [[GLOB_LOAD4]] to ptr | ||
| // CHECK: call void @[[RAW_PTR2]](ptr noundef [[GLOB_CAST4]]) | ||
| foo(LOC); | ||
| // CHECK: [[LOC_LOAD3:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]], align 8 | ||
| // CHECK: call void @[[LOC_PTR]](ptr addrspace(3) noundef [[LOC_LOAD3]]) | ||
| foo2(LOC); | ||
| // CHECK: [[LOC_LOAD4:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]], align 8 | ||
| // CHECK: [[LOC_CAST4:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(3) [[LOC_LOAD4]] to ptr | ||
| // CHECK: call void @[[RAW_PTR2]](ptr noundef [[LOC_CAST4]]) | ||
| foo(NoAS); | ||
| // CHECK: [[NoAS_LOAD3:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8 | ||
| // CHECK: call void @[[RAW_PTR]](ptr noundef [[NoAS_LOAD3]]) | ||
| foo2(NoAS); | ||
| // CHECK: [[NoAS_LOAD4:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8 | ||
| // CHECK: call void @[[RAW_PTR2]](ptr noundef [[NoAS_LOAD4]]) | ||
| tmpl(GLOB); | ||
| // CHECK: [[GLOB_LOAD4:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]], align 8 | ||
| // CHECK: call void @_Z4tmplIPU3AS1iEvT_(ptr addrspace(1) noundef [[GLOB_LOAD4]]) | ||
| tmpl(LOC); | ||
| // CHECK: [[LOC_LOAD5:%[a-zA-Z0-9]+]] = load ptr addrspace(3), ptr [[LOC]], align 8 | ||
| // CHECK: call void @_Z4tmplIPU3AS3iEvT_(ptr addrspace(3) noundef [[LOC_LOAD5]]) | ||
| tmpl(PRIV); | ||
| // CHECK: [[PRIV_LOAD5:%[a-zA-Z0-9]+]] = load ptr, ptr [[PRIV]], align 8 | ||
| // CHECK: call void @_Z4tmplIPiEvT_(ptr noundef [[PRIV_LOAD5]]) | ||
| tmpl(NoAS); | ||
| // CHECK: %33 = load ptr, ptr %NoAS, align 8 | ||
| // CHECK: call void @_Z4tmplIPiEvT_(ptr noundef %33) | ||
| } | ||
|
|
||
| // CHECK: declare void @_Z4tmplIPU3AS1iEvT_(ptr addrspace(1) noundef) | ||
| // CHECK: declare void @_Z4tmplIPU3AS3iEvT_(ptr addrspace(3) noundef) | ||
| // CHECK: declare void @_Z4tmplIPiEvT_(ptr noundef) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected | ||
|
|
||
| float test_no_second_arg ( float2 p0) { | ||
| return __builtin_hlsl_dot ( p0 ); | ||
| // expected-error@-1 {{too few arguments to function call, expected 2, have 1}} | ||
| } | ||
|
|
||
| float test_too_many_arg ( float2 p0) { | ||
| return __builtin_hlsl_dot ( p0, p0, p0 ); | ||
| // expected-error@-1 {{too many arguments to function call, expected 2, have 3}} | ||
| } | ||
|
|
||
| float test_dot_no_second_arg ( float2 p0) { | ||
| return dot ( p0 ); | ||
| // expected-error@-1 {{no matching function for call to 'dot'}} | ||
| } | ||
|
|
||
| float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| // expected-warning@-1 {{implicit conversion truncates vector: 'float3' (aka 'vector<float, 3>') to 'float __attribute__((ext_vector_type(2)))' (vector of 2 'float' values)}} | ||
| } | ||
|
|
||
| float test_dot_builtin_vector_size_mismatch ( float3 p0, float2 p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have the same type}} | ||
| } | ||
|
|
||
| float test_dot_scalar_mismatch ( float p0, int p1 ) { | ||
| return dot ( p0, p1 ); | ||
| // expected-error@-1 {{call to 'dot' is ambiguous}} | ||
| } | ||
|
|
||
| float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) { | ||
| return dot ( p0, p1 ); | ||
| // expected-error@-1 {{call to 'dot' is ambiguous}} | ||
| } | ||
|
|
||
| //NOTE: for all the *_promotion we are intentionally not handling type promotion in builtins | ||
| float test_builtin_dot_vec_int_to_float_promotion ( int2 p0, float2 p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have the same type}} | ||
| } | ||
|
|
||
| int64_t test_builtin_dot_vec_int_to_int64_promotion( int64_t2 p0, int2 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have the same type}} | ||
| } | ||
|
|
||
| float test_builtin_dot_vec_half_to_float_promotion( float2 p0, half2 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have the same type}} | ||
| } | ||
|
|
||
| #ifdef __HLSL_ENABLE_16_BIT | ||
| float test_builtin_dot_vec_int16_to_float_promotion( float2 p0, int16_t2 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have the same type}} | ||
| } | ||
|
|
||
| half test_builtin_dot_vec_int16_to_half_promotion( half2 p0, int16_t2 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have the same type}} | ||
| } | ||
|
|
||
| int test_builtin_dot_vec_int16_to_int_promotion( int2 p0, int16_t2 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have the same type}} | ||
| } | ||
|
|
||
| int64_t test_builtin_dot_vec_int16_to_int64_promotion( int64_t2 p0, int16_t2 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must have the same type}} | ||
| } | ||
| #endif | ||
|
|
||
| float test_builtin_dot_float2_splat ( float p0, float2 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must be vectors}} | ||
| } | ||
|
|
||
| float test_builtin_dot_float3_splat ( float p0, float3 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must be vectors}} | ||
| } | ||
|
|
||
| float test_builtin_dot_float4_splat ( float p0, float4 p1 ) { | ||
| return __builtin_hlsl_dot( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must be vectors}} | ||
| } | ||
|
|
||
| float test_dot_float2_int_splat ( float2 p0, int p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must be vectors}} | ||
| } | ||
|
|
||
| float test_dot_float3_int_splat ( float3 p0, int p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must be vectors}} | ||
| } | ||
|
|
||
| float test_builtin_dot_int_vect_to_float_vec_promotion ( int2 p0, float p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| // expected-error@-1 {{first two arguments to '__builtin_hlsl_dot' must be vectors}} | ||
| } | ||
|
|
||
| int test_builtin_dot_bool_type_promotion ( bool p0, bool p1 ) { | ||
| return __builtin_hlsl_dot ( p0, p1 ); | ||
| // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'bool')}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // RUN: %clang_cc1 %s -verify -fopenacc -fcxx-exceptions | ||
|
|
||
|
|
||
| void ReturnTest() { | ||
| #pragma acc parallel | ||
| { | ||
| (void)[]() { return; }; | ||
| } | ||
|
|
||
| #pragma acc parallel | ||
| { | ||
| try {} | ||
| catch(...){ | ||
| return; // expected-error{{invalid return out of OpenACC Compute Construct}} | ||
| } | ||
| } | ||
| } |