diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp --- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp @@ -92,12 +92,26 @@ "variable to fir::ExtendedValue must not require cleanup"); if (lhs.isArray()) { + const bool rhsIsValue = fir::isa_trivial(fir::getBase(rhsExv).getType()); + if (rhsIsValue) { + // createBox can only be called for fir::ExtendedValue that are + // already in memory. Place the integer/real/complex/logical scalar + // in memory (convert to the LHS type so that i1 are allocated in + // a proper Fortran logical storage). + mlir::Type lhsValueType = lhs.getFortranElementType(); + mlir::Value rhsVal = + builder.createConvert(loc, lhsValueType, fir::getBase(rhsExv)); + mlir::Value temp = builder.create(loc, lhsValueType); + builder.create(loc, rhsVal, temp); + rhsExv = temp; + } + // Use the runtime for simplicity. An optimization pass will be added to // inline array assignment when profitable. auto to = fir::getBase(builder.createBox(loc, lhsExv)); auto from = fir::getBase(builder.createBox(loc, rhsExv)); bool cleanUpTemp = false; - if (mayAlias(rhs, lhs)) + if (!rhsIsValue && mayAlias(rhs, lhs)) std::tie(from, cleanUpTemp) = genTempFromSourceBox(loc, builder, from); auto toMutableBox = builder.createTemporary(loc, to.getType()); diff --git a/flang/test/HLFIR/assign-codegen.fir b/flang/test/HLFIR/assign-codegen.fir --- a/flang/test/HLFIR/assign-codegen.fir +++ b/flang/test/HLFIR/assign-codegen.fir @@ -155,3 +155,32 @@ // CHECK: %[[VAL_29:.*]] = fir.call @_FortranAAssign(%[[VAL_26]], %[[VAL_27]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.ref, i32) -> none // CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box>>) -> !fir.heap> // CHECK: fir.freemem %[[VAL_30]] : !fir.heap> + + +func.func @test_scalar_to_array(%lhs: !fir.box>, %rhs: i32) { + hlfir.assign %rhs to %lhs : i32, !fir.box> + return +} +// CHECK-LABEL: func.func @test_scalar_to_array( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>, +// CHECK-SAME: %[[VAL_1:.*]]: i32) { +// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box> +// CHECK: %[[VAL_5:.*]] = fir.alloca i32 +// CHECK: fir.store %[[VAL_1]] to %[[VAL_5]] : !fir.ref +// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.ref) -> !fir.box +// CHECK: fir.store %[[VAL_0]] to %[[VAL_2]] : !fir.ref>> +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>>) -> !fir.ref> +// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_6]] : (!fir.box) -> !fir.box +// CHECK: %[[VAL_13:.*]] = fir.call @_FortranAAssign(%[[VAL_10]], %[[VAL_11]] + + +func.func @test_i1_scalar_to_array(%lhs: !fir.box>>, %rhs: i1) { + hlfir.assign %rhs to %lhs : i1, !fir.box>> + return +} +// CHECK-LABEL: func.func @test_i1_scalar_to_array( +// CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (i1) -> !fir.logical<4> +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.logical<4> +// CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]] : (!fir.ref>) -> !fir.box> +// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_7]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_14:.*]] = fir.call @_FortranAAssign(%{{.*}}, %[[VAL_12]]