Skip to content

Commit b400ef5

Browse files
committed
[mlir] Add __atomic_store to AtomicInfo
1 parent 10c18ab commit b400ef5

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed

llvm/include/llvm/Frontend/Atomic/Atomic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class AtomicInfo {
9696
bool IsVolatile, bool IsWeak);
9797

9898
std::pair<LoadInst *, AllocaInst *> EmitAtomicLoadLibcall(AtomicOrdering AO);
99+
100+
void EmitAtomicStoreLibcall(AtomicOrdering AO, Value *Source);
99101
};
100102
} // end namespace llvm
101103

llvm/lib/Frontend/Atomic/Atomic.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,39 @@ AtomicInfo::EmitAtomicLoadLibcall(AtomicOrdering AO) {
141141
AllocaResult);
142142
}
143143

144+
void AtomicInfo::EmitAtomicStoreLibcall(AtomicOrdering AO, Value *Source) {
145+
LLVMContext &Ctx = getLLVMContext();
146+
SmallVector<Value *, 6> Args;
147+
AttributeList Attr;
148+
Module *M = Builder->GetInsertBlock()->getModule();
149+
const DataLayout &DL = M->getDataLayout();
150+
Args.push_back(
151+
ConstantInt::get(DL.getIntPtrType(Ctx), this->getAtomicSizeInBits() / 8));
152+
153+
Value *PtrVal = getAtomicPointer();
154+
PtrVal = Builder->CreateAddrSpaceCast(PtrVal, PointerType::getUnqual(Ctx));
155+
Args.push_back(PtrVal);
156+
157+
Value *SourceAlloca = Builder->CreateAlloca(Source->getType());
158+
Builder->CreateStore(Source, SourceAlloca);
159+
SourceAlloca = Builder->CreatePointerBitCastOrAddrSpaceCast(
160+
SourceAlloca, Builder->getPtrTy());
161+
Args.push_back(SourceAlloca);
162+
163+
Constant *OrderingVal =
164+
ConstantInt::get(Type::getInt32Ty(Ctx), (int)toCABI(AO));
165+
Args.push_back(OrderingVal);
166+
167+
SmallVector<Type *, 6> ArgTys;
168+
for (Value *Arg : Args)
169+
ArgTys.push_back(Arg->getType());
170+
FunctionType *FnType = FunctionType::get(Type::getVoidTy(Ctx), ArgTys, false);
171+
FunctionCallee LibcallFn =
172+
M->getOrInsertFunction("__atomic_store", FnType, Attr);
173+
CallInst *Call = Builder->CreateCall(LibcallFn, Args);
174+
Call->setAttributes(Attr);
175+
}
176+
144177
std::pair<Value *, Value *> AtomicInfo::EmitAtomicCompareExchange(
145178
Value *ExpectedVal, Value *DesiredVal, AtomicOrdering Success,
146179
AtomicOrdering Failure, bool IsVolatile, bool IsWeak) {

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8400,12 +8400,22 @@ OpenMPIRBuilder::createAtomicWrite(const LocationDescription &Loc,
84008400
"OMP Atomic expects a pointer to target memory");
84018401
Type *XElemTy = X.ElemTy;
84028402
assert((XElemTy->isFloatingPointTy() || XElemTy->isIntegerTy() ||
8403-
XElemTy->isPointerTy()) &&
8403+
XElemTy->isPointerTy() || XElemTy->isStructTy()) &&
84048404
"OMP atomic write expected a scalar type");
84058405

84068406
if (XElemTy->isIntegerTy()) {
84078407
StoreInst *XSt = Builder.CreateStore(Expr, X.Var, X.IsVolatile);
84088408
XSt->setAtomic(AO);
8409+
} else if (XElemTy->isStructTy()) {
8410+
LoadInst *OldVal = Builder.CreateLoad(XElemTy, X.Var, "omp.atomic.read");
8411+
const DataLayout &LoadDL = OldVal->getModule()->getDataLayout();
8412+
unsigned LoadSize =
8413+
LoadDL.getTypeStoreSize(OldVal->getPointerOperand()->getType());
8414+
OpenMPIRBuilder::AtomicInfo atomicInfo(
8415+
&Builder, XElemTy, LoadSize * 8, LoadSize * 8, OldVal->getAlign(),
8416+
OldVal->getAlign(), true /* UseLibcall */, X.Var);
8417+
atomicInfo.EmitAtomicStoreLibcall(AO, Expr);
8418+
OldVal->eraseFromParent();
84098419
} else {
84108420
// We need to bitcast and perform atomic op as integers
84118421
IntegerType *IntCastTy =

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,28 @@ llvm.func @omp_atomic_update(%x:!llvm.ptr, %expr: i32, %xbool: !llvm.ptr, %exprb
14091409
llvm.return
14101410
}
14111411

1412+
// ----
1413+
1414+
//CHECK-LABEL: @atomic_complex_write
1415+
//CHECK: %[[V:.*]] = alloca { float, float }, i64 1, align 8
1416+
//CHECK: %[[X:.*]] = alloca { float, float }, i64 1, align 8
1417+
//CHECK: %[[LOAD:.*]] = load { float, float }, ptr %1, align 4
1418+
//CHECK: %[[ALLOCA:.*]] = alloca { float, float }, align 8
1419+
//CHECK: store { float, float } %[[LOAD]], ptr %[[ALLOCA]], align 4
1420+
//CHECK: call void @__atomic_store(i64 8, ptr %[[X]], ptr %[[ALLOCA]], i32 0)
1421+
1422+
llvm.func @atomic_complex_write() {
1423+
%0 = llvm.mlir.constant(1 : i64) : i64
1424+
%1 = llvm.alloca %0 x !llvm.struct<(f32, f32)> {bindc_name = "r"} : (i64) -> !llvm.ptr
1425+
%2 = llvm.mlir.constant(1 : i64) : i64
1426+
%3 = llvm.alloca %2 x !llvm.struct<(f32, f32)> {bindc_name = "l"} : (i64) -> !llvm.ptr
1427+
%4 = llvm.mlir.constant(1 : i64) : i64
1428+
%5 = llvm.mlir.constant(1 : i64) : i64
1429+
%6 = llvm.load %1 : !llvm.ptr -> !llvm.struct<(f32, f32)>
1430+
omp.atomic.write %3 = %6 : !llvm.ptr, !llvm.struct<(f32, f32)>
1431+
llvm.return
1432+
}
1433+
14121434
// -----
14131435

14141436
//CHECK: %[[X_NEW_VAL:.*]] = alloca { float, float }, align 8

0 commit comments

Comments
 (0)