From 30d80009e5012eba5f2e026375038e81932d84f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?= =?UTF-8?q?=E3=83=B3=29?= Date: Wed, 6 Nov 2024 17:45:58 -0800 Subject: [PATCH] [flang][cuda] Allow SHARED actual to DEVICE dummy (#115215) Update the compatibility rules to allow SHARED actual argument passed to DEVICE dummy argument. Emit a warning in that case. --- flang/include/flang/Common/Fortran.h | 3 ++- flang/lib/Common/Fortran.cpp | 9 +++++++-- flang/lib/Evaluate/characteristics.cpp | 4 ++-- flang/lib/Semantics/check-call.cpp | 7 ++++++- flang/test/Semantics/cuf17.cuf | 18 ++++++++++++++++++ 5 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 flang/test/Semantics/cuf17.cuf diff --git a/flang/include/flang/Common/Fortran.h b/flang/include/flang/Common/Fortran.h index 5b2ed43a8f99..cb109ad574cf 100644 --- a/flang/include/flang/Common/Fortran.h +++ b/flang/include/flang/Common/Fortran.h @@ -118,7 +118,8 @@ static constexpr IgnoreTKRSet ignoreTKRAll{IgnoreTKR::Type, IgnoreTKR::Kind, std::string AsFortran(IgnoreTKRSet); bool AreCompatibleCUDADataAttrs(std::optional, - std::optional, IgnoreTKRSet, bool allowUnifiedMatchingRule, + std::optional, IgnoreTKRSet, std::optional *, + bool allowUnifiedMatchingRule, const LanguageFeatureControl *features = nullptr); static constexpr char blankCommonObjectName[] = "__BLNK__"; diff --git a/flang/lib/Common/Fortran.cpp b/flang/lib/Common/Fortran.cpp index c014b1263a67..367a51f884e8 100644 --- a/flang/lib/Common/Fortran.cpp +++ b/flang/lib/Common/Fortran.cpp @@ -103,7 +103,8 @@ std::string AsFortran(IgnoreTKRSet tkr) { /// dummy argument attribute while `y` represents the actual argument attribute. bool AreCompatibleCUDADataAttrs(std::optional x, std::optional y, IgnoreTKRSet ignoreTKR, - bool allowUnifiedMatchingRule, const LanguageFeatureControl *features) { + std::optional *warning, bool allowUnifiedMatchingRule, + const LanguageFeatureControl *features) { bool isCudaManaged{features ? features->IsEnabled(common::LanguageFeature::CudaManaged) : false}; @@ -134,8 +135,12 @@ bool AreCompatibleCUDADataAttrs(std::optional x, } else { if (*x == CUDADataAttr::Device) { if ((y && - (*y == CUDADataAttr::Managed || *y == CUDADataAttr::Unified)) || + (*y == CUDADataAttr::Managed || *y == CUDADataAttr::Unified || + *y == CUDADataAttr::Shared)) || (!y && (isCudaUnified || isCudaManaged))) { + if (y && *y == CUDADataAttr::Shared && warning) { + *warning = "SHARED attribute ignored"s; + } return true; } } else if (*x == CUDADataAttr::Managed) { diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp index 2496e4427fe7..78cc63d0fde4 100644 --- a/flang/lib/Evaluate/characteristics.cpp +++ b/flang/lib/Evaluate/characteristics.cpp @@ -371,7 +371,7 @@ bool DummyDataObject::IsCompatibleWith(const DummyDataObject &actual, } if (!attrs.test(Attr::Value) && !common::AreCompatibleCUDADataAttrs(cudaDataAttr, actual.cudaDataAttr, - ignoreTKR, + ignoreTKR, warning, /*allowUnifiedMatchingRule=*/false)) { if (whyNot) { *whyNot = "incompatible CUDA data attributes"; @@ -1771,7 +1771,7 @@ bool DistinguishUtils::Distinguishable( x.intent != common::Intent::In) { return true; } else if (!common::AreCompatibleCUDADataAttrs(x.cudaDataAttr, y.cudaDataAttr, - x.ignoreTKR | y.ignoreTKR, + x.ignoreTKR | y.ignoreTKR, nullptr, /*allowUnifiedMatchingRule=*/false)) { return true; } else if (features_.IsEnabled( diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp index fa2d59da10f8..a161d2bdf9db 100644 --- a/flang/lib/Semantics/check-call.cpp +++ b/flang/lib/Semantics/check-call.cpp @@ -976,8 +976,9 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy, actualDataAttr = common::CUDADataAttr::Device; } } + std::optional warning; if (!common::AreCompatibleCUDADataAttrs(dummyDataAttr, actualDataAttr, - dummy.ignoreTKR, + dummy.ignoreTKR, &warning, /*allowUnifiedMatchingRule=*/true, &context.languageFeatures())) { auto toStr{[](std::optional x) { return x ? "ATTRIBUTES("s + @@ -988,6 +989,10 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy, "%s has %s but its associated actual argument has %s"_err_en_US, dummyName, toStr(dummyDataAttr), toStr(actualDataAttr)); } + if (warning && context.ShouldWarn(common::UsageWarning::CUDAUsage)) { + messages.Say(common::UsageWarning::CUDAUsage, "%s"_warn_en_US, + std::move(*warning)); + } } // Warning for breaking F'2023 change with character allocatables diff --git a/flang/test/Semantics/cuf17.cuf b/flang/test/Semantics/cuf17.cuf new file mode 100644 index 000000000000..daeb59033561 --- /dev/null +++ b/flang/test/Semantics/cuf17.cuf @@ -0,0 +1,18 @@ +! RUN: bbc -emit-hlfir -fcuda %s 2>&1 | FileCheck %s + +module mod1 +contains + +attributes(device) subroutine sub1(adev) + real, device :: adev(10) +end + +attributes(global) subroutine sub2() + real, shared :: adev(10) + !WARNING: SHARED attribute ignored + call sub1(adev) +end subroutine + +end module + +! CHECK: warning: SHARED attribute ignored