diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -674,7 +674,8 @@ const auto &itemList = std::get<0>(ioImpliedDo.t); const auto &control = std::get<1>(ioImpliedDo.t); const auto &loopSym = *control.name.thing.thing.symbol; - mlir::Value loopVar = converter.getSymbolAddress(loopSym); + mlir::Value loopVar = fir::getBase(converter.genExprAddr( + Fortran::evaluate::AsGenericExpr(loopSym).value(), stmtCtx)); auto genControlValue = [&](const Fortran::parser::ScalarIntExpr &expr) { mlir::Value v = fir::getBase( converter.genExprValue(*Fortran::semantics::GetExpr(expr), stmtCtx)); @@ -701,8 +702,8 @@ loc, lowerValue, upperValue, stepValue, /*unordered=*/false, /*finalCountValue=*/true); builder.setInsertionPointToStart(doLoopOp.getBody()); - mlir::Value lcv = builder.createConvert(loc, converter.genType(loopSym), - doLoopOp.getInductionVar()); + mlir::Value lcv = builder.createConvert( + loc, fir::unwrapRefType(loopVar.getType()), doLoopOp.getInductionVar()); builder.create(loc, lcv, loopVar); genItemList(ioImpliedDo); builder.setInsertionPointToEnd(doLoopOp.getBody()); @@ -711,7 +712,7 @@ builder.create(loc, result); builder.setInsertionPointAfter(doLoopOp); // The loop control variable may be used after the loop. - lcv = builder.createConvert(loc, converter.genType(loopSym), + lcv = builder.createConvert(loc, fir::unwrapRefType(loopVar.getType()), doLoopOp.getResult(0)); builder.create(loc, lcv, loopVar); return; @@ -722,8 +723,9 @@ auto iterWhileOp = builder.create( loc, lowerValue, upperValue, stepValue, ok, /*finalCountValue*/ true); builder.setInsertionPointToStart(iterWhileOp.getBody()); - mlir::Value lcv = builder.createConvert(loc, converter.genType(loopSym), - iterWhileOp.getInductionVar()); + mlir::Value lcv = + builder.createConvert(loc, fir::unwrapRefType(loopVar.getType()), + iterWhileOp.getInductionVar()); builder.create(loc, lcv, loopVar); ok = iterWhileOp.getIterateVar(); mlir::Value falseValue = @@ -756,7 +758,7 @@ ok = iterWhileOp.getResult(1); builder.setInsertionPointAfter(iterWhileOp); // The loop control variable may be used after the loop. - lcv = builder.createConvert(loc, converter.genType(loopSym), + lcv = builder.createConvert(loc, fir::unwrapRefType(loopVar.getType()), iterWhileOp.getResult(0)); builder.create(loc, lcv, loopVar); } diff --git a/flang/test/Lower/io-implied-do-fixes.f90 b/flang/test/Lower/io-implied-do-fixes.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/io-implied-do-fixes.f90 @@ -0,0 +1,48 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: func @_QPido1 +! CHECK: %[[J_REF_ADDR:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFido1Eiptr.addr"} +! CHECK: %[[J_ADDR:.*]] = fir.load %[[J_REF_ADDR]] : !fir.ref> +! CHECK: %[[J_VAL_FINAL:.*]] = fir.do_loop %[[J_VAL:.*]] = %{{.*}} to %{{.*}} step %{{.*}} -> index { +! CHECK: %[[J_VAL_CVT1:.*]] = fir.convert %[[J_VAL]] : (index) -> i32 +! CHECK: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.ptr +! CHECK: } +! CHECK: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]] : (index) -> i32 +! CHECK: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.ptr +subroutine ido1 + integer, pointer :: iptr + integer, target :: itgt + iptr => itgt + print *, (iptr,iptr=1,10) +end subroutine + +! CHECK-LABEL: func @_QPido2 +! CHECK: %[[J_REF_ADDR:.*]] = fir.alloca !fir.heap {uniq_name = "_QFido2Eiptr.addr"} +! CHECK: %[[J_ADDR:.*]] = fir.load %[[J_REF_ADDR]] : !fir.ref> +! CHECK: %[[J_VAL_FINAL:.*]] = fir.do_loop %[[J_VAL:.*]] = %{{.*}} to %{{.*}} step %{{.*}} -> index { +! CHECK: %[[J_VAL_CVT1:.*]] = fir.convert %[[J_VAL]] : (index) -> i32 +! CHECK: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.heap +! CHECK: } +! CHECK: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]] : (index) -> i32 +! CHECK: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.heap +subroutine ido2 + integer, allocatable :: iptr + allocate(iptr) + print *, (iptr,iptr=1,10) +end subroutine + +! CHECK-LABEL: func @_QPido3 +! CHECK: %[[J_REF_ADDR:.*]] = fir.alloca !fir.heap {uniq_name = "_QFido3Ej.addr"} +! CHECK: %[[J_ADDR:.*]] = fir.load %[[J_REF_ADDR]] : !fir.ref> +! CHECK: %[[J_VAL_FINAL:.*]]:2 = fir.iterate_while (%[[J_VAL:.*]] = %{{.*}} to %{{.*}} step %{{.*}}) and ({{.*}}) -> (index, i1) { +! CHECK: %[[J_VAL_CVT1:.*]] = fir.convert %[[J_VAL]] : (index) -> i32 +! CHECK: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.heap +! CHECK: } +! CHECK: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]]#0 : (index) -> i32 +! CHECK: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.heap