diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -1157,8 +1157,18 @@ if (fir::isa_ref_type(rhsVal.getType())) rhsVal = builder.create(loc, rhsVal); mlir::Value lhsAddr = fir::getBase(lhs); - rhsVal = builder.createConvert(loc, fir::unwrapRefType(lhsAddr.getType()), - rhsVal); + mlir::Type lhsTargetType = fir::unwrapRefType(lhsAddr.getType()); + mlir::Type rhsTy = rhsVal.getType(); + if (rhsTy != lhsTargetType) { + if (fir::ConvertOp::canBeConverted(rhsTy, lhsTargetType)) + rhsVal = builder.createConvert( + loc, fir::unwrapRefType(lhsAddr.getType()), rhsVal); + else + // we can't convert rhs to match lhs, so instead convert lhs e.g. + // convert !fir.ref to !fir.ref + lhsAddr = + builder.createConvert(loc, ReferenceType::get(rhsTy), lhsAddr); + } builder.create(loc, rhsVal, lhsAddr); } } 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 @@ -267,3 +267,26 @@ // CHECK: %[[VAL_13:.*]] = fir.call @_FortranAAssign(%[[VAL_10]], %[[VAL_11]], %[[VAL_12]], %{{.*}}) : (!fir.ref>, !fir.box, !fir.ref, i32) -> none // CHECK: return // CHECK: } + +// Test we can assign types which cannot be converted e.g. logical -> complex +func.func @_QPe1() -> !fir.logical<4> { + %0 = fir.alloca !fir.complex<4> {bindc_name = "f1", uniq_name = "_QFf1Ef1"} + %1:2 = hlfir.declare %0 {uniq_name = "_QFf1Ef1"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %1#1 {uniq_name = "_QFf1Ee1"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) + %false = arith.constant false + %3 = fir.convert %false : (i1) -> !fir.logical<4> + // this is the important bit: + hlfir.assign %3 to %2#0 : !fir.logical<4>, !fir.ref> + %4 = fir.convert %2#1 : (!fir.ref>) -> !fir.ref> + %5 = fir.load %4 : !fir.ref> + return %5 : !fir.logical<4> +} +// CHECK-LABEL: func.func @_QPe1() +// CHECK-NEXT: %[[F1_ALLOC:.*]] = fir.alloca !fir.complex<4> +// CHECK-NEXT: %[[F1_DECL:.*]] = fir.declare %[[F1_ALLOC]] +// CHECK-NEXT: %[[E1_DECL:.*]] = fir.declare %[[F1_DECL]] +// CHECK-NEXT: %[[FALSE:.*]] = arith.constant false +// CHECK-NEXT: %[[FALSE_LOGICAL:.*]] = fir.convert %[[FALSE]] +// this is the important bit: +// CHECK-NEXT: %[[CONV:.*]] = fir.convert %[[E1_DECL]] : (!fir.ref>) -> !fir.ref> +// CHECK-NEXT: fir.store %[[FALSE_LOGICAL]] to %[[CONV]]