diff --git a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp --- a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp @@ -350,8 +350,10 @@ builder.createConvert(loc, associate.getResultTypes()[0], hlfirVar); associate.getResult(0).replaceAllUsesWith(hlfirVar); mlir::Type associateFirVarType = associate.getResultTypes()[1]; - if (firVar.getType().isa() && - !associateFirVarType.isa()) + if ((firVar.getType().isa() && + !associateFirVarType.isa()) || + (firVar.getType().isa() && + !associateFirVarType.isa())) firVar = builder.create(loc, associateFirVarType, firVar); else diff --git a/flang/test/HLFIR/associate-codegen.fir b/flang/test/HLFIR/associate-codegen.fir --- a/flang/test/HLFIR/associate-codegen.fir +++ b/flang/test/HLFIR/associate-codegen.fir @@ -53,31 +53,61 @@ func.func @associate_char(%arg0: !fir.boxchar<1> ) { + %c1 = arith.constant 1 : index %0:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref>, index) %1:2 = hlfir.declare %0#0 typeparams %0#1 {uniq_name = "x"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) - %2 = arith.addi %0#1, %0#1 : index - %3 = hlfir.concat %1#0, %1#0 len %2 : (!fir.boxchar<1>, !fir.boxchar<1>, index) -> !hlfir.expr> - %4:3 = hlfir.associate %3 typeparams %2 {uniq_name = "x"} : (!hlfir.expr>, index) -> (!fir.boxchar<1>, !fir.ref>, i1) - fir.call @take_c(%4#0) : (!fir.boxchar<1>) -> () - hlfir.end_associate %4#1, %4#2 : !fir.ref>, i1 + %2 = arith.addi %0#1, %c1 : index + %3 = fir.undefined !fir.ref> + %4:2 = hlfir.declare %3 typeparams %c1 {fortran_attrs = #fir.var_attrs, uniq_name = "char_literal"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) + %5 = hlfir.concat %1#0, %4#0 len %2 : (!fir.boxchar<1>, !fir.ref>, index) -> !hlfir.expr> + %6 = hlfir.no_reassoc %5 : !hlfir.expr> + %7:3 = hlfir.associate %6 typeparams %2 {uniq_name = "x"} : (!hlfir.expr>, index) -> (!fir.boxchar<1>, !fir.ref>, i1) + fir.call @take_c(%7#0) : (!fir.boxchar<1>) -> () + hlfir.end_associate %7#1, %7#2 : !fir.ref>, i1 return } -// CHECK-LABEL: func.func @associate_char( -// CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>) { -// CHECK: %[[VAL_1:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) -// CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]]#0 typeparams %[[VAL_1]]#1 {uniq_name = "x"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) -// CHECK: %[[VAL_3:.*]] = arith.addi %[[VAL_1]]#1, %[[VAL_1]]#1 : index -// CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_1]]#1, %[[VAL_1]]#1 : index -// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_4]] : index) {bindc_name = ".chrtmp"} -// CHECK: fir.call @llvm.memmove.p0.p0.i64 -// CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[VAL_4]] {uniq_name = "tmp"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) -// CHECK: %[[VAL_22:.*]] = arith.constant false -// CHECK: %[[VAL_23:.*]] = fir.undefined tuple, i1> -// CHECK: %[[VAL_24:.*]] = fir.insert_value %[[VAL_23]], %[[VAL_22]], [1 : index] : (tuple, i1>, i1) -> tuple, i1> -// CHECK: %[[VAL_25:.*]] = fir.insert_value %[[VAL_24]], %[[VAL_21]]#0, [0 : index] : (tuple, i1>, !fir.boxchar<1>) -> tuple, i1> -// CHECK: fir.call @take_c(%[[VAL_21]]#0) : (!fir.boxchar<1>) -> () -// CHECK-NOT: fir.freemem +// CHECK-LABEL: func.func @associate_char( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +// CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]]#0 typeparams %[[VAL_2]]#1 {uniq_name = "x"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) +// CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_2]]#1, %[[VAL_1]] : index +// CHECK: %[[VAL_5:.*]] = fir.undefined !fir.ref> +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[VAL_1]] {fortran_attrs = #fir.var_attrs, uniq_name = "char_literal"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +// CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_2]]#1, %[[VAL_1]] : index +// CHECK: %[[VAL_8:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_7]] : index) {bindc_name = ".chrtmp"} +// CHECK: %[[VAL_9:.*]] = arith.constant 1 : i64 +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_2]]#1 : (index) -> i64 +// CHECK: %[[VAL_11:.*]] = arith.muli %[[VAL_9]], %[[VAL_10]] : i64 +// CHECK: %[[VAL_12:.*]] = arith.constant false +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_8]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_13]], %[[VAL_14]], %[[VAL_11]], %[[VAL_12]]) : (!fir.ref, !fir.ref, i64, i1) -> () +// CHECK: %[[VAL_15:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_7]], %[[VAL_15]] : index +// CHECK: fir.do_loop %[[VAL_17:.*]] = %[[VAL_2]]#1 to %[[VAL_16]] step %[[VAL_15]] { +// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_2]]#1 : index +// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_6]]#1 : (!fir.ref>) -> !fir.ref>> +// CHECK: %[[VAL_20:.*]] = fir.coordinate_of %[[VAL_19]], %[[VAL_18]] : (!fir.ref>>, index) -> !fir.ref> +// CHECK: %[[VAL_21:.*]] = fir.load %[[VAL_20]] : !fir.ref> +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_8]] : (!fir.ref>) -> !fir.ref>> +// CHECK: %[[VAL_23:.*]] = fir.coordinate_of %[[VAL_22]], %[[VAL_17]] : (!fir.ref>>, index) -> !fir.ref> +// CHECK: fir.store %[[VAL_21]] to %[[VAL_23]] : !fir.ref> +// CHECK: } +// CHECK: %[[VAL_24:.*]]:2 = hlfir.declare %[[VAL_8]] typeparams %[[VAL_7]] {uniq_name = "tmp"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) +// CHECK: %[[VAL_25:.*]] = arith.constant false +// CHECK: %[[VAL_26:.*]] = fir.undefined tuple, i1> +// CHECK: %[[VAL_27:.*]] = fir.insert_value %[[VAL_26]], %[[VAL_25]], [1 : index] : (tuple, i1>, i1) -> tuple, i1> +// CHECK: %[[VAL_28:.*]] = fir.insert_value %[[VAL_27]], %[[VAL_24]]#0, [0 : index] : (tuple, i1>, !fir.boxchar<1>) -> tuple, i1> +// CHECK: %[[VAL_29:.*]] = hlfir.no_reassoc %[[VAL_24]]#0 : !fir.boxchar<1> +// CHECK: %[[VAL_30:.*]] = fir.undefined tuple, i1> +// CHECK: %[[VAL_31:.*]] = fir.insert_value %[[VAL_30]], %[[VAL_25]], [1 : index] : (tuple, i1>, i1) -> tuple, i1> +// CHECK: %[[VAL_32:.*]] = fir.insert_value %[[VAL_31]], %[[VAL_29]], [0 : index] : (tuple, i1>, !fir.boxchar<1>) -> tuple, i1> +// CHECK: %[[VAL_33:.*]] = fir.box_addr %[[VAL_29]] : (!fir.boxchar<1>) -> !fir.ref> +// CHECK: fir.call @take_c(%[[VAL_29]]) : (!fir.boxchar<1>) -> () +// CHECK: return +// CHECK: } func.func @test_end_associate_box(%var: !fir.box>) { %true = arith.constant 1 : i1