Skip to content

Commit 1caff48

Browse files
committed
[llvm] [OpenMP] Handle complex types in atomic read
1 parent a018353 commit 1caff48

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7822,7 +7822,7 @@ OpenMPIRBuilder::createAtomicRead(const LocationDescription &Loc,
78227822
"OMP Atomic expects a pointer to target memory");
78237823
Type *XElemTy = X.ElemTy;
78247824
assert((XElemTy->isFloatingPointTy() || XElemTy->isIntegerTy() ||
7825-
XElemTy->isPointerTy()) &&
7825+
XElemTy->isPointerTy() || XElemTy->isStructTy()) &&
78267826
"OMP atomic read expected a scalar type");
78277827

78287828
Value *XRead = nullptr;
@@ -7832,6 +7832,18 @@ OpenMPIRBuilder::createAtomicRead(const LocationDescription &Loc,
78327832
Builder.CreateLoad(XElemTy, X.Var, X.IsVolatile, "omp.atomic.read");
78337833
XLD->setAtomic(AO);
78347834
XRead = cast<Value>(XLD);
7835+
} else if (XElemTy->isStructTy()) {
7836+
LoadInst *OldVal = Builder.CreateLoad(XElemTy, X.Var, "omp.atomic.read");
7837+
OldVal->setAtomic(AO);
7838+
const DataLayout &LoadDL = OldVal->getModule()->getDataLayout();
7839+
unsigned LoadSize =
7840+
LoadDL.getTypeStoreSize(OldVal->getPointerOperand()->getType());
7841+
OpenMPIRBuilder::AtomicInfo atomicInfo(
7842+
&Builder, XElemTy, LoadSize * 8, LoadSize * 8, OldVal->getAlign(),
7843+
OldVal->getAlign(), true /* UseLibcall */, X.Var);
7844+
auto AtomicLoadRes = atomicInfo.EmitAtomicLoadLibcall(AO);
7845+
XRead = AtomicLoadRes.first;
7846+
OldVal->eraseFromParent();
78357847
} else {
78367848
// We need to perform atomic op as integer
78377849
IntegerType *IntCastTy =

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

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

15651565
// -----
15661566

1567+
// CHECK-LABEL: define void @omp_atomic_read_complex() {
1568+
llvm.func @omp_atomic_read_complex(){
1569+
1570+
// CHECK: %[[a:.*]] = alloca { float, float }, i64 1, align 8
1571+
// CHECK: %[[b:.*]] = alloca { float, float }, i64 1, align 8
1572+
// CHECK: %[[ATOMIC_TEMP_LOAD:.*]] = alloca { float, float }, align 8
1573+
// CHECK: call void @__atomic_load(i64 8, ptr %[[b]], ptr %[[ATOMIC_TEMP_LOAD]], i32 0)
1574+
// CHECK: %[[LOADED_VAL:.*]] = load { float, float }, ptr %[[ATOMIC_TEMP_LOAD]], align 8
1575+
// CHECK: store { float, float } %[[LOADED_VAL]], ptr %[[a]], align 4
1576+
// CHECK: ret void
1577+
// CHECK: }
1578+
1579+
%0 = llvm.mlir.constant(1 : i64) : i64
1580+
%1 = llvm.alloca %0 x !llvm.struct<(f32, f32)> {bindc_name = "ib"} : (i64) -> !llvm.ptr
1581+
%2 = llvm.mlir.constant(1 : i64) : i64
1582+
%3 = llvm.alloca %2 x !llvm.struct<(f32, f32)> {bindc_name = "ia"} : (i64) -> !llvm.ptr
1583+
omp.atomic.read %1 = %3 : !llvm.ptr, !llvm.struct<(f32, f32)>
1584+
llvm.return
1585+
}
1586+
1587+
// -----
1588+
15671589
// Checking an order-dependent operation when the order is `expr binop x`
15681590
// CHECK-LABEL: @omp_atomic_update_ordering
15691591
// CHECK-SAME: (ptr %[[x:.*]], i32 %[[expr:.*]])

0 commit comments

Comments
 (0)