[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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user