Skip to content

Commit 5524ecd

Browse files
Krish GuptaKrish Gupta
authored andcommitted
[OpenMP][Flang] Fix atomic size for complex types
Fixes #165184 In OMPIRBuilder::createAtomicRead() and createAtomicWrite(), the size parameter for __atomic_load/__atomic_store was incorrectly computed from the pointer type instead of the pointee (element) type. On 64-bit systems, this resulted in only 8 bytes being transferred regardless of the actual struct size. Changed both functions to use XElemTy (element type) instead of the pointer type when computing LoadSize. This ensures the full struct is transferred.
1 parent 4678f16 commit 5524ecd

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
! Test lowering of atomic read to LLVM IR for complex types.
2+
! This is a regression test for issue #165184.
3+
4+
! RUN: %flang_fc1 -emit-llvm -fopenmp -o - %s | FileCheck %s
5+
6+
! Test that atomic read operations with complex types emit the correct
7+
! size parameter to __atomic_load:
8+
! - complex(4) (8 bytes total): should call __atomic_load(i64 8, ...)
9+
! - complex(8) (16 bytes total): should call __atomic_load(i64 16, ...)
10+
11+
program atomic_read_complex
12+
implicit none
13+
14+
! Test complex(4) - single precision (8 bytes)
15+
complex(4) :: c41, c42
16+
! Test complex(8) - double precision (16 bytes)
17+
complex(8) :: c81, c82
18+
19+
c42 = (1.0_4, 1.0_4)
20+
c82 = (1.0_8, 1.0_8)
21+
22+
! CHECK-LABEL: define {{.*}} @_QQmain
23+
24+
! Single precision complex: 8 bytes
25+
! CHECK: call void @__atomic_load(i64 8, ptr {{.*}}, ptr {{.*}}, i32 {{.*}})
26+
!$omp atomic read
27+
c41 = c42
28+
29+
! Double precision complex: 16 bytes (this was broken before the fix)
30+
! CHECK: call void @__atomic_load(i64 16, ptr {{.*}}, ptr {{.*}}, i32 {{.*}})
31+
!$omp atomic read
32+
c81 = c82
33+
34+
end program atomic_read_complex
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
! Test lowering of atomic write to LLVM IR for complex types.
2+
! This is a regression test for issue #165184.
3+
4+
! RUN: %flang_fc1 -emit-llvm -fopenmp -o - %s | FileCheck %s
5+
6+
! Test that atomic write operations with complex types emit the correct
7+
! size parameter to __atomic_store:
8+
! - complex(4) (8 bytes total): should call __atomic_store(i64 8, ...)
9+
! - complex(8) (16 bytes total): should call __atomic_store(i64 16, ...)
10+
11+
program atomic_write_complex
12+
implicit none
13+
14+
! Test complex(4) - single precision (8 bytes)
15+
complex(4) :: c41, c42
16+
! Test complex(8) - double precision (16 bytes)
17+
complex(8) :: c81, c82
18+
19+
c42 = (1.0_4, 1.0_4)
20+
c82 = (1.0_8, 1.0_8)
21+
22+
! CHECK-LABEL: define {{.*}} @_QQmain
23+
24+
! Single precision complex: 8 bytes
25+
! CHECK: call void @__atomic_store(i64 8, ptr {{.*}}, ptr {{.*}}, i32 {{.*}})
26+
!$omp atomic write
27+
c41 = c42
28+
29+
! Double precision complex: 16 bytes (this was broken before the fix)
30+
! CHECK: call void @__atomic_store(i64 16, ptr {{.*}}, ptr {{.*}}, i32 {{.*}})
31+
!$omp atomic write
32+
c81 = c82
33+
34+
end program atomic_write_complex

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9338,9 +9338,8 @@ OpenMPIRBuilder::createAtomicRead(const LocationDescription &Loc,
93389338
// target does not support `atomicrmw` of the size of the struct
93399339
LoadInst *OldVal = Builder.CreateLoad(XElemTy, X.Var, "omp.atomic.read");
93409340
OldVal->setAtomic(AO);
9341-
const DataLayout &LoadDL = OldVal->getModule()->getDataLayout();
9342-
unsigned LoadSize =
9343-
LoadDL.getTypeStoreSize(OldVal->getPointerOperand()->getType());
9341+
const DataLayout &DL = OldVal->getModule()->getDataLayout();
9342+
unsigned LoadSize = DL.getTypeStoreSize(XElemTy);
93449343
OpenMPIRBuilder::AtomicInfo atomicInfo(
93459344
&Builder, XElemTy, LoadSize * 8, LoadSize * 8, OldVal->getAlign(),
93469345
OldVal->getAlign(), true /* UseLibcall */, AllocaIP, X.Var);
@@ -9384,9 +9383,8 @@ OpenMPIRBuilder::createAtomicWrite(const LocationDescription &Loc,
93849383
XSt->setAtomic(AO);
93859384
} else if (XElemTy->isStructTy()) {
93869385
LoadInst *OldVal = Builder.CreateLoad(XElemTy, X.Var, "omp.atomic.read");
9387-
const DataLayout &LoadDL = OldVal->getModule()->getDataLayout();
9388-
unsigned LoadSize =
9389-
LoadDL.getTypeStoreSize(OldVal->getPointerOperand()->getType());
9386+
const DataLayout &DL = OldVal->getModule()->getDataLayout();
9387+
unsigned LoadSize = DL.getTypeStoreSize(XElemTy);
93909388
OpenMPIRBuilder::AtomicInfo atomicInfo(
93919389
&Builder, XElemTy, LoadSize * 8, LoadSize * 8, OldVal->getAlign(),
93929390
OldVal->getAlign(), true /* UseLibcall */, AllocaIP, X.Var);

0 commit comments

Comments
 (0)