Skip to content

Commit 645e6f1

Browse files
authored
[llvm][OpenMP] Handle complex types in atomic read (#111377)
This patch adds functionality for atomically reading `llvm.struct` types. Fixes: #93441
1 parent bd6c430 commit 645e6f1

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7836,7 +7836,7 @@ OpenMPIRBuilder::createAtomicRead(const LocationDescription &Loc,
78367836
"OMP Atomic expects a pointer to target memory");
78377837
Type *XElemTy = X.ElemTy;
78387838
assert((XElemTy->isFloatingPointTy() || XElemTy->isIntegerTy() ||
7839-
XElemTy->isPointerTy()) &&
7839+
XElemTy->isPointerTy() || XElemTy->isStructTy()) &&
78407840
"OMP atomic read expected a scalar type");
78417841

78427842
Value *XRead = nullptr;
@@ -7846,6 +7846,20 @@ OpenMPIRBuilder::createAtomicRead(const LocationDescription &Loc,
78467846
Builder.CreateLoad(XElemTy, X.Var, X.IsVolatile, "omp.atomic.read");
78477847
XLD->setAtomic(AO);
78487848
XRead = cast<Value>(XLD);
7849+
} else if (XElemTy->isStructTy()) {
7850+
// FIXME: Add checks to ensure __atomic_load is emitted iff the
7851+
// target does not support `atomicrmw` of the size of the struct
7852+
LoadInst *OldVal = Builder.CreateLoad(XElemTy, X.Var, "omp.atomic.read");
7853+
OldVal->setAtomic(AO);
7854+
const DataLayout &LoadDL = OldVal->getModule()->getDataLayout();
7855+
unsigned LoadSize =
7856+
LoadDL.getTypeStoreSize(OldVal->getPointerOperand()->getType());
7857+
OpenMPIRBuilder::AtomicInfo atomicInfo(
7858+
&Builder, XElemTy, LoadSize * 8, LoadSize * 8, OldVal->getAlign(),
7859+
OldVal->getAlign(), true /* UseLibcall */, X.Var);
7860+
auto AtomicLoadRes = atomicInfo.EmitAtomicLoadLibcall(AO);
7861+
XRead = AtomicLoadRes.first;
7862+
OldVal->eraseFromParent();
78497863
} else {
78507864
// We need to perform atomic op as integer
78517865
IntegerType *IntCastTy =

mlir/test/Target/LLVMIR/openmp-llvm.mlir

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,28 @@ llvm.func @_QPomp_atomic_capture_complex() {
15251525

15261526
// -----
15271527

1528+
// CHECK-LABEL: define void @omp_atomic_read_complex() {
1529+
llvm.func @omp_atomic_read_complex(){
1530+
1531+
// CHECK: %[[a:.*]] = alloca { float, float }, i64 1, align 8
1532+
// CHECK: %[[b:.*]] = alloca { float, float }, i64 1, align 8
1533+
// CHECK: %[[ATOMIC_TEMP_LOAD:.*]] = alloca { float, float }, align 8
1534+
// CHECK: call void @__atomic_load(i64 8, ptr %[[b]], ptr %[[ATOMIC_TEMP_LOAD]], i32 0)
1535+
// CHECK: %[[LOADED_VAL:.*]] = load { float, float }, ptr %[[ATOMIC_TEMP_LOAD]], align 8
1536+
// CHECK: store { float, float } %[[LOADED_VAL]], ptr %[[a]], align 4
1537+
// CHECK: ret void
1538+
// CHECK: }
1539+
1540+
%0 = llvm.mlir.constant(1 : i64) : i64
1541+
%1 = llvm.alloca %0 x !llvm.struct<(f32, f32)> {bindc_name = "ib"} : (i64) -> !llvm.ptr
1542+
%2 = llvm.mlir.constant(1 : i64) : i64
1543+
%3 = llvm.alloca %2 x !llvm.struct<(f32, f32)> {bindc_name = "ia"} : (i64) -> !llvm.ptr
1544+
omp.atomic.read %1 = %3 : !llvm.ptr, !llvm.struct<(f32, f32)>
1545+
llvm.return
1546+
}
1547+
1548+
// -----
1549+
15281550
// Checking an order-dependent operation when the order is `expr binop x`
15291551
// CHECK-LABEL: @omp_atomic_update_ordering
15301552
// CHECK-SAME: (ptr %[[x:.*]], i32 %[[expr:.*]])

0 commit comments

Comments
 (0)