[flang-commits] [flang] [llvm] [mlir] [OpenMPIRBuilder] Emit __atomic_load and __atomic_compare_exchange libcalls for complex types in atomic update (PR #92364)

via flang-commits flang-commits at lists.llvm.org
Fri Sep 27 01:11:40 PDT 2024


================
@@ -7943,6 +7943,83 @@ Value *OpenMPIRBuilder::emitRMWOpAsInstruction(Value *Src1, Value *Src2,
   llvm_unreachable("Unsupported atomic update operation");
 }
 
+std::pair<llvm::LoadInst *, llvm::AllocaInst *>
+OpenMPIRBuilder::EmitAtomicLoadLibcall(Value *X, Type *XElemTy,
+                                       llvm::AtomicOrdering AO,
+                                       uint64_t AtomicSizeInBits) {
+  LLVMContext &Ctx = Builder.getContext();
+  Type *SizedIntTy = Type::getIntNTy(Ctx, AtomicSizeInBits * 8);
+  Type *ResultTy;
+  SmallVector<Value *, 6> Args;
+  AttributeList Attr;
+  Module *M = Builder.GetInsertBlock()->getModule();
+  const DataLayout &DL = M->getDataLayout();
+  Args.push_back(ConstantInt::get(DL.getIntPtrType(Ctx), AtomicSizeInBits / 8));
+  Value *PtrVal = X;
+  PtrVal = Builder.CreateAddrSpaceCast(PtrVal, PointerType::getUnqual(Ctx));
+  Args.push_back(PtrVal);
+  llvm::AllocaInst *allocaInst = Builder.CreateAlloca(XElemTy);
+  allocaInst->setName(X->getName() + "atomic.temp.load");
+  const Align AllocaAlignment = DL.getPrefTypeAlign(SizedIntTy);
+  allocaInst->setAlignment(AllocaAlignment);
+  Args.push_back(allocaInst);
+  Constant *OrderingVal =
+      ConstantInt::get(Type::getInt32Ty(Ctx), (int)toCABI(AO));
+  Args.push_back(OrderingVal);
+  ResultTy = Type::getVoidTy(Ctx);
+  SmallVector<Type *, 6> ArgTys;
+  for (Value *Arg : Args)
+    ArgTys.push_back(Arg->getType());
+  FunctionType *FnType = FunctionType::get(ResultTy, ArgTys, false);
+  FunctionCallee LibcallFn =
+      M->getOrInsertFunction("__atomic_load", FnType, Attr);
+  CallInst *Call = Builder.CreateCall(LibcallFn, Args);
+  Call->setAttributes(Attr);
+  return std::make_pair(
+      Builder.CreateAlignedLoad(XElemTy, allocaInst, AllocaAlignment),
+      allocaInst);
+}
+
+std::pair<llvm::Value *, llvm::Value *>
+OpenMPIRBuilder::EmitAtomicCompareExchangeLibcall(
+    Value *X, Type *XElemTy, uint64_t AtomicSizeInBits,
+    llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
+    llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure) {
+  LLVMContext &Ctx = Builder.getContext();
+  uint64_t IntBits = 32;
----------------
NimishMishra wrote:

The last two arguments to `__atomic_compare_exchange` are `int success` and `int failure`. Hence, we create a `llvm::Constant::getIntegerValue` and use the generic 4-byte width for an integer. I have added a TODO to instead get the width of an integer from `TargetMachine` and `TargetInfo`. The new code resides in `EmitAtomicCompareExchangeLibcall` in `Atomic.h`

https://github.com/llvm/llvm-project/pull/92364


More information about the flang-commits mailing list