-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[flang][OpenMP] Remove ineffective atomic capture validation (issue #161934 deferred) #162884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-openmp Author: Krish Gupta (KrxGu) ChangesProblem:The Flang frontend's semantic analysis can produce invalid operation sequences for OpenMP atomic capture constructs. Specifically, it may generate a WRITE→READ sequence instead of the valid READ→UPDATE or UPDATE→WRITE sequences required by the OpenMP specification. When this invalid sequence reaches the MLIR lowering stage, verification fails with a cryptic error message and the compiler crashes. Example that triggers the bug: type :: t
integer :: a(10)
end type
type(t) :: x, y
!$omp atomic capture
x%a(i) = y%a(i)
v = y%a(i)
!$omp end atomic capture Solution: This prevents the crash and provides actionable feedback to users or downstream bug reporters. Changes: Both tests pass, confirming the diagnostic is emitted for invalid sequences while valid constructs compile successfully. Full diff: https://github.com/llvm/llvm-project/pull/162884.diff 3 Files Affected:
diff --git a/flang/lib/Lower/OpenMP/Atomic.cpp b/flang/lib/Lower/OpenMP/Atomic.cpp
index ff82a36951bfa..48016b5c21ab8 100644
--- a/flang/lib/Lower/OpenMP/Atomic.cpp
+++ b/flang/lib/Lower/OpenMP/Atomic.cpp
@@ -19,6 +19,7 @@
#include "flang/Lower/SymbolMap.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/semantics.h"
#include "flang/Semantics/type.h"
@@ -459,6 +460,23 @@ void Fortran::lower::omp::lowerAtomic(
} else {
int action0 = analysis.op0.what & analysis.Action;
int action1 = analysis.op1.what & analysis.Action;
+
+ // Check for invalid atomic capture sequence.
+ // Valid sequences: (READ, UPDATE) or (UPDATE, WRITE)
+ if (construct.IsCapture()) {
+ using Action = parser::OpenMPAtomicConstruct::Analysis;
+ const bool validSequence =
+ (action0 == Action::Read && action1 == Action::Update) ||
+ (action0 == Action::Update && action1 == Action::Write);
+
+ if (!validSequence) {
+ mlir::emitError(loc,
+ "OpenMP atomic capture produced an invalid operation "
+ "sequence (expected read+update or update+write)");
+ return;
+ }
+ }
+
mlir::Operation *captureOp = nullptr;
fir::FirOpBuilder::InsertPoint preAt = builder.saveInsertionPoint();
fir::FirOpBuilder::InsertPoint atomicAt, postAt;
diff --git a/flang/test/Lower/OpenMP/atomic-capture-derived-array-diag.f90 b/flang/test/Lower/OpenMP/atomic-capture-derived-array-diag.f90
new file mode 100644
index 0000000000000..d22126c04005d
--- /dev/null
+++ b/flang/test/Lower/OpenMP/atomic-capture-derived-array-diag.f90
@@ -0,0 +1,24 @@
+! Test diagnostic for atomic capture with invalid operation sequence
+! RUN: not %flang_fc1 -emit-fir -fopenmp %s 2>&1 | FileCheck %s
+
+! This test verifies that a clear diagnostic is emitted when atomic capture
+! produces an invalid operation sequence. This can occur with derived-type
+! component array elements where different indices are used.
+
+program test_atomic_capture_invalid_sequence
+ type t1
+ integer :: i(1)
+ end type
+ type(t1) :: t2
+ integer :: j
+
+ t2%i = 0
+ j = 1
+
+ ! CHECK: error: OpenMP atomic capture produced an invalid operation sequence
+ !$omp atomic capture
+ t2%i(j*1) = t2%i(1) + 1
+ t2%i(1) = t2%i(j*1)
+ !$omp end atomic
+
+end program test_atomic_capture_invalid_sequence
diff --git a/flang/test/Lower/OpenMP/atomic-capture-same-element.f90 b/flang/test/Lower/OpenMP/atomic-capture-same-element.f90
new file mode 100644
index 0000000000000..208a2db362369
--- /dev/null
+++ b/flang/test/Lower/OpenMP/atomic-capture-same-element.f90
@@ -0,0 +1,21 @@
+! Test that atomic capture works correctly with same element (positive control)
+! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
+
+! This test verifies that atomic capture with the same array element in both
+! statements works correctly and doesn't trigger the invalid sequence diagnostic.
+
+! CHECK-LABEL: func @_QQmain
+program test_atomic_capture_same_element
+ integer :: a(10)
+ integer :: v
+
+ a = 0
+
+ ! This should work - same element a(1) in both statements
+ ! CHECK: omp.atomic.capture
+ !$omp atomic capture
+ v = a(1)
+ a(1) = a(1) + 1
+ !$omp end atomic
+
+end program test_atomic_capture_same_element
|
066ad69
to
6109921
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
OpenMP atomic capture allows four operation pairs in any order: READ+UPDATE, UPDATE+READ, READ+WRITE, UPDATE+WRITE. Previous code only allowed READ+UPDATE and UPDATE+WRITE, causing CI failures on existing tests. Fixes llvm#161934
6109921
to
a9f7208
Compare
Update: Fixed CI Failures Changes:
All existing tests now pass. Issue #161934 still fails appropriately with verifier error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not clear what is fixed in this patch.
-> There is already an error generated for the example in the summary.
type :: t
integer :: a(10)
end type
type(t) :: x, y
!$omp atomic capture
x%a(i) = y%a(i)
v = y%a(i)
!$omp end atomic capture
-> The issue in #161934 does not seem to be fixed.
flang/lib/Lower/OpenMP/Atomic.cpp
Outdated
mlir::emitError(loc, "OpenMP atomic capture requires one read and one " | ||
"write/update operation"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no test for this error.
Is this not already caught in Semantics? If not, why wasn't this code included in Semantics?
- Removed redundant lowering-layer check in Atomic.cpp per review feedback - Added semantic layer placeholder for issue llvm#161934 (not yet implemented) - Full semantic check deferred due to complexity of Flang expression traversal The MLIR verification layer continues to catch these cases as a safety net.
Thank you for the feedback on the previous approach. You were right that the lowering check was ineffective. I've attempted to implement the semantic check you suggested, but after 4+ different approaches, I've hit my knowledge limits with Flang's expression system. The complexity is beyond what I initially expected. This updated PR:
The MLIR verification still catches these cases at runtime. If you think this partial cleanup isn't worth merging, I'm happy to close the PR. Otherwise, the infrastructure is in place for someone with deeper Flang internals knowledge to complete it. What do you think is the best path forward? |
Summary
This PR addresses reviewer feedback that the previous lowering-layer validation was ineffective and removes that code. It also adds semantic layer infrastructure for a proper fix to issue #161934, though the full implementation is deferred due to complexity.
Changes
1. Removed Ineffective Lowering Check (
Atomic.cpp
)2. Added Semantic Layer Infrastructure (
check-omp-atomic.cpp
)checkSameAtomicLocation()
placeholder lambda inCheckUpdateCapture()
3. Removed Test Files
Why Not Fully Implemented?
I attempted multiple approaches to implement the semantic check but encountered significant complexity:
t2%i(1) + 1
Full implementation requires deep expertise in Flang's
evaluate
namespace and expression representation system (estimated 150-200 LOC).Safety Net
The MLIR verification layer continues to catch issue #161934 cases at runtime, so this doesn't introduce silent failures. A semantic check would provide better error messages earlier but requires specialized knowledge.
Next Steps
Seeking feedback from reviewers:
The placeholder includes clear documentation for future implementers.
Related Issue
Fixes (partially): #161934