mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 23:49:22 +08:00
[flang][hlfir] Special handling for temporary LHS in AssignOp.
When `AssignOp` is used with LHS that is a compiler generated temporary special care must be taken to initialize the temporary and avoid finalizations of its components. This change-set adds optional `temporary_lhs` attribute for `AssignOp` to convey this information to HLFIR-to-FIR conversion pass. Currently, this results in calling `AssignTemporary` runtime for doing the assignment. Reviewed By: jeanPerier, tblah Differential Revision: https://reviews.llvm.org/D152482
This commit is contained in:
@@ -496,6 +496,8 @@ The attributes can be:
|
||||
analysis pass).
|
||||
- unordered : mark that an assignment can happen in any element order (not
|
||||
true if there is an impure elemental function being called).
|
||||
- temporary_lhs: mark that the left hand side of the assignment is
|
||||
a compiler generated temporary.
|
||||
|
||||
This will replace the current array_load/array_access/array_merge semantics.
|
||||
Instead, a more generic alias analysis will be performed on the LHS and RHS to
|
||||
|
||||
@@ -588,14 +588,16 @@ fir::ExtendedValue arraySectionElementToExtendedValue(
|
||||
/// assignment follows Fortran intrinsic assignment semantic (10.2.1.3).
|
||||
void genScalarAssignment(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
const fir::ExtendedValue &lhs,
|
||||
const fir::ExtendedValue &rhs);
|
||||
const fir::ExtendedValue &rhs,
|
||||
bool isTemporaryLHS = false);
|
||||
/// Assign \p rhs to \p lhs. Both \p rhs and \p lhs must be scalar derived
|
||||
/// types. The assignment follows Fortran intrinsic assignment semantic for
|
||||
/// derived types (10.2.1.3 point 13).
|
||||
void genRecordAssignment(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
const fir::ExtendedValue &lhs,
|
||||
const fir::ExtendedValue &rhs,
|
||||
bool needFinalization = false);
|
||||
bool needFinalization = false,
|
||||
bool isTemporaryLHS = false);
|
||||
|
||||
/// Builds and returns the type of a ragged array header used to cache mask
|
||||
/// evaluations. RaggedArrayHeader is defined in
|
||||
|
||||
@@ -140,16 +140,25 @@ def fir_AssignOp : hlfir_Op<"assign", [MemoryEffects<[MemWrite]>]> {
|
||||
Otherwise, the left hand side will be allocated or reallocated to match the
|
||||
right hand side length if they differ. This covers the case of deferred
|
||||
length character allocatables.
|
||||
The optional "temporary_lhs" flag indicates that the LHS is a compiler
|
||||
generated temporary. In this case the temporary is initialized if needed
|
||||
(e.g. the LHS is of derived type with allocatable/pointer components),
|
||||
and the assignment is done without LHS (or its subobjects) finalization
|
||||
and with automatic allocation. Since LHS is uninitialized in this case,
|
||||
"keep_lhs_length_if_realloc" attribute does not make sense. "realloc"
|
||||
attribute is allowed with "temporary_lhs", though, it is implied.
|
||||
}];
|
||||
|
||||
let arguments = (ins AnyFortranEntity:$rhs,
|
||||
Arg<AnyFortranVariable, "", [MemWrite]>:$lhs,
|
||||
UnitAttr:$realloc,
|
||||
UnitAttr:$keep_lhs_length_if_realloc);
|
||||
UnitAttr:$keep_lhs_length_if_realloc,
|
||||
UnitAttr:$temporary_lhs);
|
||||
|
||||
let assemblyFormat = [{
|
||||
$rhs `to` $lhs (`realloc` $realloc^)?
|
||||
(`keep_lhs_len` $keep_lhs_length_if_realloc^)?
|
||||
(`temporary_lhs` $temporary_lhs^)?
|
||||
attr-dict `:` type(operands)
|
||||
}];
|
||||
|
||||
@@ -164,6 +173,10 @@ def fir_AssignOp : hlfir_Op<"assign", [MemoryEffects<[MemWrite]>]> {
|
||||
bool mustKeepLhsLengthInAllocatableAssignment() {
|
||||
return getKeepLhsLengthIfRealloc();
|
||||
}
|
||||
/// Is the assignment's left hand side a compiler generated temporary?
|
||||
bool isTemporaryLHS() {
|
||||
return getTemporaryLhs();
|
||||
}
|
||||
}];
|
||||
|
||||
let hasVerifier = 1;
|
||||
|
||||
@@ -1686,7 +1686,9 @@ private:
|
||||
loc, resultType, varOp, /*shape=*/nullptr,
|
||||
/*typeparams=*/mlir::ValueRange{});
|
||||
auto rhs = gen(expr);
|
||||
builder.create<hlfir::AssignOp>(loc, rhs, lhs);
|
||||
builder.create<hlfir::AssignOp>(loc, rhs, lhs, /*realloc=*/false,
|
||||
/*keep_lhs_length_if_realloc=*/false,
|
||||
/*temporary_lhs=*/true);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1742,7 +1744,9 @@ private:
|
||||
bitEnumContainsAny(attrs.getFlags(),
|
||||
fir::FortranVariableFlagsEnum::allocatable);
|
||||
auto rhs = gen(expr);
|
||||
builder.create<hlfir::AssignOp>(loc, rhs, lhs, allowRealloc);
|
||||
builder.create<hlfir::AssignOp>(loc, rhs, lhs, allowRealloc,
|
||||
/*keep_lhs_length_if_realloc=*/false,
|
||||
/*temporary_lhs=*/true);
|
||||
}
|
||||
|
||||
return varOp;
|
||||
|
||||
@@ -1138,7 +1138,8 @@ fir::ExtendedValue fir::factory::arraySectionElementToExtendedValue(
|
||||
void fir::factory::genScalarAssignment(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
const fir::ExtendedValue &lhs,
|
||||
const fir::ExtendedValue &rhs) {
|
||||
const fir::ExtendedValue &rhs,
|
||||
bool isTemporaryLHS) {
|
||||
assert(lhs.rank() == 0 && rhs.rank() == 0 && "must be scalars");
|
||||
auto type = fir::unwrapSequenceType(
|
||||
fir::unwrapPassByRefType(fir::getBase(lhs).getType()));
|
||||
@@ -1150,7 +1151,8 @@ void fir::factory::genScalarAssignment(fir::FirOpBuilder &builder,
|
||||
helper.createAssign(fir::ExtendedValue{*toChar},
|
||||
fir::ExtendedValue{*fromChar});
|
||||
} else if (type.isa<fir::RecordType>()) {
|
||||
fir::factory::genRecordAssignment(builder, loc, lhs, rhs);
|
||||
fir::factory::genRecordAssignment(
|
||||
builder, loc, lhs, rhs, /*needFinalization=*/false, isTemporaryLHS);
|
||||
} else {
|
||||
assert(!fir::hasDynamicSize(type));
|
||||
auto rhsVal = fir::getBase(rhs);
|
||||
@@ -1166,7 +1168,8 @@ void fir::factory::genScalarAssignment(fir::FirOpBuilder &builder,
|
||||
static void genComponentByComponentAssignment(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
const fir::ExtendedValue &lhs,
|
||||
const fir::ExtendedValue &rhs) {
|
||||
const fir::ExtendedValue &rhs,
|
||||
bool isTemporaryLHS) {
|
||||
auto lbaseType = fir::unwrapPassByRefType(fir::getBase(lhs).getType());
|
||||
auto lhsType = lbaseType.dyn_cast<fir::RecordType>();
|
||||
assert(lhsType && "lhs must be a scalar record type");
|
||||
@@ -1229,7 +1232,7 @@ static void genComponentByComponentAssignment(fir::FirOpBuilder &builder,
|
||||
auto from =
|
||||
fir::factory::componentToExtendedValue(builder, loc, fromCoor);
|
||||
auto to = fir::factory::componentToExtendedValue(builder, loc, toCoor);
|
||||
fir::factory::genScalarAssignment(builder, loc, to, from);
|
||||
fir::factory::genScalarAssignment(builder, loc, to, from, isTemporaryLHS);
|
||||
}
|
||||
if (outerLoop)
|
||||
builder.setInsertionPointAfter(*outerLoop);
|
||||
@@ -1260,7 +1263,8 @@ void fir::factory::genRecordAssignment(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
const fir::ExtendedValue &lhs,
|
||||
const fir::ExtendedValue &rhs,
|
||||
bool needFinalization) {
|
||||
bool needFinalization,
|
||||
bool isTemporaryLHS) {
|
||||
assert(lhs.rank() == 0 && rhs.rank() == 0 && "assume scalar assignment");
|
||||
auto baseTy = fir::dyn_cast_ptrOrBoxEleTy(fir::getBase(lhs).getType());
|
||||
assert(baseTy && "must be a memory type");
|
||||
@@ -1281,7 +1285,10 @@ void fir::factory::genRecordAssignment(fir::FirOpBuilder &builder,
|
||||
// TODO: does this holds true with polymorphic entities ?
|
||||
auto toMutableBox = builder.createTemporary(loc, to.getType());
|
||||
builder.create<fir::StoreOp>(loc, to, toMutableBox);
|
||||
fir::runtime::genAssign(builder, loc, toMutableBox, from);
|
||||
if (isTemporaryLHS)
|
||||
fir::runtime::genAssignTemporary(builder, loc, toMutableBox, from);
|
||||
else
|
||||
fir::runtime::genAssign(builder, loc, toMutableBox, from);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1299,7 +1306,7 @@ void fir::factory::genRecordAssignment(fir::FirOpBuilder &builder,
|
||||
// leads to issues in LLVM (long compile times, long IR files, and even
|
||||
// asserts at some point). Since there is no good size boundary, just always
|
||||
// use component by component assignment here.
|
||||
genComponentByComponentAssignment(builder, loc, lhs, rhs);
|
||||
genComponentByComponentAssignment(builder, loc, lhs, rhs, isTemporaryLHS);
|
||||
}
|
||||
|
||||
mlir::TupleType
|
||||
|
||||
@@ -47,6 +47,9 @@ mlir::LogicalResult hlfir::AssignOp::verify() {
|
||||
hlfir::getFortranElementType(lhsType).isa<fir::CharacterType>()))
|
||||
return emitOpError("`realloc` must be set and lhs must be a character "
|
||||
"allocatable when `keep_lhs_length_if_realloc` is set");
|
||||
if (mustKeepLhsLengthInAllocatableAssignment() && isTemporaryLHS())
|
||||
return emitOpError("`keep_lhs_length_if_realloc` does not make sense "
|
||||
"for `temporary_lhs` assignments");
|
||||
return mlir::success();
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ createTempFromMold(mlir::Location loc, fir::FirOpBuilder &builder,
|
||||
isHeapAlloc = builder.createBool(loc, true);
|
||||
} else {
|
||||
alloc = builder.createTemporary(loc, mold.getFortranElementType(), tmpName,
|
||||
/*shape*/ std::nullopt, lenParams);
|
||||
/*shape=*/std::nullopt, lenParams);
|
||||
isHeapAlloc = builder.createBool(loc, false);
|
||||
}
|
||||
auto declareOp = builder.create<hlfir::DeclareOp>(
|
||||
@@ -162,7 +162,9 @@ struct AsExprOpConversion : public mlir::OpConversionPattern<hlfir::AsExprOp> {
|
||||
// Otherwise, create a copy in a new buffer.
|
||||
hlfir::Entity source = hlfir::Entity{adaptor.getVar()};
|
||||
auto [temp, cleanup] = createTempFromMold(loc, builder, source);
|
||||
builder.create<hlfir::AssignOp>(loc, source, temp);
|
||||
builder.create<hlfir::AssignOp>(loc, source, temp, /*realloc=*/false,
|
||||
/*keep_lhs_length_if_realloc=*/false,
|
||||
/*temporary_lhs=*/true);
|
||||
mlir::Value bufferizedExpr =
|
||||
packageBufferizedExpr(loc, builder, temp, cleanup);
|
||||
rewriter.replaceOp(asExpr, bufferizedExpr);
|
||||
@@ -307,7 +309,10 @@ struct SetLengthOpConversion
|
||||
fir::FortranVariableFlagsAttr{});
|
||||
hlfir::Entity temp{declareOp.getBase()};
|
||||
// Assign string value to the created temp.
|
||||
builder.create<hlfir::AssignOp>(loc, string, temp);
|
||||
builder.create<hlfir::AssignOp>(loc, string, temp,
|
||||
/*realloc=*/false,
|
||||
/*keep_lhs_length_if_realloc=*/false,
|
||||
/*temporary_lhs=*/true);
|
||||
mlir::Value bufferizedExpr =
|
||||
packageBufferizedExpr(loc, builder, temp, false);
|
||||
rewriter.replaceOp(setLength, bufferizedExpr);
|
||||
@@ -572,7 +577,10 @@ struct ElementalOpConversion
|
||||
// Assign the element value to the temp element for this iteration.
|
||||
auto tempElement =
|
||||
hlfir::getElementAt(loc, builder, temp, loopNest.oneBasedIndices);
|
||||
builder.create<hlfir::AssignOp>(loc, elementValue, tempElement);
|
||||
builder.create<hlfir::AssignOp>(loc, elementValue, tempElement,
|
||||
/*realloc=*/false,
|
||||
/*keep_lhs_length_if_realloc=*/false,
|
||||
/*temporary_lhs=*/true);
|
||||
// hlfir.yield_element implicitly marks the end-of-life its operand if
|
||||
// it is an expression created in the hlfir.elemental (since it is its
|
||||
// last use and an hlfir.destroy could not be created afterwards)
|
||||
|
||||
@@ -121,6 +121,11 @@ public:
|
||||
// mismatch, and that it should use the LHS explicit/assumed length if
|
||||
// allocating/reallocation the LHS.
|
||||
fir::runtime::genAssignExplicitLengthCharacter(builder, loc, to, from);
|
||||
} else if (assignOp.isTemporaryLHS()) {
|
||||
// Use AssignTemporary, when the LHS is a compiler generated temporary.
|
||||
// Note that it also works properly for polymorphic LHS (i.e. the LHS
|
||||
// will have the RHS dynamic type after the assignment).
|
||||
fir::runtime::genAssignTemporary(builder, loc, to, from);
|
||||
} else if (lhs.isPolymorphic()) {
|
||||
// Indicate the runtime that the LHS must have the RHS dynamic type
|
||||
// after the assignment.
|
||||
@@ -138,13 +143,17 @@ public:
|
||||
// reference.
|
||||
auto toMutableBox = builder.createTemporary(loc, to.getType());
|
||||
builder.create<fir::StoreOp>(loc, to, toMutableBox);
|
||||
fir::runtime::genAssign(builder, loc, toMutableBox, from);
|
||||
if (assignOp.isTemporaryLHS())
|
||||
fir::runtime::genAssignTemporary(builder, loc, toMutableBox, from);
|
||||
else
|
||||
fir::runtime::genAssign(builder, loc, toMutableBox, from);
|
||||
} else {
|
||||
// genScalarAssignment() must take care of potential overlap
|
||||
// between LHS and RHS. Note that the overlap is possible
|
||||
// also for components of LHS/RHS, and the Assign() runtime
|
||||
// must take care of it.
|
||||
fir::factory::genScalarAssignment(builder, loc, lhsExv, rhsExv);
|
||||
fir::factory::genScalarAssignment(builder, loc, lhsExv, rhsExv,
|
||||
assignOp.isTemporaryLHS());
|
||||
}
|
||||
rewriter.eraseOp(assignOp);
|
||||
return mlir::success();
|
||||
|
||||
@@ -14,7 +14,7 @@ func.func @char_expr(%addr: !fir.ref<!fir.char<1,?>>, %len: index) {
|
||||
// CHECK: %[[VAL_3:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_1]] : index) {bindc_name = ".tmp"}
|
||||
// CHECK: %[[VAL_5:.*]] = arith.constant false
|
||||
// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] typeparams %[[VAL_1]] {uniq_name = ".tmp"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
// CHECK: hlfir.assign %[[VAL_2]]#0 to %[[VAL_4]]#0 : !fir.boxchar<1>, !fir.boxchar<1>
|
||||
// CHECK: hlfir.assign %[[VAL_2]]#0 to %[[VAL_4]]#0 temporary_lhs : !fir.boxchar<1>, !fir.boxchar<1>
|
||||
// CHECK: %[[VAL_6:.*]] = fir.undefined tuple<!fir.boxchar<1>, i1>
|
||||
// CHECK: %[[VAL_7:.*]] = fir.insert_value %[[VAL_6]], %[[VAL_5]], [1 : index] : (tuple<!fir.boxchar<1>, i1>, i1) -> tuple<!fir.boxchar<1>, i1>
|
||||
// CHECK: %[[VAL_8:.*]] = fir.insert_value %[[VAL_7]], %[[VAL_4]]#0, [0 : index] : (tuple<!fir.boxchar<1>, i1>, !fir.boxchar<1>) -> tuple<!fir.boxchar<1>, i1>
|
||||
@@ -31,7 +31,7 @@ func.func @char_expr_2(%addr: !fir.ref<!fir.char<1,10>>, %len: index) {
|
||||
// CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "c"} : (!fir.ref<!fir.char<1,10>>, index) -> (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>)
|
||||
// CHECK: %[[VAL_5:.*]] = arith.constant false
|
||||
// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_1]] {uniq_name = ".tmp"} : (!fir.ref<!fir.char<1,10>>, index) -> (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>)
|
||||
// CHECK: hlfir.assign %[[VAL_3]]#0 to %[[VAL_4]]#0 : !fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>
|
||||
// CHECK: hlfir.assign %[[VAL_3]]#0 to %[[VAL_4]]#0 temporary_lhs : !fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>
|
||||
// CHECK: %[[VAL_6:.*]] = fir.undefined tuple<!fir.ref<!fir.char<1,10>>, i1>
|
||||
// CHECK: %[[VAL_7:.*]] = fir.insert_value %[[VAL_6]], %[[VAL_5]], [1 : index] : (tuple<!fir.ref<!fir.char<1,10>>, i1>, i1) -> tuple<!fir.ref<!fir.char<1,10>>, i1>
|
||||
// CHECK: %[[VAL_8:.*]] = fir.insert_value %[[VAL_7]], %[[VAL_4]]#0, [0 : index] : (tuple<!fir.ref<!fir.char<1,10>>, i1>, !fir.ref<!fir.char<1,10>>) -> tuple<!fir.ref<!fir.char<1,10>>, i1>
|
||||
@@ -48,7 +48,7 @@ func.func @shape_from_type(%arg0 : !fir.ref<!fir.array<10x20xi32>>) {
|
||||
// CHECK: %[[VAL_4:.*]] = fir.allocmem !fir.array<10x20xi32> {bindc_name = ".tmp", uniq_name = ""}
|
||||
// CHECK: %[[VAL_5:.*]] = arith.constant true
|
||||
// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_4]](%[[VAL_3]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<10x20xi32>>, !fir.shape<2>) -> (!fir.heap<!fir.array<10x20xi32>>, !fir.heap<!fir.array<10x20xi32>>)
|
||||
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_6]]#0 : !fir.ref<!fir.array<10x20xi32>>, !fir.heap<!fir.array<10x20xi32>>
|
||||
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_6]]#0 temporary_lhs : !fir.ref<!fir.array<10x20xi32>>, !fir.heap<!fir.array<10x20xi32>>
|
||||
// CHECK: %[[VAL_7:.*]] = fir.undefined tuple<!fir.heap<!fir.array<10x20xi32>>, i1>
|
||||
// CHECK: %[[VAL_8:.*]] = fir.insert_value %[[VAL_7]], %[[VAL_5]], [1 : index] : (tuple<!fir.heap<!fir.array<10x20xi32>>, i1>, i1) -> tuple<!fir.heap<!fir.array<10x20xi32>>, i1>
|
||||
// CHECK: %[[VAL_9:.*]] = fir.insert_value %[[VAL_8]], %[[VAL_6]]#0, [0 : index] : (tuple<!fir.heap<!fir.array<10x20xi32>>, i1>, !fir.heap<!fir.array<10x20xi32>>) -> tuple<!fir.heap<!fir.array<10x20xi32>>, i1>
|
||||
@@ -67,7 +67,7 @@ func.func @shape_from_box(%arg0 : !fir.box<!fir.array<10x?xi32>>) {
|
||||
// CHECK: %[[VAL_5:.*]] = fir.allocmem !fir.array<10x?xi32>, %[[VAL_3]]#1 {bindc_name = ".tmp", uniq_name = ""}
|
||||
// CHECK: %[[VAL_6:.*]] = arith.constant true
|
||||
// CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]](%[[VAL_4]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<10x?xi32>>, !fir.shape<2>) -> (!fir.box<!fir.array<10x?xi32>>, !fir.heap<!fir.array<10x?xi32>>)
|
||||
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_7]]#0 : !fir.box<!fir.array<10x?xi32>>, !fir.box<!fir.array<10x?xi32>>
|
||||
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_7]]#0 temporary_lhs : !fir.box<!fir.array<10x?xi32>>, !fir.box<!fir.array<10x?xi32>>
|
||||
// CHECK: %[[VAL_8:.*]] = fir.undefined tuple<!fir.box<!fir.array<10x?xi32>>, i1>
|
||||
// CHECK: %[[VAL_9:.*]] = fir.insert_value %[[VAL_8]], %[[VAL_6]], [1 : index] : (tuple<!fir.box<!fir.array<10x?xi32>>, i1>, i1) -> tuple<!fir.box<!fir.array<10x?xi32>>, i1>
|
||||
// CHECK: %[[VAL_10:.*]] = fir.insert_value %[[VAL_9]], %[[VAL_7]]#0, [0 : index] : (tuple<!fir.box<!fir.array<10x?xi32>>, i1>, !fir.box<!fir.array<10x?xi32>>) -> tuple<!fir.box<!fir.array<10x?xi32>>, i1>
|
||||
|
||||
@@ -145,6 +145,31 @@ func.func @array(%arg0: !fir.box<!fir.array<?xi32>>, %arg1: !fir.ref<!fir.array<
|
||||
// CHECK: %[[VAL_29:.*]] = fir.call @_FortranAAssign(%[[VAL_26]], %[[VAL_27]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
|
||||
|
||||
func.func @array_temp(%arg0: !fir.box<!fir.array<?xi32>>, %arg1: !fir.ref<!fir.array<100xi32>>) {
|
||||
%c100 = arith.constant 100 : index
|
||||
%0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box<!fir.array<?xi32>>) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
|
||||
%1 = fir.shape %c100 : (index) -> !fir.shape<1>
|
||||
%2:2 = hlfir.declare %arg1(%1) {uniq_name = "y"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
|
||||
hlfir.assign %2#0 to %0#0 temporary_lhs : !fir.ref<!fir.array<100xi32>>, !fir.box<!fir.array<?xi32>>
|
||||
return
|
||||
}
|
||||
// CHECK-LABEL: func.func @array_temp(
|
||||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>,
|
||||
// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.array<100xi32>>) {
|
||||
// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.array<?xi32>>
|
||||
// CHECK: %[[VAL_4:.*]] = arith.constant 100 : index
|
||||
// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
|
||||
// CHECK: %[[VAL_6:.*]] = fir.rebox %[[VAL_5]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
|
||||
// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
|
||||
// CHECK: %[[VAL_8:.*]] = fir.declare %[[VAL_1]](%[[VAL_7]]) {uniq_name = "y"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<100xi32>>
|
||||
// CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
|
||||
// CHECK: %[[VAL_10:.*]] = fir.embox %[[VAL_8]](%[[VAL_9]]) : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<100xi32>>
|
||||
// CHECK: fir.store %[[VAL_5]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
|
||||
// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<none>>
|
||||
// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_10]] : (!fir.box<!fir.array<100xi32>>) -> !fir.box<none>
|
||||
// CHECK: %[[VAL_29:.*]] = fir.call @_FortranAAssignTemporary(%[[VAL_26]], %[[VAL_27]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
|
||||
|
||||
func.func @test_scalar_to_array(%lhs: !fir.box<!fir.array<?xi32>>, %rhs: i32) {
|
||||
hlfir.assign %rhs to %lhs : i32, !fir.box<!fir.array<?xi32>>
|
||||
return
|
||||
@@ -184,6 +209,16 @@ func.func @alloc_assign(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>,
|
||||
// CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
|
||||
// CHECK: fir.call @_FortranAAssign(%[[VAL_2]], %[[VAL_3]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
|
||||
func.func @alloc_assign_temp(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, %arg1: !fir.box<!fir.array<?xi32>>) {
|
||||
hlfir.assign %arg1 to %arg0 realloc temporary_lhs : !fir.box<!fir.array<?xi32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
||||
return
|
||||
}
|
||||
// CHECK-LABEL: func.func @alloc_assign_temp(
|
||||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>,
|
||||
// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>) {
|
||||
// CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
|
||||
// CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
|
||||
// CHECK: fir.call @_FortranAAssignTemporary(%[[VAL_2]], %[[VAL_3]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
|
||||
func.func @test_alloc_assign_explicit_length_character(%lhs: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>, %rhs: !fir.box<!fir.array<?x!fir.char<1,?>>>) {
|
||||
hlfir.assign %rhs to %lhs realloc keep_lhs_len : !fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>
|
||||
@@ -246,6 +281,17 @@ func.func @assign_i1_to_polymorphic(%arg0: !fir.ref<!fir.class<!fir.heap<none>>>
|
||||
// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_6]] : (!fir.box<!fir.logical<4>>) -> !fir.box<none>
|
||||
// CHECK: %[[VAL_13:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_10]], %[[VAL_11]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
|
||||
func.func @test_alloc_assign_polymorphic_temp(%lhs: !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<t>>>>>, %rhs: !fir.class<!fir.array<?x!fir.type<t>>>) {
|
||||
hlfir.assign %rhs to %lhs realloc temporary_lhs : !fir.class<!fir.array<?x!fir.type<t>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<t>>>>>
|
||||
return
|
||||
}
|
||||
// CHECK-LABEL: func.func @test_alloc_assign_polymorphic_temp(
|
||||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<t>>>>>,
|
||||
// CHECK-SAME: %[[VAL_1:.*]]: !fir.class<!fir.array<?x!fir.type<t>>>) {
|
||||
// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<t>>>>>) -> !fir.ref<!fir.box<none>>
|
||||
// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.class<!fir.array<?x!fir.type<t>>>) -> !fir.box<none>
|
||||
// CHECK: %[[VAL_10:.*]] = fir.call @_FortranAAssignTemporary(%[[VAL_7]], %[[VAL_8]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
|
||||
func.func @test_allocatable_component(%arg0: !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {fir.bindc_name = "x", fir.target}, %arg1: !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {fir.bindc_name = "y", fir.target}) {
|
||||
%4:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEx"} : (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
|
||||
%5:2 = hlfir.declare %arg1 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEy"} : (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
|
||||
@@ -267,3 +313,25 @@ func.func @test_allocatable_component(%arg0: !fir.ref<!fir.type<_QFtestTt1{a:!fi
|
||||
// CHECK: %[[VAL_13:.*]] = fir.call @_FortranAAssign(%[[VAL_10]], %[[VAL_11]], %[[VAL_12]], %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
// CHECK: return
|
||||
// CHECK: }
|
||||
|
||||
func.func @test_allocatable_component_temp(%arg0: !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {fir.bindc_name = "x", fir.target}, %arg1: !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {fir.bindc_name = "y", fir.target}) {
|
||||
%4:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEx"} : (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
|
||||
%5:2 = hlfir.declare %arg1 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEy"} : (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
|
||||
hlfir.assign %5#0 to %4#0 temporary_lhs : !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
|
||||
return
|
||||
}
|
||||
// CHECK-LABEL: func.func @test_allocatable_component_temp(
|
||||
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {fir.bindc_name = "x", fir.target},
|
||||
// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>> {fir.bindc_name = "y", fir.target}) {
|
||||
// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
|
||||
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEx"} : (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
|
||||
// CHECK: %[[VAL_4:.*]] = fir.declare %[[VAL_1]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEy"} : (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
|
||||
// CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_3]] : (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
|
||||
// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_4]] : (!fir.ref<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
|
||||
// CHECK: fir.store %[[VAL_5]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>>
|
||||
// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>>) -> !fir.ref<!fir.box<none>>
|
||||
// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_6]] : (!fir.box<!fir.type<_QFtestTt1{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<none>
|
||||
// CHECK: %[[VAL_12:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
|
||||
// CHECK: %[[VAL_13:.*]] = fir.call @_FortranAAssignTemporary(%[[VAL_10]], %[[VAL_11]], %[[VAL_12]], %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
// CHECK: return
|
||||
// CHECK: }
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
// CHECK: %[[VAL_54:.*]] = fir.insert_value %[[VAL_53]], %[[VAL_48]], [1 : index] : (tuple<!fir.boxchar<1>, i1>, i1) -> tuple<!fir.boxchar<1>, i1>
|
||||
// CHECK: %[[VAL_55:.*]] = fir.insert_value %[[VAL_54]], %[[VAL_52]], [0 : index] : (tuple<!fir.boxchar<1>, i1>, !fir.boxchar<1>) -> tuple<!fir.boxchar<1>, i1>
|
||||
// CHECK: %[[VAL_56:.*]] = hlfir.designate %[[VAL_42]]#0 (%[[VAL_45]]) typeparams %[[VAL_39]] : (!fir.box<!fir.array<1x!fir.char<1,?>>>, index, index) -> !fir.boxchar<1>
|
||||
// CHECK: hlfir.assign %[[VAL_52]] to %[[VAL_56]] : !fir.boxchar<1>, !fir.boxchar<1>
|
||||
// CHECK: hlfir.assign %[[VAL_52]] to %[[VAL_56]] temporary_lhs : !fir.boxchar<1>, !fir.boxchar<1>
|
||||
// CHECK: }
|
||||
// CHECK: %[[VAL_57:.*]] = fir.undefined tuple<!fir.box<!fir.array<1x!fir.char<1,?>>>, i1>
|
||||
// CHECK: %[[VAL_58:.*]] = fir.insert_value %[[VAL_57]], %[[VAL_43]], [1 : index] : (tuple<!fir.box<!fir.array<1x!fir.char<1,?>>>, i1>, i1) -> tuple<!fir.box<!fir.array<1x!fir.char<1,?>>>, i1>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
// CHECK: fir.do_loop %[[VAL_23:.*]] = %[[VAL_22]] to %[[VAL_2]] step %[[VAL_22]] {
|
||||
// CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_11]]#0 : !fir.ref<f32>
|
||||
// CHECK: %[[VAL_25:.*]] = hlfir.designate %[[VAL_20]]#0 (%[[VAL_23]]) : (!fir.heap<!fir.array<2xf32>>, index) -> !fir.ref<f32>
|
||||
// CHECK: hlfir.assign %[[VAL_24]] to %[[VAL_25]] : f32, !fir.ref<f32>
|
||||
// CHECK: hlfir.assign %[[VAL_24]] to %[[VAL_25]] temporary_lhs : f32, !fir.ref<f32>
|
||||
// CHECK: }
|
||||
// CHECK: %[[VAL_26:.*]] = fir.undefined tuple<!fir.heap<!fir.array<2xf32>>, i1>
|
||||
// CHECK: %[[VAL_27:.*]] = fir.insert_value %[[VAL_26]], %[[VAL_21]], [1 : index] : (tuple<!fir.heap<!fir.array<2xf32>>, i1>, i1) -> tuple<!fir.heap<!fir.array<2xf32>>, i1>
|
||||
@@ -41,7 +41,7 @@
|
||||
// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_30]] : (!fir.ref<!fir.array<2xf32>>) -> !fir.heap<!fir.array<2xf32>>
|
||||
// CHECK: fir.freemem %[[VAL_34]] : !fir.heap<!fir.array<2xf32>>
|
||||
// CHECK: %[[VAL_35:.*]] = hlfir.designate %[[VAL_14]]#0 (%[[VAL_17]]) : (!fir.heap<!fir.array<2xf32>>, index) -> !fir.ref<f32>
|
||||
// CHECK: hlfir.assign %[[VAL_33]] to %[[VAL_35]] : f32, !fir.ref<f32>
|
||||
// CHECK: hlfir.assign %[[VAL_33]] to %[[VAL_35]] temporary_lhs : f32, !fir.ref<f32>
|
||||
// CHECK: }
|
||||
// CHECK: %[[VAL_36:.*]] = fir.undefined tuple<!fir.heap<!fir.array<2xf32>>, i1>
|
||||
// CHECK: %[[VAL_37:.*]] = fir.insert_value %[[VAL_36]], %[[VAL_15]], [1 : index] : (tuple<!fir.heap<!fir.array<2xf32>>, i1>, i1) -> tuple<!fir.heap<!fir.array<2xf32>>, i1>
|
||||
|
||||
@@ -34,7 +34,7 @@ func.func @numeric_type(%arg0: !fir.ref<!fir.array<10x20xi32>>, %arg1: !fir.ref<
|
||||
// CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_12]] : !fir.ref<i32>
|
||||
// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_13]], %[[VAL_14]] : i32
|
||||
// CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_10]], %[[VAL_9]]) : (!fir.heap<!fir.array<10x20xi32>>, index, index) -> !fir.ref<i32>
|
||||
// CHECK: hlfir.assign %[[VAL_15]] to %[[VAL_16]] : i32, !fir.ref<i32>
|
||||
// CHECK: hlfir.assign %[[VAL_15]] to %[[VAL_16]] temporary_lhs : i32, !fir.ref<i32>
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: %[[VAL_17:.*]] = fir.undefined tuple<!fir.heap<!fir.array<10x20xi32>>, i1>
|
||||
@@ -71,7 +71,7 @@ func.func @char_type(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>>, %arg1: index
|
||||
// CHECK: %[[VAL_33:.*]] = fir.insert_value %[[VAL_32]], %[[VAL_31]], [1 : index] : (tuple<!fir.boxchar<1>, i1>, i1) -> tuple<!fir.boxchar<1>, i1>
|
||||
// CHECK: %[[VAL_34:.*]] = fir.insert_value %[[VAL_33]], %[[VAL_30]]#0, [0 : index] : (tuple<!fir.boxchar<1>, i1>, !fir.boxchar<1>) -> tuple<!fir.boxchar<1>, i1>
|
||||
// CHECK: %[[VAL_35:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_9]]) typeparams %[[VAL_2]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index, index) -> !fir.boxchar<1>
|
||||
// CHECK: hlfir.assign %[[VAL_30]]#0 to %[[VAL_35]] : !fir.boxchar<1>, !fir.boxchar<1>
|
||||
// CHECK: hlfir.assign %[[VAL_30]]#0 to %[[VAL_35]] temporary_lhs : !fir.boxchar<1>, !fir.boxchar<1>
|
||||
// CHECK: }
|
||||
// CHECK: %[[VAL_36:.*]] = fir.undefined tuple<!fir.box<!fir.array<?x!fir.char<1,?>>>, i1>
|
||||
// CHECK: %[[VAL_37:.*]] = fir.insert_value %[[VAL_36]], %[[VAL_7]], [1 : index] : (tuple<!fir.box<!fir.array<?x!fir.char<1,?>>>, i1>, i1) -> tuple<!fir.box<!fir.array<?x!fir.char<1,?>>>, i1>
|
||||
@@ -101,7 +101,7 @@ func.func @derived_transpose(%arg0: !fir.box<!fir.array<?x?x!fir.type<t{field:f3
|
||||
// CHECK: fir.do_loop %[[VAL_9:.*]] = %[[VAL_7]] to %[[VAL_2]] step %[[VAL_7]] {
|
||||
// CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_9]], %[[VAL_8]]) : (!fir.box<!fir.array<?x?x!fir.type<t{field:f32}>>>, index, index) -> !fir.box<!fir.type<t{field:f32}>>
|
||||
// CHECK: %[[VAL_11:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_9]], %[[VAL_8]]) : (!fir.box<!fir.array<?x?x!fir.type<t{field:f32}>>>, index, index) -> !fir.ref<!fir.type<t{field:f32}>>
|
||||
// CHECK: hlfir.assign %[[VAL_10]] to %[[VAL_11]] : !fir.box<!fir.type<t{field:f32}>>, !fir.ref<!fir.type<t{field:f32}>>
|
||||
// CHECK: hlfir.assign %[[VAL_10]] to %[[VAL_11]] temporary_lhs : !fir.box<!fir.type<t{field:f32}>>, !fir.ref<!fir.type<t{field:f32}>>
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: %[[VAL_12:.*]] = fir.undefined tuple<!fir.box<!fir.array<?x?x!fir.type<t{field:f32}>>>, i1>
|
||||
|
||||
@@ -644,6 +644,13 @@ func.func @bad_assign_2(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>,
|
||||
return
|
||||
}
|
||||
|
||||
// -----
|
||||
func.func @bad_assign_3(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>, %arg1: !fir.box<!fir.array<?x!fir.char<1,?>>>) {
|
||||
// expected-error@+1 {{'hlfir.assign' op `keep_lhs_length_if_realloc` does not make sense for `temporary_lhs` assignments}}
|
||||
hlfir.assign %arg1 to %arg0 realloc keep_lhs_len temporary_lhs : !fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
|
||||
return
|
||||
}
|
||||
|
||||
// -----
|
||||
func.func @bad_parent_comp1(%arg0: !fir.box<!fir.array<10x!fir.type<t2{i:i32,j:i32}>>>) {
|
||||
// expected-error@+1 {{'hlfir.parent_comp' op must be provided a shape if and only if the base is an array}}
|
||||
|
||||
@@ -11,7 +11,7 @@ func.func @test_cst_len(%str : !fir.boxchar<1>) {
|
||||
// CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1,10> {bindc_name = ".tmp"}
|
||||
// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
|
||||
// CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_1]] typeparams %[[VAL_2]] {uniq_name = ".tmp"} : (!fir.ref<!fir.char<1,10>>, index) -> (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>)
|
||||
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_3]]#0 : !fir.boxchar<1>, !fir.ref<!fir.char<1,10>>
|
||||
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_3]]#0 temporary_lhs : !fir.boxchar<1>, !fir.ref<!fir.char<1,10>>
|
||||
// CHECK: %[[VAL_4:.*]] = arith.constant false
|
||||
// CHECK: %[[VAL_5:.*]] = fir.undefined tuple<!fir.ref<!fir.char<1,10>>, i1>
|
||||
// CHECK: %[[VAL_6:.*]] = fir.insert_value %[[VAL_5]], %[[VAL_4]], [1 : index] : (tuple<!fir.ref<!fir.char<1,10>>, i1>, i1) -> tuple<!fir.ref<!fir.char<1,10>>, i1>
|
||||
@@ -26,7 +26,7 @@ func.func @test_dyn_len(%str : !fir.ref<!fir.char<1,10>>, %len : index) {
|
||||
// CHECK-SAME: %[[VAL_1:.*]]: index) {
|
||||
// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_1]] : index) {bindc_name = ".tmp"}
|
||||
// CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_1]] {uniq_name = ".tmp"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_3]]#0 : !fir.ref<!fir.char<1,10>>, !fir.boxchar<1>
|
||||
// CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_3]]#0 temporary_lhs : !fir.ref<!fir.char<1,10>>, !fir.boxchar<1>
|
||||
// CHECK: %[[VAL_4:.*]] = arith.constant false
|
||||
// CHECK: %[[VAL_5:.*]] = fir.undefined tuple<!fir.boxchar<1>, i1>
|
||||
// CHECK: %[[VAL_6:.*]] = fir.insert_value %[[VAL_5]], %[[VAL_4]], [1 : index] : (tuple<!fir.boxchar<1>, i1>, i1) -> tuple<!fir.boxchar<1>, i1>
|
||||
|
||||
@@ -48,7 +48,7 @@ end subroutine test1
|
||||
! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_8]]#0{"c"} typeparams %[[VAL_15]] : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, index) -> !fir.ref<!fir.char<1,4>>
|
||||
! CHECK: %[[VAL_17:.*]] = arith.constant 4 : i64
|
||||
! CHECK: %[[VAL_18:.*]] = hlfir.set_length %[[VAL_7]]#0 len %[[VAL_17]] : (!fir.ref<!fir.char<1,4>>, i64) -> !hlfir.expr<!fir.char<1,4>>
|
||||
! CHECK: hlfir.assign %[[VAL_18]] to %[[VAL_16]] : !hlfir.expr<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>
|
||||
! CHECK: hlfir.assign %[[VAL_18]] to %[[VAL_16]] temporary_lhs : !hlfir.expr<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>
|
||||
! CHECK: hlfir.assign %[[VAL_8]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>
|
||||
! CHECK: return
|
||||
! CHECK: }
|
||||
@@ -77,7 +77,7 @@ end subroutine test2
|
||||
! CHECK: %[[VAL_14:.*]] = arith.constant 10 : index
|
||||
! CHECK: %[[VAL_15:.*]] = fir.shape %[[VAL_14]] : (index) -> !fir.shape<1>
|
||||
! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0{"i"} <%[[VAL_15]]> shape %[[VAL_15]] : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.shape<1>, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
|
||||
! CHECK: hlfir.assign %[[VAL_6]]#0 to %[[VAL_16]] : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>
|
||||
! CHECK: hlfir.assign %[[VAL_6]]#0 to %[[VAL_16]] temporary_lhs : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>
|
||||
! CHECK: hlfir.assign %[[VAL_7]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>
|
||||
! CHECK: return
|
||||
! CHECK: }
|
||||
@@ -162,7 +162,7 @@ end subroutine test4
|
||||
! CHECK: %[[VAL_34:.*]] = hlfir.set_length %[[VAL_33]] len %[[VAL_22]] : (!fir.ref<!fir.char<1,2>>, i64) -> !hlfir.expr<!fir.char<1,2>>
|
||||
! CHECK: hlfir.yield_element %[[VAL_34]] : !hlfir.expr<!fir.char<1,2>>
|
||||
! CHECK: }
|
||||
! CHECK: hlfir.assign %[[VAL_35:.*]] to %[[VAL_20]] realloc : !hlfir.expr<?x!fir.char<1,?>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
|
||||
! CHECK: hlfir.assign %[[VAL_35:.*]] to %[[VAL_20]] realloc temporary_lhs : !hlfir.expr<?x!fir.char<1,?>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
|
||||
! CHECK: hlfir.assign %[[VAL_12]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>
|
||||
! CHECK: hlfir.destroy %[[VAL_35]] : !hlfir.expr<?x!fir.char<1,?>>
|
||||
! CHECK: return
|
||||
@@ -194,7 +194,7 @@ end subroutine test5
|
||||
! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
|
||||
! CHECK: %[[VAL_17:.*]] = fir.call @_FortranAInitialize(%[[VAL_15]], %[[VAL_16]], %[[VAL_14]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
! CHECK: %[[VAL_18:.*]] = hlfir.designate %[[VAL_11]]#0{"t5m"} {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
|
||||
! CHECK: hlfir.assign %[[VAL_10]]#0 to %[[VAL_18]] realloc : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
|
||||
! CHECK: hlfir.assign %[[VAL_10]]#0 to %[[VAL_18]] realloc temporary_lhs : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
|
||||
! CHECK: hlfir.assign %[[VAL_11]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>, !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>
|
||||
! CHECK: return
|
||||
! CHECK: }
|
||||
@@ -243,8 +243,8 @@ end subroutine test6
|
||||
! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_30]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
|
||||
! CHECK: %[[VAL_34:.*]] = fir.call @_FortranAInitialize(%[[VAL_32]], %[[VAL_33]], %[[VAL_31]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> none
|
||||
! CHECK: %[[VAL_35:.*]] = hlfir.designate %[[VAL_28]]#0{"t5m"} {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
|
||||
! CHECK: hlfir.assign %[[VAL_19]]#0 to %[[VAL_35]] realloc : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
|
||||
! CHECK: hlfir.assign %[[VAL_28]]#0 to %[[VAL_27]] : !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>, !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>
|
||||
! CHECK: hlfir.assign %[[VAL_19]]#0 to %[[VAL_35]] realloc temporary_lhs : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
|
||||
! CHECK: hlfir.assign %[[VAL_28]]#0 to %[[VAL_27]] temporary_lhs : !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>, !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>
|
||||
! CHECK: %[[VAL_36:.*]] = arith.constant 1 : index
|
||||
! CHECK: %[[VAL_37:.*]] = fir.shape %[[VAL_36]] : (index) -> !fir.shape<1>
|
||||
! CHECK: %[[VAL_38:.*]] = hlfir.designate %[[VAL_20]]#0{"t6m"} <%[[VAL_37]]> shape %[[VAL_37]] : (!fir.ref<!fir.type<_QMtypesTt6{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>, !fir.shape<1>, !fir.shape<1>) -> !fir.ref<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>
|
||||
@@ -273,12 +273,12 @@ end subroutine test6
|
||||
! CHECK: %[[VAL_60:.*]] = hlfir.designate %[[VAL_52]]#0{"c"} typeparams %[[VAL_59]] : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, index) -> !fir.ref<!fir.char<1,4>>
|
||||
! CHECK: %[[VAL_61:.*]] = arith.constant 4 : i64
|
||||
! CHECK: %[[VAL_62:.*]] = hlfir.set_length %[[VAL_10]]#0 len %[[VAL_61]] : (!fir.ref<!fir.char<1,4>>, i64) -> !hlfir.expr<!fir.char<1,4>>
|
||||
! CHECK: hlfir.assign %[[VAL_62]] to %[[VAL_60]] : !hlfir.expr<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>
|
||||
! CHECK: hlfir.assign %[[VAL_62]] to %[[VAL_60]] temporary_lhs : !hlfir.expr<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>
|
||||
! CHECK: %[[VAL_63:.*]] = fir.convert %[[VAL_52]]#1 : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> !fir.llvm_ptr<i8>
|
||||
! CHECK: %[[VAL_64:.*]] = fir.call @_FortranAPushArrayConstructorSimpleScalar(%[[VAL_45]], %[[VAL_63]]) fastmath<contract> : (!fir.llvm_ptr<i8>, !fir.llvm_ptr<i8>) -> none
|
||||
! CHECK: %[[VAL_65:.*]] = arith.constant true
|
||||
! CHECK: %[[VAL_66:.*]] = hlfir.as_expr %[[VAL_42]]#0 move %[[VAL_65]] : (!fir.heap<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>, i1) -> !hlfir.expr<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>
|
||||
! CHECK: hlfir.assign %[[VAL_66]] to %[[VAL_38]] : !hlfir.expr<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>
|
||||
! CHECK: hlfir.assign %[[VAL_66]] to %[[VAL_38]] temporary_lhs : !hlfir.expr<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>
|
||||
! CHECK: hlfir.assign %[[VAL_20]]#0 to %[[VAL_12]]#0 : !fir.ref<!fir.type<_QMtypesTt6{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>, !fir.ref<!fir.type<_QMtypesTt6{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>
|
||||
! CHECK: hlfir.destroy %[[VAL_66]] : !hlfir.expr<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>
|
||||
! CHECK: return
|
||||
|
||||
Reference in New Issue
Block a user