@@ -4534,6 +4534,85 @@ 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+
4575+ Builder.restoreIP (OMPBuilder.createAtomicRead (Loc, X, V, AO, AllocaIP));
4576+
4577+ Builder.CreateRetVoid ();
4578+ OMPBuilder.finalize ();
4579+ EXPECT_FALSE (verifyModule (*M, &errs ()));
4580+
4581+ // Verify that __atomic_store and __atomic_load are called with size 16
4582+ bool FoundAtomicStore = false ;
4583+ bool FoundAtomicLoad = false ;
4584+
4585+ for (Function &Fn : *M) {
4586+ if (Fn.getName ().starts_with (" __atomic_store" )) {
4587+ // Check that first call to __atomic_store has size argument = 16
4588+ for (User *U : Fn.users ()) {
4589+ if (auto *CB = dyn_cast<CallBase>(U)) {
4590+ if (auto *SizeArg = dyn_cast<ConstantInt>(CB->getArgOperand (0 ))) {
4591+ EXPECT_EQ (SizeArg->getZExtValue (), 16U );
4592+ FoundAtomicStore = true ;
4593+ break ;
4594+ }
4595+ }
4596+ }
4597+ }
4598+ if (Fn.getName ().starts_with (" __atomic_load" )) {
4599+ // Check that first call to __atomic_load has size argument = 16
4600+ for (User *U : Fn.users ()) {
4601+ if (auto *CB = dyn_cast<CallBase>(U)) {
4602+ if (auto *SizeArg = dyn_cast<ConstantInt>(CB->getArgOperand (0 ))) {
4603+ EXPECT_EQ (SizeArg->getZExtValue (), 16U );
4604+ FoundAtomicLoad = true ;
4605+ break ;
4606+ }
4607+ }
4608+ }
4609+ }
4610+ }
4611+
4612+ EXPECT_TRUE (FoundAtomicStore) << " Did not find __atomic_store call" ;
4613+ EXPECT_TRUE (FoundAtomicLoad) << " Did not find __atomic_load call" ;
4614+ }
4615+
45374616TEST_F (OpenMPIRBuilderTest, CreateTeams) {
45384617 using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
45394618 OpenMPIRBuilder OMPBuilder (*M);
@@ -7576,8 +7655,7 @@ TEST_F(OpenMPIRBuilderTest, CreateTaskgroup) {
75767655 // Checking the general structure of the IR generated is same as expected.
75777656 Instruction *GeneratedStoreInst = TaskgroupCall->getNextNode ();
75787657 EXPECT_EQ (GeneratedStoreInst, InternalStoreInst);
7579- Instruction *GeneratedLoad32 =
7580- GeneratedStoreInst->getNextNode ();
7658+ Instruction *GeneratedLoad32 = GeneratedStoreInst->getNextNode ();
75817659 EXPECT_EQ (GeneratedLoad32, InternalLoad32);
75827660 Instruction *GeneratedLoad128 = GeneratedLoad32->getNextNode ();
75837661 EXPECT_EQ (GeneratedLoad128, InternalLoad128);
0 commit comments