@@ -290,6 +290,14 @@ static constexpr IntrinsicHandler handlers[]{
290290 {" atan2pi" , &I::genAtanpi},
291291 {" atand" , &I::genAtand},
292292 {" atanpi" , &I::genAtanpi},
293+ {" atomicadd_r2x2" ,
294+ &I::genAtomicAddVector,
295+ {{{" a" , asAddr}, {" v" , asAddr}}},
296+ false },
297+ {" atomicadd_r4x2" ,
298+ &I::genAtomicAddVector,
299+ {{{" a" , asAddr}, {" v" , asAddr}}},
300+ false },
293301 {" atomicaddd" , &I::genAtomicAdd, {{{" a" , asAddr}, {" v" , asValue}}}, false },
294302 {" atomicaddf" , &I::genAtomicAdd, {{{" a" , asAddr}, {" v" , asValue}}}, false },
295303 {" atomicaddi" , &I::genAtomicAdd, {{{" a" , asAddr}, {" v" , asValue}}}, false },
@@ -3168,6 +3176,48 @@ IntrinsicLibrary::genAtomicAddR2(mlir::Type resultType,
31683176 mlir::ArrayRef<int64_t >{0 });
31693177}
31703178
3179+ fir::ExtendedValue
3180+ IntrinsicLibrary::genAtomicAddVector (mlir::Type resultType,
3181+ llvm::ArrayRef<fir::ExtendedValue> args) {
3182+ assert (args.size () == 2 );
3183+ mlir::Value res = fir::AllocaOp::create (
3184+ builder, loc, fir::SequenceType::get ({2 }, resultType));
3185+ mlir::Value a = fir::getBase (args[0 ]);
3186+ if (mlir::isa<fir::BaseBoxType>(a.getType ())) {
3187+ a = fir::BoxAddrOp::create (builder, loc, a);
3188+ }
3189+ auto eleTy = fir::unwrapSequenceType (resultType);
3190+ auto loc = builder.getUnknownLoc ();
3191+ auto i32Ty = builder.getI32Type ();
3192+ auto vecTy = mlir::VectorType::get ({2 }, eleTy);
3193+ mlir::Type idxTy = builder.getIndexType ();
3194+ auto refTy = fir::ReferenceType::get (eleTy);
3195+ auto zero = builder.createIntegerConstant (loc, idxTy, 0 );
3196+ auto one = builder.createIntegerConstant (loc, idxTy, 1 );
3197+ auto v1Coord = fir::CoordinateOp::create (builder, loc, refTy,
3198+ fir::getBase (args[1 ]), zero);
3199+ auto v2Coord = fir::CoordinateOp::create (builder, loc, refTy,
3200+ fir::getBase (args[1 ]), one);
3201+ auto v1 = fir::LoadOp::create (builder, loc, v1Coord);
3202+ auto v2 = fir::LoadOp::create (builder, loc, v2Coord);
3203+ mlir::Value undef = mlir::LLVM::UndefOp::create (builder, loc, vecTy);
3204+ mlir::Value vec1 = mlir::LLVM::InsertElementOp::create (
3205+ builder, loc, undef, v1, builder.createIntegerConstant (loc, i32Ty, 0 ));
3206+ mlir::Value vec2 = mlir::LLVM::InsertElementOp::create (
3207+ builder, loc, vec1, v2, builder.createIntegerConstant (loc, i32Ty, 1 ));
3208+ auto add = genAtomBinOp (builder, loc, mlir::LLVM::AtomicBinOp::fadd, a, vec2);
3209+ auto r1 = mlir::LLVM::ExtractElementOp::create (
3210+ builder, loc, add, builder.createIntegerConstant (loc, i32Ty, 0 ));
3211+ auto r2 = mlir::LLVM::ExtractElementOp::create (
3212+ builder, loc, add, builder.createIntegerConstant (loc, i32Ty, 1 ));
3213+ auto c1 = fir::CoordinateOp::create (builder, loc, refTy, res, zero);
3214+ auto c2 = fir::CoordinateOp::create (builder, loc, refTy, res, one);
3215+ fir::StoreOp::create (builder, loc, r1, c1);
3216+ fir::StoreOp::create (builder, loc, r2, c2);
3217+ mlir::Value ext = builder.createIntegerConstant (loc, idxTy, 2 );
3218+ return fir::ArrayBoxValue (res, {ext});
3219+ }
3220+
31713221mlir::Value IntrinsicLibrary::genAtomicSub (mlir::Type resultType,
31723222 llvm::ArrayRef<mlir::Value> args) {
31733223 assert (args.size () == 2 );
0 commit comments