Skip to content

Commit a16eddb

Browse files
clementvaljeanPeriermleair
committed
[flang] Lower transfer instrinsic
This patch adds lowering for the `transfer` intrinsic. The calls are lowered to runtime function calls. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D121777 Co-authored-by: Jean Perier <[email protected]> Co-authored-by: mleair <[email protected]>
1 parent 63bbac1 commit a16eddb

File tree

4 files changed

+220
-0
lines changed

4 files changed

+220
-0
lines changed

flang/include/flang/Lower/Runtime.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ void genRandomNumber(fir::FirOpBuilder &, mlir::Location, mlir::Value harvest);
8181
void genRandomSeed(fir::FirOpBuilder &, mlir::Location, int argIndex,
8282
mlir::Value argBox);
8383

84+
/// generate runtime call to transfer intrinsic with no size argument
85+
void genTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
86+
mlir::Value resultBox, mlir::Value sourceBox,
87+
mlir::Value moldBox);
88+
89+
/// generate runtime call to transfer intrinsic with size argument
90+
void genTransferSize(fir::FirOpBuilder &builder, mlir::Location loc,
91+
mlir::Value resultBox, mlir::Value sourceBox,
92+
mlir::Value moldBox, mlir::Value size);
93+
8494
/// generate system_clock runtime call/s
8595
/// all intrinsic arguments are optional and may appear here as mlir::Value{}
8696
void genSystemClock(fir::FirOpBuilder &, mlir::Location, mlir::Value count,

flang/lib/Lower/IntrinsicCall.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,8 @@ struct IntrinsicLibrary {
464464
fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
465465
fir::ExtendedValue genSum(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
466466
void genSystemClock(llvm::ArrayRef<fir::ExtendedValue>);
467+
fir::ExtendedValue genTransfer(mlir::Type,
468+
llvm::ArrayRef<fir::ExtendedValue>);
467469
fir::ExtendedValue genUbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
468470

469471
/// Define the different FIR generators that can be mapped to intrinsic to
@@ -659,6 +661,10 @@ static constexpr IntrinsicHandler handlers[]{
659661
&I::genSystemClock,
660662
{{{"count", asAddr}, {"count_rate", asAddr}, {"count_max", asAddr}}},
661663
/*isElemental=*/false},
664+
{"transfer",
665+
&I::genTransfer,
666+
{{{"source", asAddr}, {"mold", asAddr}, {"size", asValue}}},
667+
/*isElemental=*/false},
662668
{"ubound",
663669
&I::genUbound,
664670
{{{"array", asBox}, {"dim", asValue}, {"kind", asValue}}},
@@ -1949,6 +1955,53 @@ IntrinsicLibrary::genSize(mlir::Type resultType,
19491955
.getResults()[0];
19501956
}
19511957

1958+
// TRANSFER
1959+
fir::ExtendedValue
1960+
IntrinsicLibrary::genTransfer(mlir::Type resultType,
1961+
llvm::ArrayRef<fir::ExtendedValue> args) {
1962+
1963+
assert(args.size() >= 2); // args.size() == 2 when size argument is omitted.
1964+
1965+
// Handle source argument
1966+
mlir::Value source = builder.createBox(loc, args[0]);
1967+
1968+
// Handle mold argument
1969+
mlir::Value mold = builder.createBox(loc, args[1]);
1970+
fir::BoxValue moldTmp = mold;
1971+
unsigned moldRank = moldTmp.rank();
1972+
1973+
bool absentSize = (args.size() == 2);
1974+
1975+
// Create mutable fir.box to be passed to the runtime for the result.
1976+
mlir::Type type = (moldRank == 0 && absentSize)
1977+
? resultType
1978+
: builder.getVarLenSeqTy(resultType, 1);
1979+
fir::MutableBoxValue resultMutableBox =
1980+
fir::factory::createTempMutableBox(builder, loc, type);
1981+
1982+
if (moldRank == 0 && absentSize) {
1983+
// This result is a scalar in this case.
1984+
mlir::Value resultIrBox =
1985+
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
1986+
1987+
Fortran::lower::genTransfer(builder, loc, resultIrBox, source, mold);
1988+
} else {
1989+
// The result is a rank one array in this case.
1990+
mlir::Value resultIrBox =
1991+
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
1992+
1993+
if (absentSize) {
1994+
Fortran::lower::genTransfer(builder, loc, resultIrBox, source, mold);
1995+
} else {
1996+
mlir::Value sizeArg = fir::getBase(args[2]);
1997+
Fortran::lower::genTransferSize(builder, loc, resultIrBox, source, mold,
1998+
sizeArg);
1999+
}
2000+
}
2001+
return readAndAddCleanUp(resultMutableBox, resultType,
2002+
"unexpected result for TRANSFER");
2003+
}
2004+
19522005
// LBOUND
19532006
fir::ExtendedValue
19542007
IntrinsicLibrary::genLbound(mlir::Type resultType,

flang/lib/Lower/Runtime.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "flang/Optimizer/Builder/FIRBuilder.h"
1414
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
1515
#include "flang/Parser/parse-tree.h"
16+
#include "flang/Runtime/misc-intrinsic.h"
1617
#include "flang/Runtime/pointer.h"
1718
#include "flang/Runtime/random.h"
1819
#include "flang/Runtime/stop.h"
@@ -234,6 +235,39 @@ void Fortran::lower::genRandomSeed(fir::FirOpBuilder &builder,
234235
builder.create<fir::CallOp>(loc, func, args);
235236
}
236237

238+
/// generate runtime call to transfer intrinsic with no size argument
239+
void Fortran::lower::genTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
240+
mlir::Value resultBox, mlir::Value sourceBox,
241+
mlir::Value moldBox) {
242+
243+
mlir::FuncOp func =
244+
fir::runtime::getRuntimeFunc<mkRTKey(Transfer)>(loc, builder);
245+
mlir::FunctionType fTy = func.getType();
246+
mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
247+
mlir::Value sourceLine =
248+
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
249+
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
250+
builder, loc, fTy, resultBox, sourceBox, moldBox, sourceFile, sourceLine);
251+
builder.create<fir::CallOp>(loc, func, args);
252+
}
253+
254+
/// generate runtime call to transfer intrinsic with size argument
255+
void Fortran::lower::genTransferSize(fir::FirOpBuilder &builder,
256+
mlir::Location loc, mlir::Value resultBox,
257+
mlir::Value sourceBox, mlir::Value moldBox,
258+
mlir::Value size) {
259+
mlir::FuncOp func =
260+
fir::runtime::getRuntimeFunc<mkRTKey(TransferSize)>(loc, builder);
261+
mlir::FunctionType fTy = func.getType();
262+
mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
263+
mlir::Value sourceLine =
264+
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
265+
llvm::SmallVector<mlir::Value> args =
266+
fir::runtime::createArguments(builder, loc, fTy, resultBox, sourceBox,
267+
moldBox, sourceFile, sourceLine, size);
268+
builder.create<fir::CallOp>(loc, func, args);
269+
}
270+
237271
/// generate system_clock runtime call/s
238272
/// all intrinsic arguments are optional and may appear here as mlir::Value{}
239273
void Fortran::lower::genSystemClock(fir::FirOpBuilder &builder,
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
3+
subroutine trans_test(store, word)
4+
! CHECK-LABEL: func @_QPtrans_test(
5+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32>{{.*}}, %[[VAL_1:.*]]: !fir.ref<f32>{{.*}}) {
6+
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
7+
! CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<f32>) -> !fir.box<f32>
8+
! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<i32>) -> !fir.box<i32>
9+
! CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.heap<i32>
10+
! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
11+
! CHECK: fir.store %[[VAL_6]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<i32>>>
12+
! CHECK: %[[VAL_7:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
13+
! CHECK: %[[VAL_8:.*]] = arith.constant {{.*}} : i32
14+
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> !fir.ref<!fir.box<none>>
15+
! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_3]] : (!fir.box<f32>) -> !fir.box<none>
16+
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_4]] : (!fir.box<i32>) -> !fir.box<none>
17+
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
18+
! CHECK: %[[VAL_13:.*]] = fir.call @_FortranATransfer(%[[VAL_9]], %[[VAL_10]], %[[VAL_11]], %[[VAL_12]], %[[VAL_8]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
19+
! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<i32>>>
20+
! CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
21+
! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_15]] : !fir.heap<i32>
22+
! CHECK: fir.store %[[VAL_16]] to %[[VAL_0]] : !fir.ref<i32>
23+
! CHECK: fir.freemem %[[VAL_15]]
24+
! CHECK: return
25+
! CHECK: }
26+
integer :: store
27+
real :: word
28+
store = transfer(word, store)
29+
end subroutine
30+
31+
! CHECK-LABEL: func @_QPtrans_test2(
32+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<f32>{{.*}}) {
33+
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
34+
! CHECK: %[[VAL_3:.*]] = arith.constant 3 : index
35+
! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
36+
! CHECK: %[[VAL_5:.*]] = fir.array_load %[[VAL_0]](%[[VAL_4]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.array<3xi32>
37+
! CHECK: %[[VAL_6:.*]] = arith.constant 3 : i32
38+
! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<f32>) -> !fir.box<f32>
39+
! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
40+
! CHECK: %[[VAL_9:.*]] = fir.embox %[[VAL_0]](%[[VAL_8]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
41+
! CHECK: %[[VAL_10:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
42+
! CHECK: %[[VAL_11:.*]] = arith.constant 0 : index
43+
! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_11]] : (index) -> !fir.shape<1>
44+
! CHECK: %[[VAL_13:.*]] = fir.embox %[[VAL_10]](%[[VAL_12]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
45+
! CHECK: fir.store %[[VAL_13]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
46+
! CHECK: %[[VAL_14:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,
47+
! CHECK: %[[VAL_15:.*]] = arith.constant {{.*}} : i32
48+
! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
49+
! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_7]] : (!fir.box<f32>) -> !fir.box<none>
50+
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<3xi32>>) -> !fir.box<none>
51+
! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_14]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
52+
! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_6]] : (i32) -> i64
53+
! CHECK: %[[VAL_21:.*]] = fir.call @_FortranATransferSize(%[[VAL_16]], %[[VAL_17]], %[[VAL_18]], %[[VAL_19]], %[[VAL_15]], %[[VAL_20]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32, i64) -> none
54+
! CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
55+
! CHECK: %[[VAL_23:.*]] = arith.constant 0 : index
56+
! CHECK: %[[VAL_24:.*]]:3 = fir.box_dims %[[VAL_22]], %[[VAL_23]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
57+
! CHECK: %[[VAL_25:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
58+
! CHECK: %[[VAL_26:.*]] = fir.shape_shift %[[VAL_24]]#0, %[[VAL_24]]#1 : (index, index) -> !fir.shapeshift<1>
59+
! CHECK: %[[VAL_27:.*]] = fir.array_load %[[VAL_25]](%[[VAL_26]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.array<?xi32>
60+
! CHECK: %[[VAL_28:.*]] = arith.constant 1 : index
61+
! CHECK: %[[VAL_29:.*]] = arith.constant 0 : index
62+
! CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_3]], %[[VAL_28]] : index
63+
! CHECK: %[[VAL_31:.*]] = fir.do_loop %[[VAL_32:.*]] = %[[VAL_29]] to %[[VAL_30]] step %[[VAL_28]] unordered iter_args(%[[VAL_33:.*]] = %[[VAL_5]]) -> (!fir.array<3xi32>) {
64+
! CHECK: %[[VAL_34:.*]] = fir.array_fetch %[[VAL_27]], %[[VAL_32]] : (!fir.array<?xi32>, index) -> i32
65+
! CHECK: %[[VAL_35:.*]] = fir.array_update %[[VAL_33]], %[[VAL_34]], %[[VAL_32]] : (!fir.array<3xi32>, i32, index) -> !fir.array<3xi32>
66+
! CHECK: fir.result %[[VAL_35]] : !fir.array<3xi32>
67+
! CHECK: }
68+
! CHECK: fir.array_merge_store %[[VAL_5]], %[[VAL_36:.*]] to %[[VAL_0]] : !fir.array<3xi32>, !fir.array<3xi32>, !fir.ref<!fir.array<3xi32>>
69+
! CHECK: fir.freemem %[[VAL_25]]
70+
! CHECK: return
71+
! CHECK: }
72+
73+
subroutine trans_test2(store, word)
74+
integer :: store(3)
75+
real :: word
76+
store = transfer(word, store, 3)
77+
end subroutine
78+
79+
integer function trans_test3(p)
80+
! CHECK-LABEL: func @_QPtrans_test3(
81+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32>{{.*}}) -> i32 {
82+
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.type<_QFtrans_test3Tobj{x:i32}>>
83+
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>>
84+
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QFtrans_test3Tobj{x:i32}> {bindc_name = "t", uniq_name = "_QFtrans_test3Et"}
85+
! CHECK: %[[VAL_4:.*]] = fir.alloca i32 {bindc_name = "trans_test3", uniq_name = "_QFtrans_test3Etrans_test3"}
86+
! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<i32>) -> !fir.box<i32>
87+
! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_3]] : (!fir.ref<!fir.type<_QFtrans_test3Tobj{x:i32}>>) -> !fir.box<!fir.type<_QFtrans_test3Tobj{x:i32}>>
88+
! CHECK: %[[VAL_7:.*]] = fir.zero_bits !fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>
89+
! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_7]] : (!fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>) -> !fir.box<!fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>>
90+
! CHECK: fir.store %[[VAL_8]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>>>
91+
! CHECK: %[[VAL_9:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
92+
! CHECK: %[[VAL_10:.*]] = arith.constant {{.*}} : i32
93+
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>>>) -> !fir.ref<!fir.box<none>>
94+
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_5]] : (!fir.box<i32>) -> !fir.box<none>
95+
! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_6]] : (!fir.box<!fir.type<_QFtrans_test3Tobj{x:i32}>>) -> !fir.box<none>
96+
! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_9]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
97+
! CHECK: %[[VAL_15:.*]] = fir.call @_FortranATransfer(%[[VAL_11]], %[[VAL_12]], %[[VAL_13]], %[[VAL_14]], %[[VAL_10]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
98+
! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>>>
99+
! CHECK: %[[VAL_17:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>>) -> !fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>
100+
! CHECK: %[[VAL_18:.*]] = fir.embox %[[VAL_3]] : (!fir.ref<!fir.type<_QFtrans_test3Tobj{x:i32}>>) -> !fir.box<!fir.type<_QFtrans_test3Tobj{x:i32}>>
101+
! CHECK: fir.store %[[VAL_18]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.type<_QFtrans_test3Tobj{x:i32}>>>
102+
! CHECK: %[[VAL_19:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
103+
! CHECK: %[[VAL_20:.*]] = arith.constant {{.*}} : i32
104+
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.type<_QFtrans_test3Tobj{x:i32}>>>) -> !fir.ref<!fir.box<none>>
105+
! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.heap<!fir.type<_QFtrans_test3Tobj{x:i32}>>>) -> !fir.box<none>
106+
! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_19]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
107+
! CHECK: %[[VAL_24:.*]] = fir.call @_FortranAAssign(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_20]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
108+
! CHECK: fir.freemem %[[VAL_17]]
109+
! CHECK: %[[VAL_25:.*]] = fir.field_index x, !fir.type<_QFtrans_test3Tobj{x:i32}>
110+
! CHECK: %[[VAL_26:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_25]] : (!fir.ref<!fir.type<_QFtrans_test3Tobj{x:i32}>>, !fir.field) -> !fir.ref<i32>
111+
! CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_26]] : !fir.ref<i32>
112+
! CHECK: fir.store %[[VAL_27]] to %[[VAL_4]] : !fir.ref<i32>
113+
! CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
114+
! CHECK: return %[[VAL_28]] : i32
115+
! CHECK: }
116+
type obj
117+
integer :: x
118+
end type
119+
type (obj) :: t
120+
integer :: p
121+
t = transfer(p, t)
122+
trans_test3 = t%x
123+
end function

0 commit comments

Comments
 (0)