@@ -4534,6 +4534,87 @@ TEST_F(OpenMPIRBuilderTest, OMPAtomicCompareCapture) {
45344534 EXPECT_FALSE (verifyModule (*M, &errs ()));
45354535}
45364536
4537+ TEST_F (OpenMPIRBuilderTest, OMPAtomicRWStructType) {
4538+ // Test for issue #165184: atomic read/write on struct types should use
4539+ // element type size, not pointer size.
4540+ OpenMPIRBuilder OMPBuilder (*M);
4541+ OMPBuilder.initialize ();
4542+ F->setName (" func" );
4543+ IRBuilder<> Builder (BB);
4544+
4545+ OpenMPIRBuilder::LocationDescription Loc ({Builder.saveIP (), DL});
4546+ BasicBlock *EntryBB = BB;
4547+ OpenMPIRBuilder::InsertPointTy AllocaIP (EntryBB,
4548+ EntryBB->getFirstInsertionPt ());
4549+
4550+ LLVMContext &Ctx = M->getContext ();
4551+
4552+ // Create a struct type {double, double} to simulate complex(8) - 16 bytes
4553+ StructType *Complex8Ty = StructType::create (
4554+ Ctx, {Type::getDoubleTy (Ctx), Type::getDoubleTy (Ctx)}, " complex" );
4555+
4556+ AllocaInst *XVal = Builder.CreateAlloca (Complex8Ty);
4557+ XVal->setName (" AtomicVar" );
4558+ OpenMPIRBuilder::AtomicOpValue X = {XVal, Complex8Ty, false , false };
4559+ AtomicOrdering AO = AtomicOrdering::SequentiallyConsistent;
4560+
4561+ // Create value to write: {1.0, 1.0}
4562+ Constant *Real = ConstantFP::get (Type::getDoubleTy (Ctx), 1.0 );
4563+ Constant *Imag = ConstantFP::get (Type::getDoubleTy (Ctx), 1.0 );
4564+ Constant *ValToWrite = ConstantStruct::get (Complex8Ty, {Real, Imag});
4565+
4566+ // Test atomic write
4567+ Builder.restoreIP (
4568+ OMPBuilder.createAtomicWrite (Loc, X, ValToWrite, AO, AllocaIP));
4569+
4570+ // Test atomic read
4571+ AllocaInst *VVal = Builder.CreateAlloca (Complex8Ty);
4572+ VVal->setName (" ReadDest" );
4573+ OpenMPIRBuilder::AtomicOpValue V = {VVal, Complex8Ty, false , false };
4574+ Value *ReadResult = nullptr ;
4575+
4576+ Builder.restoreIP (
4577+ OMPBuilder.createAtomicRead (Loc, X, ReadResult, AO, AllocaIP));
4578+
4579+ Builder.CreateRetVoid ();
4580+ OMPBuilder.finalize ();
4581+ EXPECT_FALSE (verifyModule (*M, &errs ()));
4582+
4583+ // Verify that __atomic_store and __atomic_load are called with size 16
4584+ bool FoundAtomicStore = false ;
4585+ bool FoundAtomicLoad = false ;
4586+
4587+ for (Function &Fn : *M) {
4588+ if (Fn.getName ().starts_with (" __atomic_store" )) {
4589+ // Check that first call to __atomic_store has size argument = 16
4590+ for (User *U : Fn.users ()) {
4591+ if (auto *CB = dyn_cast<CallBase>(U)) {
4592+ if (auto *SizeArg = dyn_cast<ConstantInt>(CB->getArgOperand (0 ))) {
4593+ EXPECT_EQ (SizeArg->getZExtValue (), 16U );
4594+ FoundAtomicStore = true ;
4595+ break ;
4596+ }
4597+ }
4598+ }
4599+ }
4600+ if (Fn.getName ().starts_with (" __atomic_load" )) {
4601+ // Check that first call to __atomic_load has size argument = 16
4602+ for (User *U : Fn.users ()) {
4603+ if (auto *CB = dyn_cast<CallBase>(U)) {
4604+ if (auto *SizeArg = dyn_cast<ConstantInt>(CB->getArgOperand (0 ))) {
4605+ EXPECT_EQ (SizeArg->getZExtValue (), 16U );
4606+ FoundAtomicLoad = true ;
4607+ break ;
4608+ }
4609+ }
4610+ }
4611+ }
4612+ }
4613+
4614+ EXPECT_TRUE (FoundAtomicStore) << " Did not find __atomic_store call" ;
4615+ EXPECT_TRUE (FoundAtomicLoad) << " Did not find __atomic_load call" ;
4616+ }
4617+
45374618TEST_F (OpenMPIRBuilderTest, CreateTeams) {
45384619 using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
45394620 OpenMPIRBuilder OMPBuilder (*M);
0 commit comments