[flang] Do not leave length parameters uninitialized in descriptor addendums (#81858)

Descriptor addendum have a field to hold length parameters (currently
only one). This field is currently never used because flang does not
lowered derived types with length parameters.

However, leaving it uninitialized is causing bugs in code like gFTL
where the code is trying to sort POINTERs (see [1]). More precisely, it
is an issue when two pointers should compare equal (same base address),
because the uninitialized values in the addendum may differ depending on
the "stack history" and optimization level.

Always initialized the length parameters field in the addendum to zero.

[1]:
dc93a5fc2f/include/v1/templates/set_impl.inc (L312)

The type being transferred to an integer array may look like:

```
   TYPE :: localwrapper
    TYPE(T), POINTER :: item
   END TYPE localwrapper
```

Which in flang case ends-up transferring a descriptor to an integer
array, the code in gFTL later compare the integer arrays. This logic is
used when building set data structures in gFTL.
This commit is contained in:
jeanPerier
2024-02-16 08:51:03 +01:00
committed by GitHub
parent 42b5037cc4
commit d26a6464f8
7 changed files with 31 additions and 14 deletions

View File

@@ -147,6 +147,9 @@ static unsigned getTypeDescFieldId(mlir::Type ty) {
auto isArray = fir::dyn_cast_ptrOrBoxEleTy(ty).isa<fir::SequenceType>();
return isArray ? kOptTypePtrPosInBox : kDimsPosInBox;
}
static unsigned getLenParamFieldId(mlir::Type ty) {
return getTypeDescFieldId(ty) + 1;
}
namespace {
/// FIR conversion pattern template
@@ -1583,6 +1586,14 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
descriptor =
insertField(rewriter, loc, descriptor, {typeDescFieldId}, typeDesc,
/*bitCast=*/true);
// Always initialize the length parameter field to zero to avoid issues
// with uninitialized values in Fortran code trying to compare physical
// representation of derived types with pointer/allocatable components.
// This has been seen in hashing algorithms using TRANSFER.
mlir::Value zero =
genConstantIndex(loc, rewriter.getI64Type(), rewriter, 0);
descriptor = insertField(rewriter, loc, descriptor,
{getLenParamFieldId(boxTy), 0}, zero);
}
return descriptor;
}