Skip to content

Commit 5415152

Browse files
committed
[flang][llvm][OpenMP][OpenACC] Add implicit casts to omp.atomic and acc.atomic
1 parent 1e1781b commit 5415152

File tree

5 files changed

+217
-42
lines changed

5 files changed

+217
-42
lines changed

flang/include/flang/Lower/DirectivesCommon.h

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "flang/Lower/PFTBuilder.h"
3030
#include "flang/Lower/StatementContext.h"
3131
#include "flang/Lower/Support/Utils.h"
32+
#include "flang/Optimizer/Builder/Complex.h"
3233
#include "flang/Optimizer/Builder/DirectivesCommon.h"
3334
#include "flang/Optimizer/Builder/HLFIRTools.h"
3435
#include "flang/Optimizer/Dialect/FIRType.h"
@@ -103,6 +104,61 @@ static void processOmpAtomicTODO(mlir::Type elementType,
103104
}
104105
}
105106

107+
/// Emits an implicit cast for atomic statements
108+
static void emitImplicitCast(Fortran::lower::AbstractConverter &converter,
109+
mlir::Location loc, mlir::Value &fromAddress,
110+
mlir::Value &toAddress, mlir::Type &elementType) {
111+
if (fromAddress.getType() == toAddress.getType())
112+
return;
113+
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
114+
mlir::Value alloca = builder.create<fir::AllocaOp>(
115+
loc, fir::unwrapRefType(toAddress.getType()));
116+
mlir::Value loadedVal = builder.create<fir::LoadOp>(loc, fromAddress);
117+
mlir::Type toType = fir::unwrapRefType(toAddress.getType());
118+
mlir::Type fromType = fir::unwrapRefType(fromAddress.getType());
119+
if (!fir::isa_complex(toType) && !fir::isa_complex(fromType)) {
120+
loadedVal = builder.create<fir::ConvertOp>(
121+
loc, fir::unwrapRefType(toAddress.getType()), loadedVal);
122+
builder.create<fir::StoreOp>(loc, loadedVal, alloca);
123+
} else if (!fir::isa_complex(toType) && fir::isa_complex(fromType)) {
124+
loadedVal = builder.create<fir::ExtractValueOp>(
125+
loc, mlir::cast<mlir::ComplexType>(fromType).getElementType(),
126+
loadedVal,
127+
builder.getArrayAttr(
128+
builder.getIntegerAttr(builder.getIndexType(), 0)));
129+
loadedVal = builder.create<fir::ConvertOp>(loc, toType, loadedVal);
130+
builder.create<fir::StoreOp>(loc, loadedVal, alloca);
131+
} else if (fir::isa_complex(toType) && fir::isa_complex(fromType)) {
132+
mlir::Value firstComp = builder.create<fir::ExtractValueOp>(
133+
loc, mlir::cast<mlir::ComplexType>(fromType).getElementType(),
134+
loadedVal,
135+
builder.getArrayAttr(
136+
builder.getIntegerAttr(builder.getIndexType(), 0)));
137+
mlir::Value secondComp = builder.create<fir::ExtractValueOp>(
138+
loc, mlir::cast<mlir::ComplexType>(fromType).getElementType(),
139+
loadedVal,
140+
builder.getArrayAttr(
141+
builder.getIntegerAttr(builder.getIndexType(), 1)));
142+
firstComp = builder.create<fir::ConvertOp>(
143+
loc, mlir::cast<mlir::ComplexType>(toType).getElementType(), firstComp);
144+
secondComp = builder.create<fir::ConvertOp>(
145+
loc, mlir::cast<mlir::ComplexType>(toType).getElementType(),
146+
secondComp);
147+
auto undef = builder.create<fir::UndefOp>(loc, toType);
148+
mlir::Value pair1 = builder.create<fir::InsertValueOp>(
149+
loc, toType, undef, firstComp,
150+
builder.getArrayAttr(
151+
builder.getIntegerAttr(builder.getIndexType(), 0)));
152+
mlir::Value pair = builder.create<fir::InsertValueOp>(
153+
loc, toType, pair1, secondComp,
154+
builder.getArrayAttr(
155+
builder.getIntegerAttr(builder.getIndexType(), 1)));
156+
builder.create<fir::StoreOp>(loc, pair, alloca);
157+
}
158+
fromAddress = alloca;
159+
elementType = fir::unwrapRefType(toAddress.getType());
160+
}
161+
106162
/// Used to generate atomic.read operation which is created in existing
107163
/// location set by builder.
108164
template <typename AtomicListT>
@@ -386,6 +442,7 @@ void genOmpAccAtomicRead(Fortran::lower::AbstractConverter &converter,
386442
fir::getBase(converter.genExprAddr(fromExpr, stmtCtx));
387443
mlir::Value toAddress = fir::getBase(converter.genExprAddr(
388444
*Fortran::semantics::GetExpr(assignmentStmtVariable), stmtCtx));
445+
emitImplicitCast(converter, loc, fromAddress, toAddress, elementType);
389446
genOmpAccAtomicCaptureStatement(converter, fromAddress, toAddress,
390447
leftHandClauseList, rightHandClauseList,
391448
elementType, loc);
@@ -481,6 +538,30 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
481538
mlir::Type stmt2VarType =
482539
fir::getBase(converter.genExprValue(assign2.lhs, stmtCtx)).getType();
483540

541+
// Checks helpful in constructing the `atomic.capture` region
542+
bool hasSingleVariable =
543+
Fortran::semantics::checkForSingleVariableOnRHS(stmt1);
544+
bool hasSymMatch = Fortran::semantics::checkForSymbolMatch(stmt2);
545+
546+
// Implicit casts
547+
mlir::Type captureStmtElemTy;
548+
if (hasSingleVariable) {
549+
if (hasSymMatch) {
550+
// Atomic capture construct is of the form [capture-stmt, update-stmt]
551+
// FIXME: Emit an implicit cast if there is a type mismatch
552+
} else {
553+
// Atomic capture construct is of the form [capture-stmt, write-stmt]
554+
const Fortran::semantics::SomeExpr &fromExpr =
555+
*Fortran::semantics::GetExpr(stmt1Expr);
556+
captureStmtElemTy = converter.genType(fromExpr);
557+
emitImplicitCast(converter, loc, stmt2LHSArg, stmt1LHSArg,
558+
captureStmtElemTy);
559+
}
560+
} else {
561+
// Atomic capture construct is of the form [update-stmt, capture-stmt]
562+
// FIXME: Emit an implicit cast if there is a type mismatch
563+
}
564+
484565
mlir::Operation *atomicCaptureOp = nullptr;
485566
if constexpr (std::is_same<AtomicListT,
486567
Fortran::parser::OmpAtomicClauseList>()) {
@@ -501,8 +582,8 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
501582
firOpBuilder.createBlock(&(atomicCaptureOp->getRegion(0)));
502583
mlir::Block &block = atomicCaptureOp->getRegion(0).back();
503584
firOpBuilder.setInsertionPointToStart(&block);
504-
if (Fortran::semantics::checkForSingleVariableOnRHS(stmt1)) {
505-
if (Fortran::semantics::checkForSymbolMatch(stmt2)) {
585+
if (hasSingleVariable) {
586+
if (hasSymMatch) {
506587
// Atomic capture construct is of the form [capture-stmt, update-stmt]
507588
const Fortran::semantics::SomeExpr &fromExpr =
508589
*Fortran::semantics::GetExpr(stmt1Expr);
@@ -521,13 +602,10 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
521602
mlir::Value stmt2RHSArg =
522603
fir::getBase(converter.genExprValue(assign2.rhs, stmtCtx));
523604
firOpBuilder.setInsertionPointToStart(&block);
524-
const Fortran::semantics::SomeExpr &fromExpr =
525-
*Fortran::semantics::GetExpr(stmt1Expr);
526-
mlir::Type elementType = converter.genType(fromExpr);
527605
genOmpAccAtomicCaptureStatement<AtomicListT>(
528606
converter, stmt2LHSArg, stmt1LHSArg,
529607
/*leftHandClauseList=*/nullptr,
530-
/*rightHandClauseList=*/nullptr, elementType, loc);
608+
/*rightHandClauseList=*/nullptr, captureStmtElemTy, loc);
531609
genOmpAccAtomicWriteStatement<AtomicListT>(
532610
converter, stmt2LHSArg, stmt2RHSArg,
533611
/*leftHandClauseList=*/nullptr,

flang/test/Lower/OpenACC/acc-atomic-capture.f90

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,14 @@ end subroutine capture_with_convert_i32_to_f64
142142
! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f64, !fir.ref<f64>
143143
! CHECK: %c0_i32 = arith.constant 0 : i32
144144
! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
145-
! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
146-
! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
145+
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
146+
! CHECK: %[[LOAD:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref<f64>
147+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (f64) -> i32
148+
! CHECK: fir.store %[[CVT]] to %[[ALLOCA]] : !fir.ref<i32>
149+
! CHECK: %[[EXPR_CVT:.*]] = fir.convert {{.*}} : (f64) -> i32
147150
! CHECK: acc.atomic.capture {
148-
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<i32>, !fir.ref<f64>, f64
149-
! CHECK: acc.atomic.write %[[X_DECL]]#1 = %[[CONV]] : !fir.ref<f64>, f64
151+
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[ALLOCA]] : !fir.ref<i32>, !fir.ref<i32>, i32
152+
! CHECK: acc.atomic.write %[[ALLOCA]] = %[[EXPR_CVT]] : !fir.ref<i32>, i32
150153
! CHECK: }
151154

152155
subroutine capture_with_convert_f64_to_i32()

flang/test/Lower/OpenACC/acc-atomic-read.f90

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,8 @@ subroutine atomic_read_with_cast()
5555
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_read_with_castEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
5656
! CHECK: %[[Y:.*]] = fir.alloca i64 {bindc_name = "y", uniq_name = "_QFatomic_read_with_castEy"}
5757
! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFatomic_read_with_castEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
58-
! CHECK: acc.atomic.read %[[Y_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<i64>, !fir.ref<i32>, i32
58+
! CHECK: %[[ALLOCA:.*]] = fir.alloca i64
59+
! CHECK: %[[LOAD:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref<i32>
60+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (i32) -> i64
61+
! CHECK: fir.store %[[CVT]] to %[[ALLOCA]] : !fir.ref<i64>
62+
! CHECK: acc.atomic.read %[[Y_DECL]]#1 = %[[ALLOCA]] : !fir.ref<i64>, !fir.ref<i64>, i64
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
! REQUIRES: openmp_runtime
2+
3+
! RUN: %flang_fc1 -emit-hlfir %openmp_flags %s -o - | FileCheck %s
4+
5+
! CHECK: func.func @_QPatomic_implicit_cast_read() {
6+
subroutine atomic_implicit_cast_read
7+
! CHECK: %[[VAL_M:.*]] = fir.alloca complex<f64> {bindc_name = "m", uniq_name = "_QFatomic_implicit_cast_readEm"}
8+
! CHECK: %[[VAL_M_DECLARE:.*]]:2 = hlfir.declare %[[VAL_M]] {uniq_name = "_QFatomic_implicit_cast_readEm"} : (!fir.ref<complex<f64>>) -> (!fir.ref<complex<f64>>, !fir.ref<complex<f64>>)
9+
! CHECK: %[[VAL_W:.*]] = fir.alloca complex<f32> {bindc_name = "w", uniq_name = "_QFatomic_implicit_cast_readEw"}
10+
! CHECK: %[[VAL_W_DECLARE:.*]]:2 = hlfir.declare %[[VAL_W]] {uniq_name = "_QFatomic_implicit_cast_readEw"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
11+
! CHECK: %[[VAL_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_implicit_cast_readEx"}
12+
! CHECK: %[[VAL_X_DECLARE:.*]]:2 = hlfir.declare %[[VAL_X]] {uniq_name = "_QFatomic_implicit_cast_readEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
13+
! CHECK: %[[VAL_Y:.*]] = fir.alloca f32 {bindc_name = "y", uniq_name = "_QFatomic_implicit_cast_readEy"}
14+
! CHECK: %[[VAL_Y_DECLARE:.*]]:2 = hlfir.declare %[[VAL_Y]] {uniq_name = "_QFatomic_implicit_cast_readEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
15+
! CHECK: %[[VAL_Z:.*]] = fir.alloca f64 {bindc_name = "z", uniq_name = "_QFatomic_implicit_cast_readEz"}
16+
! CHECK: %[[VAL_Z_DECLARE:.*]]:2 = hlfir.declare %[[VAL_Z]] {uniq_name = "_QFatomic_implicit_cast_readEz"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
17+
integer :: x
18+
real :: y
19+
double precision :: z
20+
complex :: w
21+
complex(8) :: m
22+
23+
! Atomic read
24+
25+
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
26+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_Y_DECLARE]]#1 : !fir.ref<f32>
27+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (f32) -> i32
28+
! CHECK: fir.store %[[CVT]] to %[[ALLOCA]] : !fir.ref<i32>
29+
! CHECK: omp.atomic.read %[[VAL_X_DECLARE]]#1 = %[[ALLOCA]] : !fir.ref<i32>, !fir.ref<i32>, i32
30+
!$omp atomic read
31+
x = y
32+
33+
! CHECK: %[[ALLOCA:.*]] = fir.alloca f64
34+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_X_DECLARE]]#1 : !fir.ref<i32>
35+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
36+
! CHECK: fir.store %[[CVT]] to %[[ALLOCA]] : !fir.ref<f64>
37+
! CHECK: omp.atomic.read %[[VAL_Z_DECLARE]]#1 = %[[ALLOCA]] : !fir.ref<f64>, !fir.ref<f64>, f64
38+
!$omp atomic read
39+
z = x
40+
41+
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
42+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_W_DECLARE]]#1 : !fir.ref<complex<f32>>
43+
! CHECK: %[[EXT:.*]] = fir.extract_value %[[LOAD]], [0 : index] : (complex<f32>) -> f32
44+
! CHECK: %[[CVT:.*]] = fir.convert %[[EXT]] : (f32) -> i32
45+
! CHECK: fir.store %[[CVT]] to %[[ALLOCA]] : !fir.ref<i32>
46+
! CHECK: omp.atomic.read %[[VAL_X_DECLARE]]#1 = %[[ALLOCA]] : !fir.ref<i32>, !fir.ref<i32>, i32
47+
!$omp atomic read
48+
x = w
49+
50+
! CHECK: %[[ALLOCA:.*]] = fir.alloca f32
51+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_W_DECLARE]]#1 : !fir.ref<complex<f32>>
52+
! CHECK: %[[EXT:.*]] = fir.extract_value %[[LOAD]], [0 : index] : (complex<f32>) -> f32
53+
! CHECK: %[[CVT:.*]] = fir.convert %[[EXT]] : (f32) -> f32
54+
! CHECK: fir.store %[[CVT]] to %[[ALLOCA]] : !fir.ref<f32>
55+
! CHECK: omp.atomic.read %[[VAL_Y_DECLARE]]#1 = %[[ALLOCA]] : !fir.ref<f32>, !fir.ref<f32>, f32
56+
!$omp atomic read
57+
y = w
58+
59+
! CHECK: %[[ALLOCA:.*]] = fir.alloca complex<f64>
60+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_W_DECLARE]]#1 : !fir.ref<complex<f32>>
61+
! CHECK: %[[EXT0:.*]] = fir.extract_value %[[LOAD]], [0 : index] : (complex<f32>) -> f32
62+
! CHECK: %[[EXT1:.*]] = fir.extract_value %[[LOAD]], [1 : index] : (complex<f32>) -> f32
63+
! CHECK: %[[CVT0:.*]] = fir.convert %[[EXT0]] : (f32) -> f64
64+
! CHECK: %[[CVT1:.*]] = fir.convert %[[EXT1]] : (f32) -> f64
65+
! CHECK: %[[UNDEF:.*]] = fir.undefined complex<f64>
66+
! CHECK: %[[INSERT1:.*]] = fir.insert_value %[[UNDEF]], %[[CVT0]], [0 : index] : (complex<f64>, f64) -> complex<f64>
67+
! CHECK: %[[INSERT2:.*]] = fir.insert_value %[[INSERT1]], %[[CVT1]], [1 : index] : (complex<f64>, f64) -> complex<f64>
68+
! CHECK: fir.store %[[INSERT2]] to %[[ALLOCA]] : !fir.ref<complex<f64>>
69+
! CHECK: omp.atomic.read %[[VAL_M_DECLARE]]#1 = %[[ALLOCA]] : !fir.ref<complex<f64>>, !fir.ref<complex<f64>>, complex<f64>
70+
!$omp atomic read
71+
m = w
72+
end subroutine
73+
! CHECK: func.func @_QPatomic_implicit_cast_write()
74+
subroutine atomic_implicit_cast_write
75+
! CHECK: %[[VAL_M:.*]] = fir.alloca complex<f64> {bindc_name = "m", uniq_name = "_QFatomic_implicit_cast_writeEm"}
76+
! CHECK: %[[VAL_M_DECLARE:.*]]:2 = hlfir.declare %[[VAL_M]] {uniq_name = "_QFatomic_implicit_cast_writeEm"} : (!fir.ref<complex<f64>>) -> (!fir.ref<complex<f64>>, !fir.ref<complex<f64>>)
77+
! CHECK: %[[VAL_W:.*]] = fir.alloca complex<f32> {bindc_name = "w", uniq_name = "_QFatomic_implicit_cast_writeEw"}
78+
! CHECK: %[[VAL_W_DECLARE:.*]]:2 = hlfir.declare %[[VAL_W]] {uniq_name = "_QFatomic_implicit_cast_writeEw"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
79+
! CHECK: %[[VAL_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_implicit_cast_writeEx"}
80+
! CHECK: %[[VAL_X_DECLARE:.*]]:2 = hlfir.declare %[[VAL_X]] {uniq_name = "_QFatomic_implicit_cast_writeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
81+
! CHECK: %[[VAL_Y:.*]] = fir.alloca f32 {bindc_name = "y", uniq_name = "_QFatomic_implicit_cast_writeEy"}
82+
! CHECK: %[[VAL_Y_DECLARE:.*]]:2 = hlfir.declare %[[VAL_Y]] {uniq_name = "_QFatomic_implicit_cast_writeEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
83+
! CHECK: %[[VAL_Z:.*]] = fir.alloca f64 {bindc_name = "z", uniq_name = "_QFatomic_implicit_cast_writeEz"}
84+
! CHECK: %[[VAL_Z_DECLARE:.*]]:2 = hlfir.declare %[[VAL_Z]] {uniq_name = "_QFatomic_implicit_cast_writeEz"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
85+
integer :: x
86+
real :: y
87+
double precision :: z
88+
complex :: w
89+
complex(8) :: m
90+
91+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_Y_DECLARE]]#0 : !fir.ref<f32>
92+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (f32) -> i32
93+
! CHECK: omp.atomic.write %[[VAL_X_DECLARE]]#1 = %[[CVT]] : !fir.ref<i32>, i32
94+
!$omp atomic write
95+
x = y
96+
97+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_X_DECLARE]]#0 : !fir.ref<i32>
98+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
99+
! CHECK: omp.atomic.write %[[VAL_Z_DECLARE:.*]] = %[[CVT]] : !fir.ref<f64>, f64
100+
!$omp atomic write
101+
z = x
102+
103+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_W_DECLARE]]#0 : !fir.ref<complex<f32>>
104+
! CHECK: %[[EXT:.*]] = fir.extract_value %[[LOAD]], [0 : index] : (complex<f32>) -> f32
105+
! CHECK: %[[CVT:.*]] = fir.convert %[[EXT]] : (f32) -> i32
106+
! CHECK: omp.atomic.write %[[VAL_X_DECLARE]]#1 = %[[CVT]] : !fir.ref<i32>, i32
107+
!$omp atomic write
108+
x = w
109+
110+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_W_DECLARE]]#0 : !fir.ref<complex<f32>>
111+
! CHECK: %[[EXT:.*]] = fir.extract_value %[[LOAD]], [0 : index] : (complex<f32>) -> f32
112+
! CHECK: omp.atomic.write %[[VAL_Y_DECLARE]]#1 = %[[EXT]] : !fir.ref<f32>, f32
113+
!$omp atomic write
114+
y = w
115+
116+
! CHECK: %[[LOAD:.*]] = fir.load %[[VAL_W_DECLARE]]#0 : !fir.ref<complex<f32>>
117+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (complex<f32>) -> complex<f64>
118+
! CHECK: omp.atomic.write %[[VAL_M_DECLARE]]#1 = %[[CVT]] : !fir.ref<complex<f64>>, complex<f64>
119+
!$omp atomic write
120+
m = w
121+
end subroutine

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -268,33 +268,6 @@ computeOpenMPScheduleType(ScheduleKind ClauseKind, bool HasChunks,
268268
return Result;
269269
}
270270

271-
/// Emit an implicit cast to convert \p XRead to type of variable \p V
272-
static llvm::Value *emitImplicitCast(IRBuilder<> &Builder, llvm::Value *XRead,
273-
llvm::Value *V) {
274-
// TODO: Add this functionality to the `AtomicInfo` interface
275-
llvm::Type *XReadType = XRead->getType();
276-
llvm::Type *VType = V->getType();
277-
if (llvm::AllocaInst *vAlloca = dyn_cast<llvm::AllocaInst>(V))
278-
VType = vAlloca->getAllocatedType();
279-
280-
if (XReadType->isStructTy() && VType->isStructTy())
281-
// No need to extract or convert. A direct
282-
// `store` will suffice.
283-
return XRead;
284-
285-
if (XReadType->isStructTy())
286-
XRead = Builder.CreateExtractValue(XRead, /*Idxs=*/0);
287-
if (VType->isIntegerTy() && XReadType->isFloatingPointTy())
288-
XRead = Builder.CreateFPToSI(XRead, VType);
289-
else if (VType->isFloatingPointTy() && XReadType->isIntegerTy())
290-
XRead = Builder.CreateSIToFP(XRead, VType);
291-
else if (VType->isIntegerTy() && XReadType->isIntegerTy())
292-
XRead = Builder.CreateIntCast(XRead, VType, true);
293-
else if (VType->isFloatingPointTy() && XReadType->isFloatingPointTy())
294-
XRead = Builder.CreateFPCast(XRead, VType);
295-
return XRead;
296-
}
297-
298271
/// Make \p Source branch to \p Target.
299272
///
300273
/// Handles two situations:
@@ -8655,8 +8628,6 @@ OpenMPIRBuilder::createAtomicRead(const LocationDescription &Loc,
86558628
}
86568629
}
86578630
checkAndEmitFlushAfterAtomic(Loc, AO, AtomicKind::Read);
8658-
if (XRead->getType() != V.Var->getType())
8659-
XRead = emitImplicitCast(Builder, XRead, V.Var);
86608631
Builder.CreateStore(XRead, V.Var, V.IsVolatile);
86618632
return Builder.saveIP();
86628633
}
@@ -8941,8 +8912,6 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createAtomicCapture(
89418912
return AtomicResult.takeError();
89428913
Value *CapturedVal =
89438914
(IsPostfixUpdate ? AtomicResult->first : AtomicResult->second);
8944-
if (CapturedVal->getType() != V.Var->getType())
8945-
CapturedVal = emitImplicitCast(Builder, CapturedVal, V.Var);
89468915
Builder.CreateStore(CapturedVal, V.Var, V.IsVolatile);
89478916

89488917
checkAndEmitFlushAfterAtomic(Loc, AO, AtomicKind::Capture);

0 commit comments

Comments
 (0)