From 2ab5fefdba76e265fd5fa27115a4f4e57170ea60 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Mon, 27 Oct 2025 19:03:31 -0400 Subject: [PATCH 01/16] ignore_tkr(p) support --- flang/include/flang/Support/Fortran.h | 13 +++++++------ flang/lib/Semantics/mod-file.cpp | 2 ++ flang/lib/Semantics/resolve-names.cpp | 3 +++ flang/lib/Support/Fortran.cpp | 3 +++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/flang/include/flang/Support/Fortran.h b/flang/include/flang/Support/Fortran.h index ea0344ecb0830..1c8a118dd44e7 100644 --- a/flang/include/flang/Support/Fortran.h +++ b/flang/include/flang/Support/Fortran.h @@ -81,13 +81,14 @@ static constexpr int maxNameLen{63}; // !DIR$ IGNORE_TKR [[(letters) name] ... letters // "A" expands to all of TKRDM ENUM_CLASS(IgnoreTKR, - Type, // T - don't check type category - Kind, // K - don't check kind - Rank, // R - don't check ranks - Device, // D - don't check host/device residence - Managed, // M - don't check managed storage - Contiguous) // C - don't check for storage sequence association with a + Type, // T - don't check type category + Kind, // K - don't check kind + Rank, // R - don't check ranks + Device, // D - don't check host/device residence + Managed, // M - don't check managed storage + Contiguous, // C - don't check for storage sequence association with a // potentially non-contiguous object + Pointer) // P - ignore pointer and allocatable matching using IgnoreTKRSet = EnumSet; // IGNORE_TKR(A) = IGNORE_TKR(TKRDM) static constexpr IgnoreTKRSet ignoreTKRAll{IgnoreTKR::Type, IgnoreTKR::Kind, diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index 556259d1e5e63..732be56b905dd 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -1020,6 +1020,8 @@ void ModFileWriter::PutObjectEntity( break; case common::IgnoreTKR::Contiguous: os << 'c'; + case common::IgnoreTKR::Pointer: + os << 'p'; break; } }); diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 4af6cf6a91239..d3cf6f82756a8 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -10127,6 +10127,9 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) { case 'c': set.set(common::IgnoreTKR::Contiguous); break; + case 'p': + set.set(common::IgnoreTKR::Pointer); + break; case 'a': set = common::ignoreTKRAll; break; diff --git a/flang/lib/Support/Fortran.cpp b/flang/lib/Support/Fortran.cpp index 3a8ebbb7d61ef..05d6e0e709e91 100644 --- a/flang/lib/Support/Fortran.cpp +++ b/flang/lib/Support/Fortran.cpp @@ -95,6 +95,9 @@ std::string AsFortran(IgnoreTKRSet tkr) { if (tkr.test(IgnoreTKR::Contiguous)) { result += 'C'; } + if (tkr.test(IgnoreTKR::Pointer)) { + result += 'P'; + } return result; } From 7294e688dd3aa2156311cd1ce086b249a3e570b6 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Wed, 27 Aug 2025 10:36:33 -0400 Subject: [PATCH 02/16] [flang] Implement CFI_show() Implement in runtime and add declaration to ISO_Fortran_binding.h --- flang-rt/lib/runtime/ISO_Fortran_binding.cpp | 8 ++++++++ flang/include/flang/ISO_Fortran_binding.h | 1 + 2 files changed, 9 insertions(+) diff --git a/flang-rt/lib/runtime/ISO_Fortran_binding.cpp b/flang-rt/lib/runtime/ISO_Fortran_binding.cpp index a5f8b357ae0b8..22d32155b915a 100644 --- a/flang-rt/lib/runtime/ISO_Fortran_binding.cpp +++ b/flang-rt/lib/runtime/ISO_Fortran_binding.cpp @@ -297,6 +297,14 @@ RT_API_ATTRS int CFI_setpointer(CFI_cdesc_t *result, const CFI_cdesc_t *source, return CFI_SUCCESS; } +RT_API_ATTRS void CFI_show(void *buf, const CFI_cdesc_t *descr) { + FILE *f{stderr}; + std::fprintf(f, "%p CFI_desc_t: %p\n", buf, descr); + if (descr) { + reinterpret_cast(descr)->Dump(f); + } +} + RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::ISO diff --git a/flang/include/flang/ISO_Fortran_binding.h b/flang/include/flang/ISO_Fortran_binding.h index f5b8d0d2ea610..4e2575ee9a622 100644 --- a/flang/include/flang/ISO_Fortran_binding.h +++ b/flang/include/flang/ISO_Fortran_binding.h @@ -208,6 +208,7 @@ RT_API_ATTRS int CFI_select_part(CFI_cdesc_t *, const CFI_cdesc_t *source, size_t displacement, size_t elem_len); RT_API_ATTRS int CFI_setpointer( CFI_cdesc_t *, const CFI_cdesc_t *source, const CFI_index_t lower_bounds[]); +RT_API_ATTRS void CFI_show(void *buf, const CFI_cdesc_t *descr); #ifdef __cplusplus } // extern "C" #endif From 9994293742b8737faec20c5f134448fc7eb5e82a Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 2 Sep 2025 12:46:10 -0400 Subject: [PATCH 03/16] Only pass the descriptor arg to CFI_show() --- flang-rt/lib/runtime/ISO_Fortran_binding.cpp | 6 ++---- flang/include/flang/ISO_Fortran_binding.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/flang-rt/lib/runtime/ISO_Fortran_binding.cpp b/flang-rt/lib/runtime/ISO_Fortran_binding.cpp index 22d32155b915a..7a12453f058f9 100644 --- a/flang-rt/lib/runtime/ISO_Fortran_binding.cpp +++ b/flang-rt/lib/runtime/ISO_Fortran_binding.cpp @@ -297,11 +297,9 @@ RT_API_ATTRS int CFI_setpointer(CFI_cdesc_t *result, const CFI_cdesc_t *source, return CFI_SUCCESS; } -RT_API_ATTRS void CFI_show(void *buf, const CFI_cdesc_t *descr) { - FILE *f{stderr}; - std::fprintf(f, "%p CFI_desc_t: %p\n", buf, descr); +RT_API_ATTRS void CFI_show(const CFI_cdesc_t *descr) { if (descr) { - reinterpret_cast(descr)->Dump(f); + reinterpret_cast(descr)->Dump(stderr); } } diff --git a/flang/include/flang/ISO_Fortran_binding.h b/flang/include/flang/ISO_Fortran_binding.h index 4e2575ee9a622..ec95ac7aaa7d9 100644 --- a/flang/include/flang/ISO_Fortran_binding.h +++ b/flang/include/flang/ISO_Fortran_binding.h @@ -208,7 +208,7 @@ RT_API_ATTRS int CFI_select_part(CFI_cdesc_t *, const CFI_cdesc_t *source, size_t displacement, size_t elem_len); RT_API_ATTRS int CFI_setpointer( CFI_cdesc_t *, const CFI_cdesc_t *source, const CFI_index_t lower_bounds[]); -RT_API_ATTRS void CFI_show(void *buf, const CFI_cdesc_t *descr); +RT_API_ATTRS void CFI_show(const CFI_cdesc_t *descr); #ifdef __cplusplus } // extern "C" #endif From 6d15b2d76e4d9b7bf8594350b6ae97e591b65a2a Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 12:04:53 -0400 Subject: [PATCH 04/16] Allow allocatable/pointer association if ignore_tkr(p) is given --- flang/lib/Semantics/check-call.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp index c51d40b9e5039..cf1366d4a2354 100644 --- a/flang/lib/Semantics/check-call.cpp +++ b/flang/lib/Semantics/check-call.cpp @@ -929,7 +929,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy, dummy, actual, *scope, /*isAssumedRank=*/dummyIsAssumedRank, actualIsPointer); } - } else if (!actualIsPointer) { + } else if (!actualIsPointer && !dummy.ignoreTKR.test(common::IgnoreTKR::Pointer)) { messages.Say( "Actual argument associated with POINTER %s must also be POINTER unless INTENT(IN)"_err_en_US, dummyName); From fe2604e8cfc066d20e3aa1138ce34ffe65e76bbc Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 14:43:24 -0400 Subject: [PATCH 05/16] Tweaked the check --- flang/lib/Semantics/check-call.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp index cf1366d4a2354..824172ecc99c9 100644 --- a/flang/lib/Semantics/check-call.cpp +++ b/flang/lib/Semantics/check-call.cpp @@ -914,7 +914,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy, dummyName); } // INTENT(OUT) and INTENT(IN OUT) cases are caught elsewhere - } else { + } else if (!actualIsAllocatable && !dummy.ignoreTKR.test(common::IgnoreTKR::Pointer)) { messages.Say( "ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument"_err_en_US, dummyName); From 098414329fd9337c90f59222192cb02f570a061b Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 14:44:07 -0400 Subject: [PATCH 06/16] clang-format --- flang/lib/Semantics/check-call.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp index 824172ecc99c9..995deaa12dd3b 100644 --- a/flang/lib/Semantics/check-call.cpp +++ b/flang/lib/Semantics/check-call.cpp @@ -914,7 +914,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy, dummyName); } // INTENT(OUT) and INTENT(IN OUT) cases are caught elsewhere - } else if (!actualIsAllocatable && !dummy.ignoreTKR.test(common::IgnoreTKR::Pointer)) { + } else if (!actualIsAllocatable && + !dummy.ignoreTKR.test(common::IgnoreTKR::Pointer)) { messages.Say( "ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument"_err_en_US, dummyName); @@ -929,7 +930,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy, dummy, actual, *scope, /*isAssumedRank=*/dummyIsAssumedRank, actualIsPointer); } - } else if (!actualIsPointer && !dummy.ignoreTKR.test(common::IgnoreTKR::Pointer)) { + } else if (!actualIsPointer && + !dummy.ignoreTKR.test(common::IgnoreTKR::Pointer)) { messages.Say( "Actual argument associated with POINTER %s must also be POINTER unless INTENT(IN)"_err_en_US, dummyName); From 6733871caa9407d4a50677cccc84619f4dc7ff31 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 14:45:01 -0400 Subject: [PATCH 07/16] Revert "Only pass the descriptor arg to CFI_show()" This reverts commit 9994293742b8737faec20c5f134448fc7eb5e82a. --- flang-rt/lib/runtime/ISO_Fortran_binding.cpp | 6 ++++-- flang/include/flang/ISO_Fortran_binding.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/flang-rt/lib/runtime/ISO_Fortran_binding.cpp b/flang-rt/lib/runtime/ISO_Fortran_binding.cpp index 7a12453f058f9..22d32155b915a 100644 --- a/flang-rt/lib/runtime/ISO_Fortran_binding.cpp +++ b/flang-rt/lib/runtime/ISO_Fortran_binding.cpp @@ -297,9 +297,11 @@ RT_API_ATTRS int CFI_setpointer(CFI_cdesc_t *result, const CFI_cdesc_t *source, return CFI_SUCCESS; } -RT_API_ATTRS void CFI_show(const CFI_cdesc_t *descr) { +RT_API_ATTRS void CFI_show(void *buf, const CFI_cdesc_t *descr) { + FILE *f{stderr}; + std::fprintf(f, "%p CFI_desc_t: %p\n", buf, descr); if (descr) { - reinterpret_cast(descr)->Dump(stderr); + reinterpret_cast(descr)->Dump(f); } } diff --git a/flang/include/flang/ISO_Fortran_binding.h b/flang/include/flang/ISO_Fortran_binding.h index ec95ac7aaa7d9..4e2575ee9a622 100644 --- a/flang/include/flang/ISO_Fortran_binding.h +++ b/flang/include/flang/ISO_Fortran_binding.h @@ -208,7 +208,7 @@ RT_API_ATTRS int CFI_select_part(CFI_cdesc_t *, const CFI_cdesc_t *source, size_t displacement, size_t elem_len); RT_API_ATTRS int CFI_setpointer( CFI_cdesc_t *, const CFI_cdesc_t *source, const CFI_index_t lower_bounds[]); -RT_API_ATTRS void CFI_show(const CFI_cdesc_t *descr); +RT_API_ATTRS void CFI_show(void *buf, const CFI_cdesc_t *descr); #ifdef __cplusplus } // extern "C" #endif From ad5961e48a8e8b36fa9bb03f6cc6e65c4074a1be Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 14:45:23 -0400 Subject: [PATCH 08/16] Revert "[flang] Implement CFI_show()" This reverts commit 7294e688dd3aa2156311cd1ce086b249a3e570b6. --- flang-rt/lib/runtime/ISO_Fortran_binding.cpp | 8 -------- flang/include/flang/ISO_Fortran_binding.h | 1 - 2 files changed, 9 deletions(-) diff --git a/flang-rt/lib/runtime/ISO_Fortran_binding.cpp b/flang-rt/lib/runtime/ISO_Fortran_binding.cpp index 22d32155b915a..a5f8b357ae0b8 100644 --- a/flang-rt/lib/runtime/ISO_Fortran_binding.cpp +++ b/flang-rt/lib/runtime/ISO_Fortran_binding.cpp @@ -297,14 +297,6 @@ RT_API_ATTRS int CFI_setpointer(CFI_cdesc_t *result, const CFI_cdesc_t *source, return CFI_SUCCESS; } -RT_API_ATTRS void CFI_show(void *buf, const CFI_cdesc_t *descr) { - FILE *f{stderr}; - std::fprintf(f, "%p CFI_desc_t: %p\n", buf, descr); - if (descr) { - reinterpret_cast(descr)->Dump(f); - } -} - RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::ISO diff --git a/flang/include/flang/ISO_Fortran_binding.h b/flang/include/flang/ISO_Fortran_binding.h index 4e2575ee9a622..f5b8d0d2ea610 100644 --- a/flang/include/flang/ISO_Fortran_binding.h +++ b/flang/include/flang/ISO_Fortran_binding.h @@ -208,7 +208,6 @@ RT_API_ATTRS int CFI_select_part(CFI_cdesc_t *, const CFI_cdesc_t *source, size_t displacement, size_t elem_len); RT_API_ATTRS int CFI_setpointer( CFI_cdesc_t *, const CFI_cdesc_t *source, const CFI_index_t lower_bounds[]); -RT_API_ATTRS void CFI_show(void *buf, const CFI_cdesc_t *descr); #ifdef __cplusplus } // extern "C" #endif From d8782fc7a5a78ab379c195597a4080daf0c35a46 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 15:23:45 -0400 Subject: [PATCH 09/16] Disable ignore_tkr warning when 'p' is used --- flang/lib/Semantics/check-declarations.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index 549ee83b70fce..a3674a77d27af 100644 --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -949,7 +949,7 @@ void CheckHelper::CheckObjectEntity( "!DIR$ IGNORE_TKR(R) may not apply in an ELEMENTAL procedure"_err_en_US); } if (IsPassedViaDescriptor(symbol)) { - if (IsAllocatableOrObjectPointer(&symbol)) { + if (IsAllocatableOrObjectPointer(&symbol) && !ignoreTKR.test(common::IgnoreTKR::Pointer)) { if (inExplicitExternalInterface) { Warn(common::UsageWarning::IgnoreTKRUsage, "!DIR$ IGNORE_TKR should not apply to an allocatable or pointer"_warn_en_US); From acd95b9abeb8dc73d1f645695fd30ac7190c8ffd Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 15:24:05 -0400 Subject: [PATCH 10/16] clang-format --- flang/lib/Semantics/check-declarations.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index a3674a77d27af..de407d3b1e125 100644 --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -949,7 +949,8 @@ void CheckHelper::CheckObjectEntity( "!DIR$ IGNORE_TKR(R) may not apply in an ELEMENTAL procedure"_err_en_US); } if (IsPassedViaDescriptor(symbol)) { - if (IsAllocatableOrObjectPointer(&symbol) && !ignoreTKR.test(common::IgnoreTKR::Pointer)) { + if (IsAllocatableOrObjectPointer(&symbol) && + !ignoreTKR.test(common::IgnoreTKR::Pointer)) { if (inExplicitExternalInterface) { Warn(common::UsageWarning::IgnoreTKRUsage, "!DIR$ IGNORE_TKR should not apply to an allocatable or pointer"_warn_en_US); From b1e54c097d04bd4fff7cbd55d35efe8e532e7bce Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 15:30:08 -0400 Subject: [PATCH 11/16] LIT test --- flang/test/Semantics/ignore_tkr04.f90 | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 flang/test/Semantics/ignore_tkr04.f90 diff --git a/flang/test/Semantics/ignore_tkr04.f90 b/flang/test/Semantics/ignore_tkr04.f90 new file mode 100644 index 0000000000000..4087125d75494 --- /dev/null +++ b/flang/test/Semantics/ignore_tkr04.f90 @@ -0,0 +1,26 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! Tests for ignore_tkr(p) +module ignore_tkr_4_m +interface + subroutine s(a) + real, pointer :: a(:) +!dir$ ignore_tkr(p) a +!CHECK-NOT: error +!CHECK-NOT: warning + end subroutine + subroutine s1(a) + real, allocatable :: a(:) +!dir$ ignore_tkr(p) a +!CHECK-NOT: error +!CHECK-NOT: warning + end subroutine +end interface +end module +program t + use ignore_tkr_4_m + real, allocatable :: x(:) + real, pointer :: x1(:) + call s(x) + call s1(x1) +end + From b2701e5a424f1906b1be4b25c67f9fa7211a1768 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 15:38:13 -0400 Subject: [PATCH 12/16] Docs update for ignore_tkr(p) --- flang/docs/Directives.md | 48 +++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/flang/docs/Directives.md b/flang/docs/Directives.md index 3ebb08c486228..adedf3e2a706e 100644 --- a/flang/docs/Directives.md +++ b/flang/docs/Directives.md @@ -1,9 +1,9 @@ - # Compiler directives supported by Flang @@ -12,16 +12,18 @@ A list of non-standard directives supported by Flang * `!dir$ fixed` and `!dir$ free` select Fortran source forms. Their effect persists to the end of the current source file. -* `!dir$ ignore_tkr [[(TKRDMAC)] dummy-arg-name]...` in an interface definition +* `!dir$ ignore_tkr [[(TKRDMACP)] dummy-arg-name]...` in an interface definition disables some semantic checks at call sites for the actual arguments that - correspond to some named dummy arguments (or all of them, by default). - The directive allow actual arguments that would otherwise be diagnosed - as incompatible in type (T), kind (K), rank (R), CUDA device (D), or - managed (M) status. The letter (A) is a shorthand for all of these, - and is the default when no letters appear. The letter (C) checks for - contiguity for example allowing an element of an assumed-shape array to be - passed as a dummy argument. For example, if one wanted to call a "set all - bytes to zero" utility that could be applied to arrays of any type or rank: + correspond to some named dummy arguments (or all of them, by default). The + directive allow actual arguments that would otherwise be diagnosed as + incompatible in type (T), kind (K), rank (R), CUDA device (D), or managed (M) + status. The letter (A) is a shorthand for (TKRDM), and is the default when no + letters appear. The letter (C) checks for contiguity for example allowing an + element of an assumed-shape array to be passed as a dummy argument. The + letter (P) ignores pointer and allocatable matching, so that one can pass an + allocatable array to routine with pointer array argument and vice-versa. For + example, if one wanted to call a "set all bytes to zero" utility that could + be applied to arrays of any type or rank: ``` interface subroutine clear(arr,bytes) @@ -46,27 +48,27 @@ A list of non-standard directives supported by Flang unroll the loop. Some compilers accept an optional `=` before the `n` when `n` is present in the directive. Flang does not. * `!dir$ unroll_and_jam [N]` control how many times a loop should be unrolled and - jammed. It must be placed immediately before a loop that follows. `N` is an optional - integer that specifying the unrolling factor. When `N` is `0` or `1`, the loop + jammed. It must be placed immediately before a loop that follows. `N` is an optional + integer that specifying the unrolling factor. When `N` is `0` or `1`, the loop should not be unrolled at all. If `N` is omitted the optimizer will selects the number of times to unroll the loop. * `!dir$ novector` disabling vectorization on the following loop. * `!dir$ nounroll` disabling unrolling on the following loop. * `!dir$ nounroll_and_jam` disabling unrolling and jamming on the following loop. -* `!dir$ inline` instructs the compiler to attempt to inline the called routines if the - directive is specified before a call statement or all call statements within the loop - body if specified before a DO LOOP or all function references if specified before an +* `!dir$ inline` instructs the compiler to attempt to inline the called routines if the + directive is specified before a call statement or all call statements within the loop + body if specified before a DO LOOP or all function references if specified before an assignment statement. -* `!dir$ forceinline` works in the same way as the `inline` directive, but it forces +* `!dir$ forceinline` works in the same way as the `inline` directive, but it forces inlining by the compiler on a function call statement. -* `!dir$ noinline` works in the same way as the `inline` directive, but prevents +* `!dir$ noinline` works in the same way as the `inline` directive, but prevents any attempt of inlining by the compiler on a function call statement. # Directive Details ## Introduction -Directives are commonly used in Fortran programs to specify additional actions -to be performed by the compiler. The directives are always specified with the +Directives are commonly used in Fortran programs to specify additional actions +to be performed by the compiler. The directives are always specified with the `!dir$` or `cdir$` prefix. ## Loop Directives @@ -97,7 +99,7 @@ check that that construct matches the expected construct for the directive. Skipping other intermediate directives allows multiple directives to appear on the same construct. -## Lowering +## Lowering Evaluation is extended with a new field called dirs for representing directives associated with that Evaluation. When lowering loop directives, the associated Do Loop's evaluation is found and the directive is added to it. This information @@ -109,7 +111,7 @@ about the loop. For example, the `llvm.loop.vectorize.enable` metadata informs the optimizer that a loop can be vectorized without considering its cost-model. This attribute is added to the loop condition branch. -### Representation in MLIR +### Representation in MLIR The MLIR LLVM dialect models this by an attribute called LoopAnnotation Attribute. The attribute can be added to the latch of the loop in the cf dialect and is then carried through lowering to the LLVM dialect. From a4f30b01b17b80f437b5d1d8c8d3b42ee7124e11 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 15:49:54 -0400 Subject: [PATCH 13/16] Changed error checks in LIT test --- flang/test/Semantics/ignore_tkr04.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flang/test/Semantics/ignore_tkr04.f90 b/flang/test/Semantics/ignore_tkr04.f90 index 4087125d75494..8becc85857bb1 100644 --- a/flang/test/Semantics/ignore_tkr04.f90 +++ b/flang/test/Semantics/ignore_tkr04.f90 @@ -5,14 +5,10 @@ module ignore_tkr_4_m subroutine s(a) real, pointer :: a(:) !dir$ ignore_tkr(p) a -!CHECK-NOT: error -!CHECK-NOT: warning end subroutine subroutine s1(a) real, allocatable :: a(:) !dir$ ignore_tkr(p) a -!CHECK-NOT: error -!CHECK-NOT: warning end subroutine end interface end module @@ -21,6 +17,10 @@ program t real, allocatable :: x(:) real, pointer :: x1(:) call s(x) +!CHECK-NOT: error +!CHECK-NOT: warning call s1(x1) +!CHECK-NOT: error +!CHECK-NOT: warning end From 5c923d04d214fb9e4dbab79bb7f66b9018c797af Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 15:57:35 -0400 Subject: [PATCH 14/16] upstream code formatter had other ideas :-( --- flang/include/flang/Support/Fortran.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flang/include/flang/Support/Fortran.h b/flang/include/flang/Support/Fortran.h index 1c8a118dd44e7..cf39781c1e8a7 100644 --- a/flang/include/flang/Support/Fortran.h +++ b/flang/include/flang/Support/Fortran.h @@ -81,14 +81,14 @@ static constexpr int maxNameLen{63}; // !DIR$ IGNORE_TKR [[(letters) name] ... letters // "A" expands to all of TKRDM ENUM_CLASS(IgnoreTKR, - Type, // T - don't check type category - Kind, // K - don't check kind - Rank, // R - don't check ranks - Device, // D - don't check host/device residence - Managed, // M - don't check managed storage + Type, // T - don't check type category + Kind, // K - don't check kind + Rank, // R - don't check ranks + Device, // D - don't check host/device residence + Managed, // M - don't check managed storage Contiguous, // C - don't check for storage sequence association with a // potentially non-contiguous object - Pointer) // P - ignore pointer and allocatable matching + Pointer) // P - ignore pointer and allocatable matching using IgnoreTKRSet = EnumSet; // IGNORE_TKR(A) = IGNORE_TKR(TKRDM) static constexpr IgnoreTKRSet ignoreTKRAll{IgnoreTKR::Type, IgnoreTKR::Kind, From 3289595fd6fae258365ddb261ffde70834453aad Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 16:16:06 -0400 Subject: [PATCH 15/16] Added missing break --- flang/lib/Semantics/mod-file.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index 732be56b905dd..b419864f73b8e 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -1020,6 +1020,7 @@ void ModFileWriter::PutObjectEntity( break; case common::IgnoreTKR::Contiguous: os << 'c'; + break; case common::IgnoreTKR::Pointer: os << 'p'; break; From 43e24ff8ac4bdd98601c580fbdeb2df620f33fd5 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 28 Oct 2025 21:28:16 -0400 Subject: [PATCH 16/16] Code review feedback --- flang/docs/Directives.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/docs/Directives.md b/flang/docs/Directives.md index adedf3e2a706e..2f16a8d579f8b 100644 --- a/flang/docs/Directives.md +++ b/flang/docs/Directives.md @@ -18,10 +18,10 @@ A list of non-standard directives supported by Flang directive allow actual arguments that would otherwise be diagnosed as incompatible in type (T), kind (K), rank (R), CUDA device (D), or managed (M) status. The letter (A) is a shorthand for (TKRDM), and is the default when no - letters appear. The letter (C) checks for contiguity for example allowing an + letters appear. The letter (C) checks for contiguity, for example allowing an element of an assumed-shape array to be passed as a dummy argument. The letter (P) ignores pointer and allocatable matching, so that one can pass an - allocatable array to routine with pointer array argument and vice-versa. For + allocatable array to routine with pointer array argument and vice versa. For example, if one wanted to call a "set all bytes to zero" utility that could be applied to arrays of any type or rank: ```