diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -2448,7 +2448,16 @@ rewriter.replaceOpWithNewOp(coor, ty, addr); return mlir::success(); } - auto casted = rewriter.create(loc, baseTy, addr); + // Cast the element address from void* to the derived type so that the + // derived type members can be addresses via a GEP using the index of + // components. + mlir::Type elementType = + baseTy.cast().getElementType(); + while (auto arrayTy = elementType.dyn_cast()) + elementType = arrayTy.getElementType(); + mlir::Type elementPtrType = mlir::LLVM::LLVMPointerType::get(elementType); + auto casted = + rewriter.create(loc, elementPtrType, addr); args.clear(); args.push_back(0); if (!coor.getLenParams().empty()) { diff --git a/flang/test/Fir/array-coor.fir b/flang/test/Fir/array-coor.fir --- a/flang/test/Fir/array-coor.fir +++ b/flang/test/Fir/array-coor.fir @@ -20,3 +20,26 @@ // CHECK: %[[t11:.*]] = getelementptr i8, ptr %[[t10]], i64 %[[t8]] // CHECK: %[[t12:.*]] = load double, ptr %[[t11]] // CHECK: ret double %[[t12]] + +func.func @test_array_coor_box_component_slice(%arg0: !fir.box>>) { + %c2 = arith.constant 2 : index + %c1 = arith.constant 1 : index + %0 = fir.field_index j, !fir.type + %1 = fir.slice %c1, %c2, %c1 path %0 : (index, index, index, !fir.field) -> !fir.slice<1> + %2 = fir.array_coor %arg0 [%1] %c2 : (!fir.box>>, !fir.slice<1>, index) -> !fir.ref + fir.call @take_int(%2) : (!fir.ref) -> () + return +} +func.func private @take_int(%arg0: !fir.ref) -> () + +// CHECK-LABEL: define void @test_array_coor_box_component_slice( +// CHECK-SAME: ptr %[[VAL_0:.*]]) +// CHECK: %[[VAL_1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[VAL_0]], i32 0, i32 7, i32 0, i32 2 +// CHECK: %[[VAL_2:.*]] = load i64, ptr %[[VAL_1]] +// CHECK: %[[VAL_3:.*]] = mul i64 1, %[[VAL_2]] +// CHECK: %[[VAL_4:.*]] = add i64 %[[VAL_3]], 0 +// CHECK: %[[VAL_5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[VAL_0]], i32 0, i32 0 +// CHECK: %[[VAL_6:.*]] = load ptr, ptr %[[VAL_5]] +// CHECK: %[[VAL_7:.*]] = getelementptr i8, ptr %[[VAL_6]], i64 %[[VAL_4]] +// CHECK: %[[VAL_8:.*]] = getelementptr %t, ptr %[[VAL_7]], i32 0, i32 1 +// CHECK: call void @take_int(ptr %[[VAL_8]])