Skip to content

Commit 0cfc2db

Browse files
committed
[OpenMP] Allow exceptions in target regions when offloading to GPUs
The motivation for this patch is that many code bases use exception handling. As GPUs are not expected to support exception handling in the near future, we can experiment with compiling the code for GPU targets anyway. This will allow us to run the code, as long as no exception is thrown. The overall idea is very simple: - If a throw expression is compiled to AMDGCN or NVPTX, it is replaced with a trap during code generation. - If a try/catch statement is compiled to AMDGCN or AMDHSA, we ganerate code for the try statement as if it were a basic block. With this patch, the compilation of the following example ```{C++} int gaussian_sum(int a,int b){ if ((a + b) % 2 == 0) {throw -1;}; return (a+b) * ((a+b)/2); } int main(void) { int gauss = 0; #pragma omp target map(from:gauss) { try { gauss = gaussian_sum(1,100); } catch (int e){ gauss = e; } } std::cout << "GaussianSum(1,100)="<<gauss<<std::endl; #pragma omp target map(from:gauss) { try { gauss = gaussian_sum(1,101); } catch (int e){ gauss = e; } } std::cout << "GaussianSum(1,101)="<<gauss<<std::endl; return (gauss > 1) ? 0 : 1; } ``` with offloading to `gfx906` results in ```{bash} ./bin/target_try_minimal_fail GaussianSum(1,100)=5050 AMDGPU fatal error 1: Received error in queue 0x155555506000: HSA_STATUS_ERROR_EXCEPTION: An HSAIL operation resulted in a hardware exception. zsh: abort (core dumped) ``` Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D153924
1 parent f6259d9 commit 0cfc2db

17 files changed

+371
-13
lines changed

clang/include/clang/Basic/DiagnosticCommonKinds.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,4 +425,13 @@ def err_opencl_extension_and_feature_differs : Error<
425425
"options %0 and %1 are set to different values">;
426426
def err_opencl_feature_requires : Error<
427427
"feature %0 requires support of %1 feature">;
428+
429+
def warn_throw_not_valid_on_target : Warning<
430+
"target '%0' does not support exception handling;"
431+
" 'throw' is assumed to be never reached">,
432+
InGroup<OpenMPTargetException>;
433+
def warn_try_not_valid_on_target : Warning<
434+
"target '%0' does not support exception handling;"
435+
" 'catch' block is ignored">,
436+
InGroup<OpenMPTargetException>;
428437
}

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1292,9 +1292,10 @@ def OpenMPTarget : DiagGroup<"openmp-target", [OpenMPMapping]>;
12921292
def OpenMPPre51Compat : DiagGroup<"pre-openmp-51-compat">;
12931293
def OpenMP51Ext : DiagGroup<"openmp-51-extensions">;
12941294
def OpenMPExtensions : DiagGroup<"openmp-extensions">;
1295+
def OpenMPTargetException : DiagGroup<"openmp-target-exception">;
12951296
def OpenMP : DiagGroup<"openmp", [
12961297
SourceUsesOpenMP, OpenMPClauses, OpenMPLoopForm, OpenMPTarget,
1297-
OpenMPMapping, OpenMP51Ext, OpenMPExtensions
1298+
OpenMPMapping, OpenMP51Ext, OpenMPExtensions, OpenMPTargetException
12981299
]>;
12991300

13001301
// Backend warnings.

clang/lib/CodeGen/CGException.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,15 @@ llvm::Value *CodeGenFunction::getSelectorFromSlot() {
440440

441441
void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
442442
bool KeepInsertionPoint) {
443+
// If the exception is being emitted in an OpenMP target region,
444+
// and the target is a GPU, we do not support exception handling.
445+
// Therefore, we emit a trap which will abort the program, and
446+
// prompt a warning indicating that a trap will be emitted.
447+
const llvm::Triple &T = Target.getTriple();
448+
if (CGM.getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) {
449+
EmitTrapCall(llvm::Intrinsic::trap);
450+
return;
451+
}
443452
if (const Expr *SubExpr = E->getSubExpr()) {
444453
QualType ThrowType = SubExpr->getType();
445454
if (ThrowType->isObjCObjectPointerType()) {
@@ -609,9 +618,16 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
609618
}
610619

611620
void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
612-
EnterCXXTryStmt(S);
621+
const llvm::Triple &T = Target.getTriple();
622+
// If we encounter a try statement on in an OpenMP target region offloaded to
623+
// a GPU, we treat it as a basic block.
624+
const bool IsTargetDevice =
625+
(CGM.getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()));
626+
if (!IsTargetDevice)
627+
EnterCXXTryStmt(S);
613628
EmitStmt(S.getTryBlock());
614-
ExitCXXTryStmt(S);
629+
if (!IsTargetDevice)
630+
ExitCXXTryStmt(S);
615631
}
616632

617633
void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -864,13 +864,21 @@ Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) {
864864

865865
ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
866866
bool IsThrownVarInScope) {
867-
// Don't report an error if 'throw' is used in system headers.
868-
if (!getLangOpts().CXXExceptions &&
867+
const llvm::Triple &T = Context.getTargetInfo().getTriple();
868+
const bool IsOpenMPGPUTarget =
869+
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
870+
// Don't report an error if 'throw' is used in system headers or in an OpenMP
871+
// target region compiled for a GPU architecture.
872+
if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
869873
!getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) {
870874
// Delay error emission for the OpenMP device code.
871875
targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
872876
}
873877

878+
// In OpenMP target regions, we replace 'throw' with a trap on GPU targets.
879+
if (IsOpenMPGPUTarget)
880+
targetDiag(OpLoc, diag::warn_throw_not_valid_on_target) << T.str();
881+
874882
// Exceptions aren't allowed in CUDA device code.
875883
if (getLangOpts().CUDA)
876884
CUDADiagIfDeviceCode(OpLoc, diag::err_cuda_device_exceptions)

clang/lib/Sema/SemaStmt.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4471,13 +4471,22 @@ class CatchTypePublicBases {
44714471
/// handlers and creates a try statement from them.
44724472
StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
44734473
ArrayRef<Stmt *> Handlers) {
4474-
// Don't report an error if 'try' is used in system headers.
4475-
if (!getLangOpts().CXXExceptions &&
4474+
const llvm::Triple &T = Context.getTargetInfo().getTriple();
4475+
const bool IsOpenMPGPUTarget =
4476+
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
4477+
// Don't report an error if 'try' is used in system headers or in an OpenMP
4478+
// target region compiled for a GPU architecture.
4479+
if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
44764480
!getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA) {
44774481
// Delay error emission for the OpenMP device code.
44784482
targetDiag(TryLoc, diag::err_exceptions_disabled) << "try";
44794483
}
44804484

4485+
// In OpenMP target regions, we assume that catch is never reached on GPU
4486+
// targets.
4487+
if (IsOpenMPGPUTarget)
4488+
targetDiag(TryLoc, diag::warn_try_not_valid_on_target) << T.str();
4489+
44814490
// Exceptions aren't allowed in CUDA device code.
44824491
if (getLangOpts().CUDA)
44834492
CUDADiagIfDeviceCode(TryLoc, diag::err_cuda_device_exceptions)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* The first four lines test that a warning is produced when enabling
3+
* -Wopenmp-target-exception no matter what combination of -fexceptions and
4+
* -fcxx-exceptions are set, as we want OpenMP to always allow exceptions in the
5+
* target region but emit a warning instead.
6+
*/
7+
8+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
9+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
10+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
11+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
12+
13+
/**
14+
* The following four lines test that no warning is emitted when providing
15+
* -Wno-openmp-target-exception no matter the combination of -fexceptions and
16+
* -fcxx-exceptions.
17+
*/
18+
19+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
20+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
21+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
22+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
23+
24+
/**
25+
* Finally we should test that we only ignore exceptions in the OpenMP
26+
* offloading tool-chain
27+
*/
28+
29+
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa %s -emit-llvm -S -verify=noexceptions -o -
30+
31+
// noexceptions-error@37 {{cannot use 'try' with exceptions disabled}}
32+
// noexceptions-error@38 {{cannot use 'throw' with exceptions disabled}}
33+
34+
#pragma omp declare target
35+
int foo(void) {
36+
int error = -1;
37+
try { // with-warning {{target 'amdgcn-amd-amdhsa' does not support exception handling; 'catch' block is ignored}}
38+
throw 404; // with-warning {{target 'amdgcn-amd-amdhsa' does not support exception handling; 'throw' is assumed to be never reached}}
39+
}
40+
catch (int e){
41+
error = e;
42+
}
43+
return error;
44+
}
45+
#pragma omp end declare target
46+
// without-no-diagnostics

clang/test/OpenMP/amdgpu_throw.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* The first four lines test that a warning is produced when enabling
3+
* -Wopenmp-target-exception no matter what combination of -fexceptions and
4+
* -fcxx-exceptions are set, as we want OpenMP to always allow exceptions in the
5+
* target region but emit a warning instead.
6+
*/
7+
8+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
9+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
10+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
11+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
12+
13+
/**
14+
* The following four lines test that no warning is emitted when providing
15+
* -Wno-openmp-target-exception no matter the combination of -fexceptions and
16+
* -fcxx-exceptions.
17+
*/
18+
19+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
20+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
21+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
22+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
23+
24+
/**
25+
* Finally we should test that we only ignore exceptions in the OpenMP
26+
* offloading tool-chain
27+
*/
28+
29+
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa %s -emit-llvm -S -verify=noexceptions -o -
30+
31+
// noexceptions-error@35 {{cannot use 'throw' with exceptions disabled}}
32+
33+
#pragma omp declare target
34+
void foo(void) {
35+
throw 404; // with-warning {{target 'amdgcn-amd-amdhsa' does not support exception handling; 'throw' is assumed to be never reached}}
36+
}
37+
#pragma omp end declare target
38+
// without-no-diagnostics
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device %s -emit-llvm -S -Wno-openmp-target-exception -o - | FileCheck -check-prefix=DEVICE %s
2+
// RUN: %clang_cc1 -fopenmp -triple x86_64-pc-linux-gnu -fopenmp-is-target-device -fcxx-exceptions %s -emit-llvm -S -Wno-openmp-target-exception -o - | FileCheck -check-prefix=HOST %s
3+
// DEVICE: s_trap
4+
// DEVICE-NOT: __cxa_throw
5+
// HOST: __cxa_throw
6+
// HOST-NOT: s_trap
7+
#pragma omp declare target
8+
void foo(void) {
9+
throw 404;
10+
}
11+
#pragma omp end declare target
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* The first four lines test that a warning is produced when enabling
3+
* -Wopenmp-target-exception no matter what combination of -fexceptions and
4+
* -fcxx-exceptions are set, as we want OpenMP to always allow exceptions in the
5+
* target region but emit a warning instead.
6+
*/
7+
8+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
9+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
10+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
11+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
12+
13+
/**
14+
* The following four lines test that no warning is emitted when providing
15+
* -Wno-openmp-target-exception no matter the combination of -fexceptions and
16+
* -fcxx-exceptions.
17+
*/
18+
19+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
20+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fcxx-exceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
21+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
22+
// RUN: %clang_cc1 -fopenmp -triple amdgcn-amd-amdhsa -fopenmp-is-target-device %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
23+
24+
/**
25+
* Finally we should test that we only ignore exceptions in the OpenMP
26+
* offloading tool-chain
27+
*/
28+
29+
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa %s -emit-llvm -S -verify=noexceptions -o -
30+
31+
// noexceptions-error@36 {{cannot use 'try' with exceptions disabled}}
32+
33+
#pragma omp declare target
34+
int foo(void) {
35+
int error = -1;
36+
try { // with-warning {{target 'amdgcn-amd-amdhsa' does not support exception handling; 'catch' block is ignored}}
37+
error = 1;
38+
}
39+
catch (int e){
40+
error = e;
41+
}
42+
return error;
43+
}
44+
#pragma omp end declare target
45+
// without-no-diagnostics
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* The first four lines test that a warning is produced when enabling
3+
* -Wopenmp-target-exception no matter what combination of -fexceptions and
4+
* -fcxx-exceptions are set, as we want OpenMP to always allow exceptions in the
5+
* target region but emit a warning instead.
6+
*/
7+
8+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
9+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
10+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
11+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
12+
13+
/**
14+
* The following four lines test that no warning is emitted when providing
15+
* -Wno-openmp-target-exception no matter the combination of -fexceptions and
16+
* -fcxx-exceptions.
17+
*/
18+
19+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
20+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fcxx-exceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
21+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
22+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
23+
24+
/**
25+
* Finally we should test that we only ignore exceptions in the OpenMP
26+
* offloading tool-chain
27+
*/
28+
29+
// RUN: %clang_cc1 -triple nvptx64 %s -emit-llvm -S -verify=noexceptions -o -
30+
31+
// noexceptions-error@37 {{cannot use 'try' with exceptions disabled}}
32+
// noexceptions-error@38 {{cannot use 'throw' with exceptions disabled}}
33+
34+
#pragma omp declare target
35+
int foo(void) {
36+
int error = -1;
37+
try { // with-warning {{target 'nvptx64' does not support exception handling; 'catch' block is ignored}}
38+
throw 404; // with-warning {{target 'nvptx64' does not support exception handling; 'throw' is assumed to be never reached}}
39+
}
40+
catch (int e){
41+
error = e;
42+
}
43+
return error;
44+
}
45+
#pragma omp end declare target
46+
// without-no-diagnostics

clang/test/OpenMP/nvptx_target_exceptions_messages.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ T FA() {
3434
#pragma omp declare target
3535
struct S {
3636
int a;
37-
S(int a) : a(a) { throw 1; } // expected-error {{cannot use 'throw' with exceptions disabled}}
37+
S(int a) : a(a) { throw 1; } // expected-warning {{target 'nvptx64-unknown-unknown' does not support exception handling; 'throw' is assumed to be never reached}}
3838
};
3939

4040
int foo() { return 0; }
@@ -57,7 +57,7 @@ int maini1() {
5757
static long aaa = 23;
5858
a = foo() + bar() + b + c + d + aa + aaa + FA<int>(); // expected-note{{called by 'maini1'}}
5959
if (!a)
60-
throw "Error"; // expected-error {{cannot use 'throw' with exceptions disabled}}
60+
throw "Error"; // expected-warning {{target 'nvptx64-unknown-unknown' does not support exception handling; 'throw' is assumed to be never reached}}
6161
}
6262
} catch(...) {
6363
}
@@ -67,14 +67,14 @@ int maini1() {
6767
int baz3() { return 2 + baz2(); }
6868
int baz2() {
6969
#pragma omp target
70-
try { // expected-error {{cannot use 'try' with exceptions disabled}}
70+
try { // expected-warning {{target 'nvptx64-unknown-unknown' does not support exception handling; 'catch' block is ignored}}
7171
++c;
7272
} catch (...) {
7373
}
7474
return 2 + baz3();
7575
}
7676

77-
int baz1() { throw 1; } // expected-error {{cannot use 'throw' with exceptions disabled}}
77+
int baz1() { throw 1; } // expected-warning {{target 'nvptx64-unknown-unknown' does not support exception handling; 'throw' is assumed to be never reached}}
7878

7979
int foobar1();
8080
int foobar2();
@@ -85,7 +85,7 @@ int (*B)() = &foobar2;
8585
#pragma omp end declare target
8686

8787
int foobar1() { throw 1; }
88-
int foobar2() { throw 1; } // expected-error {{cannot use 'throw' with exceptions disabled}}
88+
int foobar2() { throw 1; } // expected-warning {{target 'nvptx64-unknown-unknown' does not support exception handling; 'throw' is assumed to be never reached}}
8989

9090

9191
int foobar3();
@@ -95,7 +95,7 @@ int (*C)() = &foobar3; // expected-warning {{declaration is not declared in any
9595
int (*D)() = C; // expected-note {{used here}}
9696
// host-note@-1 {{used here}}
9797
#pragma omp end declare target
98-
int foobar3() { throw 1; } // expected-error {{cannot use 'throw' with exceptions disabled}}
98+
int foobar3() { throw 1; } // expected-warning {{target 'nvptx64-unknown-unknown' does not support exception handling; 'throw' is assumed to be never reached}}
9999

100100
// Check no infinite recursion in deferred diagnostic emitter.
101101
long E = (long)&E;

clang/test/OpenMP/nvptx_throw.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* The first four lines test that a warning is produced when enabling
3+
* -Wopenmp-target-exception no matter what combination of -fexceptions and
4+
* -fcxx-exceptions are set, as we want OpenMP to always allow exceptions in the
5+
* target region but emit a warning instead.
6+
*/
7+
8+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
9+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
10+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
11+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device %s -emit-llvm -S -verify=with -Wopenmp-target-exception -analyze
12+
13+
/**
14+
* The following four lines test that no warning is emitted when providing
15+
* -Wno-openmp-target-exception no matter the combination of -fexceptions and
16+
* -fcxx-exceptions.
17+
*/
18+
19+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fcxx-exceptions -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
20+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fcxx-exceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
21+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device -fexceptions %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
22+
// RUN: %clang_cc1 -fopenmp -triple nvptx64 -fopenmp-is-target-device %s -emit-llvm -S -verify=without -Wno-openmp-target-exception -analyze
23+
24+
/**
25+
* Finally we should test that we only ignore exceptions in the OpenMP
26+
* offloading tool-chain
27+
*/
28+
29+
// RUN: %clang_cc1 -triple nvptx64 %s -emit-llvm -S -verify=noexceptions -o -
30+
31+
// noexceptions-error@35 {{cannot use 'throw' with exceptions disabled}}
32+
33+
#pragma omp declare target
34+
void foo(void) {
35+
throw 404; // with-warning {{target 'nvptx64' does not support exception handling; 'throw' is assumed to be never reached}}
36+
}
37+
#pragma omp end declare target
38+
// without-no-diagnostics

0 commit comments

Comments
 (0)