[flang-commits] [flang] [flang] Correct OutputAscii memory-effects attribute (PR #227485)
via flang-commits
flang-commits at lists.llvm.org
Tue Sep 29 14:48:46 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: nvptm
<details>
<summary>Changes</summary>
`OutputAscii` accesses mutable I/O state through pointers loaded from its opaque cookie. The generic memory-effects attribute incorrectly marked it as not accessing other memory, allowing stale I/O state to be reused across consecutive calls.
Add an `OutputAscii` specialization that marks other memory as readwrite, and update the attribute test.
Other I/O entry points accept the same opaque cookie and may require similar
memory effects, including `OutputInteger*`, `OutputReal*`, `OutputComplex*`,
`OutputLogical`, `OutputCharacter`, `EndIoStatement`, and the corresponding
input routines.
This patch is limited to `OutputAscii`, for which there is a reduced executable
reproducer and verified memory behavior. The remaining cookie-taking routines
should be reviewed separately because their precise memory effects may differ.
---
Full diff: https://github.com/llvm/llvm-project/pull/227485.diff
2 Files Affected:
- (modified) flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp (+17)
- (modified) flang/test/Transforms/set-runtime-call-attributes.fir (+1-1)
``````````diff
diff --git a/flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp b/flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp
index 1891bb9c3bcce..32861a053877a 100644
--- a/flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp
+++ b/flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp
@@ -118,6 +118,23 @@ struct MemoryAttrDesc {
return getGenericMemoryAttr(callOp);
}
};
+
+// OutputAscii accesses I/O state through pointers loaded from its opaque
+// cookie. That state is not based directly on a call argument, so it must be
+// represented as "other" memory rather than only argument memory.
+template <>
+struct MemoryAttrDesc<mkIOKey(OutputAscii)> {
+ static mlir::LLVM::MemoryEffectsAttr get(fir::CallOp callOp) {
+ return mlir::LLVM::MemoryEffectsAttr::get(
+ callOp->getContext(),
+ {/*other=*/mlir::LLVM::ModRefInfo::ModRef,
+ /*argMem=*/mlir::LLVM::ModRefInfo::ModRef,
+ /*inaccessibleMem=*/mlir::LLVM::ModRefInfo::ModRef,
+ /*errnoMem=*/mlir::LLVM::ModRefInfo::NoModRef,
+ /*targetMem0=*/mlir::LLVM::ModRefInfo::NoModRef,
+ /*targetMem1=*/mlir::LLVM::ModRefInfo::NoModRef});
+ }
+};
} // end anonymous namespace
// NosyncAttrDesc type provides get() method for computing
diff --git a/flang/test/Transforms/set-runtime-call-attributes.fir b/flang/test/Transforms/set-runtime-call-attributes.fir
index c3d6e4dd5797f..fb3349f7c989a 100644
--- a/flang/test/Transforms/set-runtime-call-attributes.fir
+++ b/flang/test/Transforms/set-runtime-call-attributes.fir
@@ -596,7 +596,7 @@ module {
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<i8>,
// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<i8>,
// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 {
-// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioOutputAscii(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects<other = none, argMem = readwrite, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>, llvm.nocallback, llvm.nosync} : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
+// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioOutputAscii(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects<other = readwrite, argMem = readwrite, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>, llvm.nocallback, llvm.nosync} : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
// CHECK: return %[[VAL_3]] : i1
// CHECK: }
func.func @test__FortranAioOutputAscii(%arg0: !fir.ref<i8>, %arg1: !fir.ref<i8>, %arg2: i64) -> i1 {
``````````
</details>
https://github.com/llvm/llvm-project/pull/227485
More information about the flang-commits
mailing list