[flang-commits] [flang] [mlir] [Flang][OpenMP] Fix OpenMP data-mapping stride calculation (PR #225653)
via flang-commits
flang-commits at lists.llvm.org
Wed Sep 23 02:19:19 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-openmp
Author: Michael Klemm (mjklemm)
<details>
<summary>Changes</summary>
The calculation of strides when mapping individual sub-arrays from multi-dimensional array, the calcuation of the stride was missing such that when mapping all of the multi-dim array only a fraction was actually mapped.
---
Full diff: https://github.com/llvm/llvm-project/pull/225653.diff
5 Files Affected:
- (modified) flang/test/Integration/OpenMP/map-types-and-sizes.f90 (+14-10)
- (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+69-29)
- (added) mlir/test/Target/LLVMIR/omptarget-array-section-single-element-host.mlir (+40)
- (modified) mlir/test/Target/LLVMIR/omptarget-nested-ptr-record-type-mapping-host.mlir (+1-1)
- (modified) mlir/test/Target/LLVMIR/omptarget-record-type-with-ptr-member-host.mlir (+6-2)
``````````diff
diff --git a/flang/test/Integration/OpenMP/map-types-and-sizes.f90 b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
index 1a86c7186a1f5..242ac1cfa72de 100644
--- a/flang/test/Integration/OpenMP/map-types-and-sizes.f90
+++ b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
@@ -560,10 +560,14 @@ end subroutine mapType_common_block_members
!CHECK: %[[RESTORE_OFFSET:.*]] = add i64 %[[CALCULATE_DIM_SIZE]], 1
!CHECK: %[[MEMBER_BASE_ADDR_SIZE:.*]] = mul i64 1, %[[RESTORE_OFFSET]]
!CHECK: %[[DESC_BASE_ADDR_DATA_SIZE:.*]] = mul i64 %[[MEMBER_BASE_ADDR_SIZE]], 4
+!CHECK: %[[ADDR_DATA_OFF1:.*]] = mul i64 0, %{{.*}}
+!CHECK: %[[ADDR_DATA_OFF:.*]] = add i64 0, %[[ADDR_DATA_OFF1]]
!CHECK: %[[LOAD_ADDR_DATA:.*]] = load ptr, ptr %[[MEMBER_DESCRIPTOR_BASE_ADDR]], align 8
-!CHECK: %[[GEP_ADDR_DATA:.*]] = getelementptr inbounds i32, ptr %[[LOAD_ADDR_DATA]], i64 0
+!CHECK: %[[GEP_ADDR_DATA:.*]] = getelementptr inbounds i8, ptr %[[LOAD_ADDR_DATA]], i64 %[[ADDR_DATA_OFF]]
+!CHECK: %[[ADDR_DATA2_OFF1:.*]] = mul i64 0, %{{.*}}
+!CHECK: %[[ADDR_DATA2_OFF:.*]] = add i64 0, %[[ADDR_DATA2_OFF1]]
!CHECK: %[[LOAD_ADDR_DATA2:.*]] = load ptr, ptr %[[MEMBER_DESCRIPTOR_BASE_ADDR]], align 8
-!CHECK: %[[GEP_ADDR_DATA2:.*]] = getelementptr inbounds i32, ptr %[[LOAD_ADDR_DATA2]], i64 0
+!CHECK: %[[GEP_ADDR_DATA2:.*]] = getelementptr inbounds i8, ptr %[[LOAD_ADDR_DATA2]], i64 %[[ADDR_DATA2_OFF]]
!CHECK: %[[MEMBER_ACCESS_ADDR_END:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[MEMBER_ACCESS]], i64 1
!CHECK: %[[MEMBER_ACCESS_ADDR_INT:.*]] = ptrtoaddr ptr %[[MEMBER_ACCESS_ADDR_END]] to i64
!CHECK: %[[MEMBER_ACCESS_ADDR_BEGIN:.*]] = ptrtoaddr ptr %[[MEMBER_ACCESS]] to i64
@@ -620,7 +624,7 @@ end subroutine mapType_common_block_members
!CHECK: %[[DTYPE_BASE_ADDR_LOAD_3:.*]] = load ptr, ptr %[[DTYPE_BASE_ADDR_ACCESS_3]], align 8
!CHECK: %[[DTYPE_BASE_ADDR_LOAD_3_1:.*]] = load ptr, ptr %[[DTYPE_BASE_ADDR_ACCESS_3]], align 8
!CHECK: %[[LOAD_DTYPE_DESC_MEMBER:.*]] = load ptr, ptr %[[DTYPE_ALLOCA_MEMBER_BASE_ADDR_ACCESS]], align 8
-!CHECK: %[[MEMBER_ARRAY_OFFSET:.*]] = getelementptr inbounds i32, ptr %[[LOAD_DTYPE_DESC_MEMBER]], i64 0
+!CHECK: %[[MEMBER_ARRAY_OFFSET:.*]] = getelementptr inbounds i8, ptr %[[LOAD_DTYPE_DESC_MEMBER]], i64 %{{.*}}
!CHECK: %[[SIZE_CALC_1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[DTYPE_DESC_ALLOCA_3]], i32 1
!CHECK: %[[SIZE_CALC_2:.*]] = ptrtoaddr ptr %[[SIZE_CALC_1]] to i64
!CHECK: %[[SIZE_CALC_3:.*]] = ptrtoaddr ptr %[[DTYPE_DESC_ALLOCA_3]] to i64
@@ -670,7 +674,7 @@ end subroutine mapType_common_block_members
!CHECK: %[[LOAD_BASE_ADDR:.*]] = load ptr, ptr %[[DTYPE_DESC_BASE_ADDR]], align 8
!CHECK: %[[LOAD_BASE_ADDR2:.*]] = load ptr, ptr %[[DTYPE_DESC_BASE_ADDR]], align 8
!CHECK: %[[LOAD_DESC_MEMBER_BASE_ADDR:.*]] = load ptr, ptr %[[MAPPED_MEMBER_BASE_ADDR_ACCESS]], align 8
-!CHECK: %[[ARRAY_OFFSET:.*]] = getelementptr inbounds i32, ptr %[[LOAD_DESC_MEMBER_BASE_ADDR]], i64 0
+!CHECK: %[[ARRAY_OFFSET:.*]] = getelementptr inbounds i8, ptr %[[LOAD_DESC_MEMBER_BASE_ADDR]], i64 %{{.*}}
!CHECK: %[[NULL_CMP:.*]] = icmp eq ptr %[[LOAD_BASE_ADDR2]], null
!CHECK: %[[SEL_SZ:.*]] = select i1 %[[NULL_CMP]], i64 0, i64 240
!CHECK: %[[NULL_CMP2:.*]] = icmp eq ptr %[[ARRAY_OFFSET]], null
@@ -707,9 +711,9 @@ end subroutine mapType_common_block_members
!CHECK: %[[SIZE_ZERO_CMP:.*]] = icmp eq i64 %[[ALLOCATABLE_MEMBER_SIZE_CALC_5]], 0
!CHECK: %[[SIZE_ADJUSTED:.*]] = select i1 %[[SIZE_ZERO_CMP]], i64 1, i64 %[[ALLOCATABLE_MEMBER_SIZE_CALC_5]]
!CHECK: %[[LOAD_BASE_ADDR:.*]] = load ptr, ptr %[[NESTED_MEMBER_BASE_ADDR_ACCESS]], align 8
-!CHECK: %[[ARR_OFFS:.*]] = getelementptr inbounds i32, ptr %[[LOAD_BASE_ADDR]], i64 0
+!CHECK: %[[ARR_OFFS:.*]] = getelementptr inbounds i8, ptr %[[LOAD_BASE_ADDR]], i64 %{{.*}}
!CHECK: %[[LOAD_BASE_ADDR:.*]] = load ptr, ptr %[[NESTED_MEMBER_BASE_ADDR_ACCESS]], align 8
-!CHECK: %[[ARR_OFFS2:.*]] = getelementptr inbounds i32, ptr %[[LOAD_BASE_ADDR]], i64 0
+!CHECK: %[[ARR_OFFS2:.*]] = getelementptr inbounds i8, ptr %[[LOAD_BASE_ADDR]], i64 %{{.*}}
!CHECK: %[[NESTED_MEMBER_BASE_ADDR_ACCESS_2:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[NESTED_MEMBER_ACCESS]], i64 1
!CHECK: %[[DTYPE_SEGMENT_SIZE_CALC_1:.*]] = ptrtoaddr ptr %[[NESTED_MEMBER_BASE_ADDR_ACCESS_2]] to i64
!CHECK: %[[DTYPE_SEGMENT_SIZE_CALC_2:.*]] = ptrtoaddr ptr %[[NESTED_MEMBER_ACCESS]] to i64
@@ -777,13 +781,13 @@ end subroutine mapType_common_block_members
!CHECK: %[[SIZE_ZERO_CMP_2:.*]] = icmp eq i64 %[[SZ_CALC_4_2]], 0
!CHECK: %[[SIZE_ADJUSTED_2:.*]] = select i1 %[[SIZE_ZERO_CMP_2]], i64 1, i64 %[[SZ_CALC_4_2]]
!CHECK: %[[LOAD_OFF_PTR:.*]] = load ptr, ptr %[[OFF_PTR_2]], align 8
-!CHECK: %[[ARR_OFFS:.*]] = getelementptr inbounds %_QFmaptype_nested_derived_type_member_idxTvertexes, ptr %[[LOAD_OFF_PTR]], i64 0
+!CHECK: %[[ARR_OFFS:.*]] = getelementptr inbounds i8, ptr %[[LOAD_OFF_PTR]], i64 %{{.*}}
!CHECK: %[[LOAD_ARR_OFFS:.*]] = load ptr, ptr %[[OFF_PTR_4]], align 8
-!CHECK: %[[ARR_OFFS_1:.*]] = getelementptr inbounds i32, ptr %[[LOAD_ARR_OFFS]], i64 0
+!CHECK: %[[ARR_OFFS_1:.*]] = getelementptr inbounds i8, ptr %[[LOAD_ARR_OFFS]], i64 %{{.*}}
!CHECK: %[[LOAD_OFF_PTR:.*]] = load ptr, ptr %[[OFF_PTR_2]], align 8
-!CHECK: %[[ARR_OFFS_2:.*]] = getelementptr inbounds %_QFmaptype_nested_derived_type_member_idxTvertexes, ptr %[[LOAD_OFF_PTR]], i64 0
+!CHECK: %[[ARR_OFFS_2:.*]] = getelementptr inbounds i8, ptr %[[LOAD_OFF_PTR]], i64 %{{.*}}
!CHECK: %[[LOAD_ARR_OFFS:.*]] = load ptr, ptr %[[OFF_PTR_4]], align 8
-!CHECK: %[[ARR_OFFS_3:.*]] = getelementptr inbounds i32, ptr %[[LOAD_ARR_OFFS]], i64 0
+!CHECK: %[[ARR_OFFS_3:.*]] = getelementptr inbounds i8, ptr %[[LOAD_ARR_OFFS]], i64 %{{.*}}
!CHECK: %[[SZ_CALC_1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[OFF_PTR_1]], i64 1
!CHECK: %[[SZ_CALC_2:.*]] = ptrtoaddr ptr %[[SZ_CALC_1]] to i64
!CHECK: %[[SZ_CALC_3:.*]] = ptrtoaddr ptr %[[OFF_PTR_1]] to i64
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index e5e3e0cc6d944..bc1c768d891dc 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -7643,8 +7643,9 @@ static omp::MapInfoOp getFirstOrLastMappedMemberPtr(omp::MapInfoOp mapInfo,
static std::vector<llvm::Value *>
calculateBoundsOffset(LLVM::ModuleTranslation &moduleTranslation,
llvm::IRBuilderBase &builder, bool isArrayTy,
- OperandRange bounds) {
+ OperandRange bounds, bool &isByteOffset) {
std::vector<llvm::Value *> idx;
+ isByteOffset = false;
// There's no bounds to calculate an offset from, we can safely
// ignore and return no indices.
if (bounds.empty())
@@ -7663,31 +7664,68 @@ calculateBoundsOffset(LLVM::ModuleTranslation &moduleTranslation,
}
}
} else {
- // If we do not have an array type, but we have bounds, then we're dealing
- // with a pointer that's being treated like an array and we have the
- // underlying type e.g. an i32, or f64 etc, e.g. a fortran descriptor base
- // address (pointer pointing to the actual data) so we must caclulate the
- // offset using a single index which the following loop attempts to
- // compute using the standard column-major algorithm e.g for a 3D array:
- //
- // ((((c_idx * b_len) + b_idx) * a_len) + a_idx)
- //
- // It is of note that it's doing column-major rather than row-major at the
- // moment, but having a way for the frontend to indicate which major format
- // to use or standardizing/canonicalizing the order of the bounds to compute
- // the offset may be useful in the future when there's other frontends with
- // different formats.
- for (int i = bounds.size() - 1; i >= 0; --i) {
- if (auto boundOp = dyn_cast_if_present<omp::MapBoundsOp>(
- bounds[i].getDefiningOp())) {
- if (i == ((int)bounds.size() - 1))
- idx.emplace_back(
- moduleTranslation.lookupValue(boundOp.getLowerBound()));
- else
- idx.back() = builder.CreateAdd(
- builder.CreateMul(idx.back(), moduleTranslation.lookupValue(
- boundOp.getExtent())),
- moduleTranslation.lookupValue(boundOp.getLowerBound()));
+ // Check if Fortran descriptors provide strides in bytes
+ llvm::Value *offset = builder.getInt64(0);
+ for (Value bound : bounds) {
+ auto boundOp =
+ dyn_cast_if_present<omp::MapBoundsOp>(bound.getDefiningOp());
+ if (!boundOp || !boundOp.getStride())
+ continue;
+ // Fortran descriptors provide strides in bytes; when that's the case the
+ // accumulated offset is a byte offset and must be consumed with a byte
+ // (i8) GEP at the call site to avoid double-scaling by the element size.
+ isByteOffset = boundOp.getStrideInBytes();
+ }
+ if (isByteOffset) {
+ for (Value bound : bounds) {
+ auto boundOp =
+ dyn_cast_if_present<omp::MapBoundsOp>(bound.getDefiningOp());
+ if (!boundOp || !boundOp.getStride())
+ continue;
+ // If we do not have an array type, but we have bounds, then we're
+ // dealing with a pointer that's being treated like an array
+ // and we have the underlying type e.g. an i32, or f64 etc,
+ // e.g. a fortran descriptor base address (pointer pointing to
+ // the actual data) and we know that the offset stride is expressed
+ // in bytes, so we must calculate the offset to the first mapped
+ // element as a single linear index into that data.
+ //
+ // Each bound carries the stride between consecutive elements along its
+ // dimension, so the linear offset to the section's origin is:
+ //
+ // offset += lower_bound[d] * stride[d]
+ llvm::Value *lb =
+ moduleTranslation.lookupValue(boundOp.getLowerBound());
+ llvm::Value *stride =
+ moduleTranslation.lookupValue(boundOp.getStride());
+ offset = builder.CreateAdd(offset, builder.CreateMul(lb, stride));
+ }
+ idx.push_back(offset);
+ } else {
+ for (int i = bounds.size() - 1; i >= 0; --i) {
+ if (auto boundOp = dyn_cast_if_present<omp::MapBoundsOp>(
+ bounds[i].getDefiningOp())) {
+ // If the stride in bytes is unknown, so we must calculate the
+ // offset using a single index which the following loop attempts to
+ // compute using the standard column-major algorithm e.g for a 3D
+ // array:
+ //
+ // ((((c_idx * b_len) + b_idx) * a_len) + a_idx)
+ //
+ // It is of note that it's doing column-major rather than row-major at
+ // the moment, but having a way for the frontend to indicate which
+ // major format to use or standardizing/canonicalizing the order of
+ // the bounds to compute the offset may be useful in the future when
+ // there's other frontends with different formats.
+ if (i == ((int)bounds.size() - 1))
+ idx.emplace_back(
+ moduleTranslation.lookupValue(boundOp.getLowerBound()));
+ else
+ idx.back() = builder.CreateAdd(
+ builder.CreateMul(idx.back(), moduleTranslation.lookupValue(
+ boundOp.getExtent())),
+ moduleTranslation.lookupValue(boundOp.getLowerBound()));
+ }
}
}
}
@@ -8222,15 +8260,17 @@ createAlteredByCaptureMap(MapInfoData &mapData,
switch (captureKind) {
case omp::VariableCaptureKind::ByRef: {
llvm::Value *newV = mapData.Pointers[i];
+ bool isByteOffset = false;
std::vector<llvm::Value *> offsetIdx = calculateBoundsOffset(
moduleTranslation, builder, mapData.BaseType[i]->isArrayTy(),
- mapOp.getBounds());
+ mapOp.getBounds(), isByteOffset);
if (isPtrTy)
newV = builder.CreateLoad(builder.getPtrTy(), newV);
if (!offsetIdx.empty())
- newV = builder.CreateInBoundsGEP(mapData.BaseType[i], newV, offsetIdx,
- "array_offset");
+ newV = builder.CreateInBoundsGEP(isByteOffset ? builder.getInt8Ty()
+ : mapData.BaseType[i],
+ newV, offsetIdx, "array_offset");
mapData.Pointers[i] = newV;
} break;
case omp::VariableCaptureKind::ByCopy: {
diff --git a/mlir/test/Target/LLVMIR/omptarget-array-section-single-element-host.mlir b/mlir/test/Target/LLVMIR/omptarget-array-section-single-element-host.mlir
new file mode 100644
index 0000000000000..4bb188c846480
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/omptarget-array-section-single-element-host.mlir
@@ -0,0 +1,40 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// This test checks that the begin-pointer offset for a map of a single element
+// of a multi-dimensional Fortran array (accessed through a descriptor, so the
+// map has a non-array base type and carries per-dimension bounds) is linearized
+// using the per-dimension strides carried on the omp.map.bounds operations,
+// rather than the section extents. For a single-element section all extents are
+// 1, so an extent-based fold would collapse every element onto the same begin
+// pointer. The offset must instead be:
+//
+// sum_d lower_bound[d] * stride[d]
+//
+// Here the strides are provided in bytes (stride_in_bytes(true)) with distinct
+// values 8 and 256, so the offset is lb0*8 + lb1*256 applied through a byte
+// (i8) GEP.
+
+module attributes {omp.is_target_device = false, omp.target_triples = ["amdgcn-amd-amdhsa"]} {
+ llvm.func @single_element_2d_map(%arg0: !llvm.ptr, %lb0: i64, %lb1: i64) {
+ %c1 = llvm.mlir.constant(1 : i64) : i64
+ %stride0 = llvm.mlir.constant(8 : i64) : i64
+ %stride1 = llvm.mlir.constant(256 : i64) : i64
+ %baddr = llvm.getelementptr %arg0[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>
+ %b0 = omp.map.bounds lower_bound(%lb0 : i64) upper_bound(%lb0 : i64) extent(%c1 : i64) stride(%stride0 : i64) start_idx(%c1 : i64) stride_in_bytes(true)
+ %b1 = omp.map.bounds lower_bound(%lb1 : i64) upper_bound(%lb1 : i64) extent(%c1 : i64) stride(%stride1 : i64) start_idx(%c1 : i64) stride_in_bytes(true)
+ %m0 = omp.map.info var_ptr(%arg0 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>) map_clauses(tofrom) capture(ByRef) var_ptr_ptr(%baddr : !llvm.ptr, f64) bounds(%b0, %b1) name("arr(i,j)") -> !llvm.ptr
+ %m1 = omp.map.info var_ptr(%arg0 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>) map_clauses(tofrom) capture(ByRef) members(%m0 : [0] : !llvm.ptr) name("arr(i,j)") -> !llvm.ptr
+ omp.target kernel_type(generic) map_entries(%m0 -> %a0, %m1 -> %a1 : !llvm.ptr, !llvm.ptr) {
+ omp.terminator
+ }
+ llvm.return
+ }
+}
+
+// CHECK: define void @single_element_2d_map(ptr %[[ARG0:.*]], i64 %[[LB0:.*]], i64 %[[LB1:.*]])
+// CHECK: %[[T0:.*]] = mul i64 %[[LB0]], 8
+// CHECK: %[[OFF0:.*]] = add i64 0, %[[T0]]
+// CHECK: %[[T1:.*]] = mul i64 %[[LB1]], 256
+// CHECK: %[[OFF:.*]] = add i64 %[[OFF0]], %[[T1]]
+// CHECK: %[[BASE:.*]] = load ptr, ptr %{{.*}}, align 8
+// CHECK: %[[ARR_OFFSET:.*]] = getelementptr inbounds i8, ptr %[[BASE]], i64 %[[OFF]]
\ No newline at end of file
diff --git a/mlir/test/Target/LLVMIR/omptarget-nested-ptr-record-type-mapping-host.mlir b/mlir/test/Target/LLVMIR/omptarget-nested-ptr-record-type-mapping-host.mlir
index 82ed7872e29b0..3552f9226453a 100644
--- a/mlir/test/Target/LLVMIR/omptarget-nested-ptr-record-type-mapping-host.mlir
+++ b/mlir/test/Target/LLVMIR/omptarget-nested-ptr-record-type-mapping-host.mlir
@@ -36,7 +36,7 @@ module attributes {omp.is_target_device = false, omp.target_triples = ["amdgcn-a
// CHECK: %[[NESTED_STRUCT_PTR_MEMBER_GEP:.*]] = getelementptr { float, [10 x i32], { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, i32 }, ptr %[[NESTED_DTYPE_MEMBER_GEP]], i32 0, i32 2
// CHECK: %[[NESTED_STRUCT_PTR_MEMBER_BADDR_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[NESTED_STRUCT_PTR_MEMBER_GEP]], i32 0, i32 0
// CHECK: %[[NESTED_STRUCT_PTR_MEMBER_BADDR_LOAD:.*]] = load ptr, ptr %[[NESTED_STRUCT_PTR_MEMBER_BADDR_GEP]], align 8
-// CHECK: %[[ARR_OFFSET:.*]] = getelementptr inbounds i32, ptr %[[NESTED_STRUCT_PTR_MEMBER_BADDR_LOAD]], i64 0
+// CHECK: %[[ARR_OFFSET:.*]] = getelementptr inbounds i8, ptr %[[NESTED_STRUCT_PTR_MEMBER_BADDR_LOAD]], i64 0
// CHECK: %[[DTYPE_SIZE_SEGMENT_CALC_1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[NESTED_STRUCT_PTR_MEMBER_GEP]], i64 1
// CHECK: %[[DTYPE_SIZE_SEGMENT_CALC_2:.*]] = ptrtoaddr ptr %[[DTYPE_SIZE_SEGMENT_CALC_1]] to i64
// CHECK: %[[DTYPE_SIZE_SEGMENT_CALC_3:.*]] = ptrtoaddr ptr %[[NESTED_STRUCT_PTR_MEMBER_GEP]] to i64
diff --git a/mlir/test/Target/LLVMIR/omptarget-record-type-with-ptr-member-host.mlir b/mlir/test/Target/LLVMIR/omptarget-record-type-with-ptr-member-host.mlir
index c338761da3989..059715cd1c37d 100644
--- a/mlir/test/Target/LLVMIR/omptarget-record-type-with-ptr-member-host.mlir
+++ b/mlir/test/Target/LLVMIR/omptarget-record-type-with-ptr-member-host.mlir
@@ -81,10 +81,14 @@ module attributes {omp.is_target_device = false, omp.target_triples = ["amdgcn-a
// CHECK: %[[ARR_SECT_SIZE:.*]] = mul i64 %[[ARR_SECT_SIZE1]], 4
// CHECK: %[[ARR_SECT_SIZE_ZERO_CMP:.*]] = icmp eq i64 %[[ARR_SECT_SIZE]], 0
// CHECK: %[[ARR_SECT_SIZE_ADJUSTED:.*]] = select i1 %[[ARR_SECT_SIZE_ZERO_CMP]], i64 1, i64 %[[ARR_SECT_SIZE]]
+// CHECK: %[[FULL_ARR_OFFSET1:.*]] = mul i64 0, %{{.*}}
+// CHECK: %[[FULL_ARR_OFFSET:.*]] = add i64 0, %[[FULL_ARR_OFFSET1]]
// CHECK: %[[LFULL_ARR:.*]] = load ptr, ptr @full_arr, align 8
-// CHECK: %[[FULL_ARR_PTR:.*]] = getelementptr inbounds float, ptr %[[LFULL_ARR]], i64 0
+// CHECK: %[[FULL_ARR_PTR:.*]] = getelementptr inbounds i8, ptr %[[LFULL_ARR]], i64 %[[FULL_ARR_OFFSET]]
+// CHECK: %[[ARR_SECT_OFFSET1:.*]] = mul i64 %[[ARR_SECT_OFFSET2]], %{{.*}}
+// CHECK: %[[ARR_SECT_OFFSET:.*]] = add i64 0, %[[ARR_SECT_OFFSET1]]
// CHECK: %[[LARR_SECT:.*]] = load ptr, ptr @sect_arr, align 8
-// CHECK: %[[ARR_SECT_PTR:.*]] = getelementptr inbounds i32, ptr %[[LARR_SECT]], i64 %[[ARR_SECT_OFFSET2]]
+// CHECK: %[[ARR_SECT_PTR:.*]] = getelementptr inbounds i8, ptr %[[LARR_SECT]], i64 %[[ARR_SECT_OFFSET]]
// CHECK: %[[SCALAR_PTR_LOAD:.*]] = load ptr, ptr %[[SCALAR_BASE]], align 8
// CHECK: %[[NULL_CMP:.*]] = icmp eq ptr %[[FULL_ARR_PTR]], null
// CHECK: %[[IS_NULL:.*]] = select i1 %[[NULL_CMP]], i64 0, i64 %[[FULL_ARR_SIZE_ADJUSTED]]
``````````
</details>
https://github.com/llvm/llvm-project/pull/225653
More information about the flang-commits
mailing list