diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h --- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -1216,6 +1216,7 @@ /// /// \param AllocIP Instruction to create AllocaInst before. /// \param X The target atomic pointer to be updated + /// \param XElemTy The element type of the atomic pointer. /// \param Expr The value to update X with. /// \param AO Atomic ordering of the generated atomic /// instructions. @@ -1232,12 +1233,11 @@ /// /// \returns A pair of the old value of X before the update, and the value /// used for the update. - std::pair emitAtomicUpdate(Instruction *AllocIP, Value *X, - Value *Expr, AtomicOrdering AO, - AtomicRMWInst::BinOp RMWOp, - AtomicUpdateCallbackTy &UpdateOp, - bool VolatileX, - bool IsXBinopExpr); + std::pair + emitAtomicUpdate(Instruction *AllocIP, Value *X, Type *XElemTy, Value *Expr, + AtomicOrdering AO, AtomicRMWInst::BinOp RMWOp, + AtomicUpdateCallbackTy &UpdateOp, bool VolatileX, + bool IsXBinopExpr); /// Emit the binary op. described by \p RMWOp, using \p Src1 and \p Src2 . /// @@ -1249,6 +1249,7 @@ /// a struct to pack relevant information while generating atomic Ops struct AtomicOpValue { Value *Var = nullptr; + Type *ElemTy = nullptr; bool IsSigned = false; bool IsVolatile = false; }; diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -3222,7 +3222,7 @@ Type *XTy = X.Var->getType(); assert(XTy->isPointerTy() && "OMP Atomic expects a pointer to target memory"); - Type *XElemTy = XTy->getPointerElementType(); + Type *XElemTy = X.ElemTy; assert((XElemTy->isFloatingPointTy() || XElemTy->isIntegerTy() || XElemTy->isPointerTy()) && "OMP atomic read expected a scalar type"); @@ -3264,7 +3264,7 @@ Type *XTy = X.Var->getType(); assert(XTy->isPointerTy() && "OMP Atomic expects a pointer to target memory"); - Type *XElemTy = XTy->getPointerElementType(); + Type *XElemTy = X.ElemTy; assert((XElemTy->isFloatingPointTy() || XElemTy->isIntegerTy() || XElemTy->isPointerTy()) && "OMP atomic write expected a scalar type"); @@ -3300,7 +3300,7 @@ Type *XTy = X.Var->getType(); assert(XTy->isPointerTy() && "OMP Atomic expects a pointer to target memory"); - Type *XElemTy = XTy->getPointerElementType(); + Type *XElemTy = X.ElemTy; assert((XElemTy->isFloatingPointTy() || XElemTy->isIntegerTy() || XElemTy->isPointerTy()) && "OMP atomic update expected a scalar type"); @@ -3309,8 +3309,8 @@ "OpenMP atomic does not support LT or GT operations"); }); - emitAtomicUpdate(AllocIP, X.Var, Expr, AO, RMWOp, UpdateOp, X.IsVolatile, - IsXBinopExpr); + emitAtomicUpdate(AllocIP, X.Var, X.ElemTy, Expr, AO, RMWOp, UpdateOp, + X.IsVolatile, IsXBinopExpr); checkAndEmitFlushAfterAtomic(Loc, AO, AtomicKind::Update); return Builder.saveIP(); } @@ -3343,13 +3343,10 @@ llvm_unreachable("Unsupported atomic update operation"); } -std::pair -OpenMPIRBuilder::emitAtomicUpdate(Instruction *AllocIP, Value *X, Value *Expr, - AtomicOrdering AO, AtomicRMWInst::BinOp RMWOp, - AtomicUpdateCallbackTy &UpdateOp, - bool VolatileX, bool IsXBinopExpr) { - Type *XElemTy = X->getType()->getPointerElementType(); - +std::pair OpenMPIRBuilder::emitAtomicUpdate( + Instruction *AllocIP, Value *X, Type *XElemTy, Value *Expr, + AtomicOrdering AO, AtomicRMWInst::BinOp RMWOp, + AtomicUpdateCallbackTy &UpdateOp, bool VolatileX, bool IsXBinopExpr) { bool DoCmpExch = ((RMWOp == AtomicRMWInst::BAD_BINOP) || (RMWOp == AtomicRMWInst::FAdd)) || (RMWOp == AtomicRMWInst::FSub) || @@ -3464,8 +3461,9 @@ // If UpdateExpr is 'x' updated with some `expr` not based on 'x', // 'x' is simply atomically rewritten with 'expr'. AtomicRMWInst::BinOp AtomicOp = (UpdateExpr ? RMWOp : AtomicRMWInst::Xchg); - std::pair Result = emitAtomicUpdate( - AllocIP, X.Var, Expr, AO, AtomicOp, UpdateOp, X.IsVolatile, IsXBinopExpr); + std::pair Result = + emitAtomicUpdate(AllocIP, X.Var, X.ElemTy, Expr, AO, AtomicOp, UpdateOp, + X.IsVolatile, IsXBinopExpr); Value *CapturedVal = (IsPostfixUpdate ? Result.first : Result.second); Builder.CreateStore(CapturedVal, V.Var, V.IsVolatile); diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -2758,8 +2758,8 @@ AllocaInst *VVal = Builder.CreateAlloca(Float32); VVal->setName("AtomicRead"); AtomicOrdering AO = AtomicOrdering::Monotonic; - OpenMPIRBuilder::AtomicOpValue X = {XVal, false, false}; - OpenMPIRBuilder::AtomicOpValue V = {VVal, false, false}; + OpenMPIRBuilder::AtomicOpValue X = {XVal, Float32, false, false}; + OpenMPIRBuilder::AtomicOpValue V = {VVal, Float32, false, false}; Builder.restoreIP(OMPBuilder.createAtomicRead(Loc, X, V, AO)); @@ -2803,8 +2803,8 @@ AllocaInst *VVal = Builder.CreateAlloca(Int32); VVal->setName("AtomicRead"); AtomicOrdering AO = AtomicOrdering::Monotonic; - OpenMPIRBuilder::AtomicOpValue X = {XVal, false, false}; - OpenMPIRBuilder::AtomicOpValue V = {VVal, false, false}; + OpenMPIRBuilder::AtomicOpValue X = {XVal, Int32, false, false}; + OpenMPIRBuilder::AtomicOpValue V = {VVal, Int32, false, false}; BasicBlock *EntryBB = BB; @@ -2850,7 +2850,7 @@ Type *Float32 = Type::getFloatTy(Ctx); AllocaInst *XVal = Builder.CreateAlloca(Float32); XVal->setName("AtomicVar"); - OpenMPIRBuilder::AtomicOpValue X = {XVal, false, false}; + OpenMPIRBuilder::AtomicOpValue X = {XVal, Float32, false, false}; AtomicOrdering AO = AtomicOrdering::Monotonic; Constant *ValToWrite = ConstantFP::get(Float32, 1.0); @@ -2888,7 +2888,7 @@ IntegerType *Int32 = Type::getInt32Ty(Ctx); AllocaInst *XVal = Builder.CreateAlloca(Int32); XVal->setName("AtomicVar"); - OpenMPIRBuilder::AtomicOpValue X = {XVal, false, false}; + OpenMPIRBuilder::AtomicOpValue X = {XVal, Int32, false, false}; AtomicOrdering AO = AtomicOrdering::Monotonic; ConstantInt *ValToWrite = ConstantInt::get(Type::getInt32Ty(Ctx), 1U); @@ -2928,7 +2928,7 @@ AllocaInst *XVal = Builder.CreateAlloca(Int32); XVal->setName("AtomicVar"); Builder.CreateStore(ConstantInt::get(Type::getInt32Ty(Ctx), 0U), XVal); - OpenMPIRBuilder::AtomicOpValue X = {XVal, false, false}; + OpenMPIRBuilder::AtomicOpValue X = {XVal, Int32, false, false}; AtomicOrdering AO = AtomicOrdering::Monotonic; ConstantInt *ConstVal = ConstantInt::get(Type::getInt32Ty(Ctx), 1U); Value *Expr = nullptr; @@ -2999,8 +2999,8 @@ StoreInst *Init = Builder.CreateStore(ConstantInt::get(Type::getInt32Ty(Ctx), 0U), XVal); - OpenMPIRBuilder::AtomicOpValue X = {XVal, false, false}; - OpenMPIRBuilder::AtomicOpValue V = {VVal, false, false}; + OpenMPIRBuilder::AtomicOpValue X = {XVal, Int32, false, false}; + OpenMPIRBuilder::AtomicOpValue V = {VVal, Int32, false, false}; AtomicOrdering AO = AtomicOrdering::Monotonic; ConstantInt *Expr = ConstantInt::get(Type::getInt32Ty(Ctx), 1U); AtomicRMWInst::BinOp RMWOp = AtomicRMWInst::Add; diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -930,9 +930,13 @@ llvm::DebugLoc(diLoc)); llvm::AtomicOrdering AO = convertAtomicOrdering(readOp.memory_order()); llvm::Value *x = moduleTranslation.lookupValue(readOp.x()); + Type xTy = readOp.x().getType().cast().getElementType(); llvm::Value *v = moduleTranslation.lookupValue(readOp.v()); - llvm::OpenMPIRBuilder::AtomicOpValue V = {v, false, false}; - llvm::OpenMPIRBuilder::AtomicOpValue X = {x, false, false}; + Type vTy = readOp.v().getType().cast().getElementType(); + llvm::OpenMPIRBuilder::AtomicOpValue V = { + v, moduleTranslation.convertType(vTy), false, false}; + llvm::OpenMPIRBuilder::AtomicOpValue X = { + x, moduleTranslation.convertType(xTy), false, false}; builder.restoreIP(ompBuilder->createAtomicRead(ompLoc, X, V, AO)); return success(); } @@ -954,7 +958,8 @@ llvm::AtomicOrdering ao = convertAtomicOrdering(writeOp.memory_order()); llvm::Value *expr = moduleTranslation.lookupValue(writeOp.value()); llvm::Value *dest = moduleTranslation.lookupValue(writeOp.address()); - llvm::OpenMPIRBuilder::AtomicOpValue x = {dest, /*isSigned=*/false, + llvm::Type *ty = moduleTranslation.convertType(writeOp.value().getType()); + llvm::OpenMPIRBuilder::AtomicOpValue x = {dest, ty, /*isSigned=*/false, /*isVolatile=*/false}; builder.restoreIP(ompBuilder->createAtomicWrite(ompLoc, x, expr, ao)); return success();