Skip to content

Commit aa99192

Browse files
authored
[flang][OpenMP] Add TODO messages for partially implemented atomic types (#99817)
There is ongoing work for fir.complex but this looks unlikely to land before the LLVM branch. Adding a TODO message gives cleaner output to users. Currently fir.complex leads to a compiler assertion failure. Some uses of character types lead to invalid fir.convert type conversions, others make it far enough to hit the same assertion failure as for fir.complex.
1 parent cb528e5 commit aa99192

File tree

4 files changed

+51
-16
lines changed

4 files changed

+51
-16
lines changed

flang/lib/Lower/DirectivesCommon.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "flang/Optimizer/Builder/FIRBuilder.h"
3434
#include "flang/Optimizer/Builder/HLFIRTools.h"
3535
#include "flang/Optimizer/Builder/Todo.h"
36+
#include "flang/Optimizer/Dialect/FIRType.h"
3637
#include "flang/Optimizer/HLFIR/HLFIROps.h"
3738
#include "flang/Parser/parse-tree.h"
3839
#include "flang/Semantics/openmp-directive-sets.h"
@@ -135,6 +136,22 @@ static inline void genOmpAtomicHintAndMemoryOrderClauses(
135136
}
136137
}
137138

139+
template <typename AtomicListT>
140+
static void processOmpAtomicTODO(mlir::Type elementType, mlir::Location loc) {
141+
if (!elementType)
142+
return;
143+
if constexpr (std::is_same<AtomicListT,
144+
Fortran::parser::OmpAtomicClauseList>()) {
145+
// Based on assertion for supported element types in OMPIRBuilder.cpp
146+
// createAtomicRead
147+
mlir::Type unwrappedEleTy = fir::unwrapRefType(elementType);
148+
bool supportedAtomicType =
149+
(!fir::isa_complex(unwrappedEleTy) && fir::isa_trivial(unwrappedEleTy));
150+
if (!supportedAtomicType)
151+
TODO(loc, "Unsupported atomic type");
152+
}
153+
}
154+
138155
/// Used to generate atomic.read operation which is created in existing
139156
/// location set by builder.
140157
template <typename AtomicListT>
@@ -147,6 +164,8 @@ static inline void genOmpAccAtomicCaptureStatement(
147164
// Generate `atomic.read` operation for atomic assigment statements
148165
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
149166

167+
processOmpAtomicTODO<AtomicListT>(elementType, loc);
168+
150169
if constexpr (std::is_same<AtomicListT,
151170
Fortran::parser::OmpAtomicClauseList>()) {
152171
// If no hint clause is specified, the effect is as if
@@ -183,6 +202,8 @@ static inline void genOmpAccAtomicWriteStatement(
183202
mlir::Type varType = fir::unwrapRefType(lhsAddr.getType());
184203
rhsExpr = firOpBuilder.createConvert(loc, varType, rhsExpr);
185204

205+
processOmpAtomicTODO<AtomicListT>(varType, loc);
206+
186207
if constexpr (std::is_same<AtomicListT,
187208
Fortran::parser::OmpAtomicClauseList>()) {
188209
// If no hint clause is specified, the effect is as if
@@ -323,6 +344,8 @@ static inline void genOmpAccAtomicUpdateStatement(
323344
currentLocation, lhsAddr);
324345
}
325346

347+
processOmpAtomicTODO<AtomicListT>(varType, loc);
348+
326349
llvm::SmallVector<mlir::Type> varTys = {varType};
327350
llvm::SmallVector<mlir::Location> locs = {currentLocation};
328351
firOpBuilder.createBlock(&atomicUpdateOp->getRegion(0), {}, varTys, locs);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
2+
3+
! CHECK: not yet implemented: Unsupported atomic type
4+
subroutine character_atomic
5+
character :: l, r
6+
!$omp atomic read
7+
l = r
8+
end subroutine
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
2+
3+
! CHECK: not yet implemented: Unsupported atomic type
4+
subroutine complex_atomic
5+
complex :: l, r
6+
!$omp atomic read
7+
l = r
8+
end subroutine

flang/test/Lower/OpenMP/atomic-read.f90

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,18 @@
55
! This test checks the lowering of atomic read
66

77
!CHECK: func @_QQmain() attributes {fir.bindc_name = "ompatomic"} {
8-
!CHECK: %[[A_C1:.*]] = arith.constant 1 : index
9-
!CHECK: %[[A_REF:.*]] = fir.alloca !fir.char<1> {bindc_name = "a", uniq_name = "_QFEa"}
10-
!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A_REF]] typeparams %[[A_C1]] {uniq_name = "_QFEa"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
11-
!CHECK: %[[B_C1:.*]] = arith.constant 1 : index
12-
!CHECK: %[[B_REF:.*]] = fir.alloca !fir.char<1> {bindc_name = "b", uniq_name = "_QFEb"}
13-
!CHECK: %[[B_DECL:.*]]:2 = hlfir.declare %[[B_REF]] typeparams %[[B_C1]] {uniq_name = "_QFEb"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
8+
!CHECK: %[[A_REF:.*]] = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFEa"}
9+
!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A_REF]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
10+
!CHECK: %[[B_REF:.*]] = fir.alloca i32 {bindc_name = "b", uniq_name = "_QFEb"}
11+
!CHECK: %[[B_DECL:.*]]:2 = hlfir.declare %[[B_REF]] {uniq_name = "_QFEb"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
1412
!CHECK: %[[C_REF:.*]] = fir.alloca !fir.logical<4> {bindc_name = "c", uniq_name = "_QFEc"}
1513
!CHECK: %[[C_DECL:.*]]:2 = hlfir.declare %[[C_REF]] {uniq_name = "_QFEc"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
1614
!CHECK: %[[D_REF:.*]] = fir.alloca !fir.logical<4> {bindc_name = "d", uniq_name = "_QFEd"}
1715
!CHECK: %[[D_DECL:.*]]:2 = hlfir.declare %[[D_REF]] {uniq_name = "_QFEd"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
18-
!CHECK: %[[E_C8:.*]] = arith.constant 8 : index
19-
!CHECK: %[[E_REF:.*]] = fir.alloca !fir.char<1,8> {bindc_name = "e", uniq_name = "_QFEe"}
20-
!CHECK: %[[E_DECL:.*]]:2 = hlfir.declare %[[E_REF]] typeparams %[[E_C8]] {uniq_name = "_QFEe"} : (!fir.ref<!fir.char<1,8>>, index) -> (!fir.ref<!fir.char<1,8>>, !fir.ref<!fir.char<1,8>>)
21-
!CHECK: %[[F_C8:.*]] = arith.constant 8 : index
22-
!CHECK: %[[F_REF:.*]] = fir.alloca !fir.char<1,8> {bindc_name = "f", uniq_name = "_QFEf"}
23-
!CHECK: %[[F_DECL:.*]]:2 = hlfir.declare %[[F_REF]] typeparams %[[F_C8]] {uniq_name = "_QFEf"} : (!fir.ref<!fir.char<1,8>>, index) -> (!fir.ref<!fir.char<1,8>>, !fir.ref<!fir.char<1,8>>)
16+
!CHECK: %[[E_REF:.*]] = fir.alloca i32 {bindc_name = "e", uniq_name = "_QFEe"}
17+
!CHECK: %[[E_DECL:.*]]:2 = hlfir.declare %[[E_REF]] {uniq_name = "_QFEe"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
18+
!CHECK: %[[F_REF:.*]] = fir.alloca i32 {bindc_name = "f", uniq_name = "_QFEf"}
19+
!CHECK: %[[F_DECL:.*]]:2 = hlfir.declare %[[F_REF]] {uniq_name = "_QFEf"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
2420
!CHECK: %[[G_REF:.*]] = fir.alloca f32 {bindc_name = "g", uniq_name = "_QFEg"}
2521
!CHECK: %[[G_DECL:.*]]:2 = hlfir.declare %[[G_REF]] {uniq_name = "_QFEg"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
2622
!CHECK: %[[H_REF:.*]] = fir.alloca f32 {bindc_name = "h", uniq_name = "_QFEh"}
@@ -30,19 +26,19 @@
3026
!CHECK: %[[Y_REF:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"}
3127
!CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y_REF]] {uniq_name = "_QFEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
3228
!CHECK: omp.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 memory_order(acquire) hint(uncontended) : !fir.ref<i32>, i32
33-
!CHECK: omp.atomic.read %[[A_DECL]]#1 = %[[B_DECL]]#1 memory_order(relaxed) : !fir.ref<!fir.char<1>>, !fir.char<1>
29+
!CHECK: omp.atomic.read %[[A_DECL]]#1 = %[[B_DECL]]#1 memory_order(relaxed) : !fir.ref<i32>, i32
3430
!CHECK: omp.atomic.read %[[C_DECL]]#1 = %[[D_DECL]]#1 memory_order(seq_cst) hint(contended) : !fir.ref<!fir.logical<4>>, !fir.logical<4>
35-
!CHECK: omp.atomic.read %[[E_DECL]]#1 = %[[F_DECL]]#1 hint(speculative) : !fir.ref<!fir.char<1,8>>, !fir.char<1,8>
31+
!CHECK: omp.atomic.read %[[E_DECL]]#1 = %[[F_DECL]]#1 hint(speculative) : !fir.ref<i32>, i32
3632
!CHECK: omp.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 hint(nonspeculative) : !fir.ref<f32>, f32
3733
!CHECK: omp.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 : !fir.ref<f32>, f32
3834

3935
program OmpAtomic
4036

4137
use omp_lib
4238
integer :: x, y
43-
character :: a, b
39+
integer :: a, b
4440
logical :: c, d
45-
character(8) :: e, f
41+
integer :: e, f
4642
real g, h
4743
!$omp atomic acquire read hint(omp_sync_hint_uncontended)
4844
x = y

0 commit comments

Comments
 (0)