Implements HLFIR lowering for %im and %re.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Something to note is that this patch currently doesn't support expressions like array%im + 3 because arith.fadd will complain that fir.real isn't floating-point-like. It also seems like hlfir.designate expects a fir.real designation type, so I'm not really sure how to reconcile this. I don't know if this is issue with this patch or if its a problem outside of the scope of this task, but I figured it was worth bringing up.
Great job finding out the pieces, designator lowering is not the easiest piece of lowering. Looks good overall, some comment inline.
Did you use fir.real type for a specific reason? If not, I think it will be easier to use the mlir real type (that may require inserting a convert when doing the hlfir.designate codegen, but I think it will simplify lowering). The fir.real is a bit legacy, and there could be use cases in situation where we would like to have "target independent" IR using the kinds, but I do not see it applying here.
flang/lib/Lower/ConvertExprToHLFIR.cpp | ||
---|---|---|
168 | Nit: the lowering code is following LLVM/MLIR coding convention: https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements | |
260 | Here I think it would be fine and simpler to use the MLIR real type directly. fir.real is a bit of a legacy type that is kept around because fir.complex type is kept as a hammer solution to distinguish C++ std::complex and C complex in call ABIs (long topic). | |
262–278 | Would using the version of genDesignate that takes the Fortran::evaluate::ComplexPart works and avoid the custom computation of the result type here: Fortran::evaluate::ComplexPart: return genDesignate(changedType , partInfo, complexPart);? Except the partInfo.resultShape = hlfir::genShape(getLoc(), getBuilder(), *partInfo.base); that is needed if the result is an array. The resultShape computation logic could be moved to genDesignate too to benefit the substring case too. Right now it is impossible to get an evaluate::Substring following a Symbol (c_array(1:10) is an array section, there is not way to write a symbol array substring without first adding and array section`(:)`), that is why the substring case did not have to do the partInfo.resultShape computation, but it might happen in the future with compiler generated evaluate::Expr. | |
266 | Have you run in cases where fir::isBoxAddress(changedType) is true? If so, I think it is a bug on my side because I intended the visit to only return "value" types (array or scalar types not wrapped in fir.ref/fir.box). However, I think that another condition here should be && !partInfo.resultShape: the result shape may already have been computed if there is an array section complex_array(1:10:2)%re or if there is a component ref: derived_array(1)%complex_part_array%re, and in both cases the overriding with the base shape (complex_array or derived_array shape) would be incorrect. |
Thank you for the feedback, Jean. I'll keep looking into this.
flang/lib/Lower/ConvertExprToHLFIR.cpp | ||
---|---|---|
260 | Are you referring to the real type that is returned by the FIRBuilder's getRealType method? I initially tried using the type returned by getComplexPartType in , but bbc kept throwing an error that read 'hlfir.designate' op result element type is not consistent with operands, expected '!fir.real<4>'. Is this a change that needs to be made to the designate operation? | |
262–278 | Would the moved resultShape logic be generic and generate a shape for any sequence type that doesn't have a defined resultShape yet or would it be specific to ComplexPart? I'm leaning toward the former given your aside about the substrings, but I'm not sure if that kind of change would break anything unexpected. | |
266 |
|
flang/lib/Lower/ConvertExprToHLFIR.cpp | ||
---|---|---|
260 | Right, I have been a bit too strict in the designator verifier... sorry. However, it will be slightly annoying to get the mlir real type here since this requires access to the kind mapping in designate verifier when dealing with complex part. Not a big deal either, it can be obtained via auto auto kindMap = fir::getKindMapping((*this)->getParentOfType<mlir::ModuleOp>()) And then, one would have to check that kindMap.getFloatSemantics(kind) matches the mlir::RealType::getFloatSemantics() of the result element type (there is sadly no easy way to build the mlir::RealType from the float semantics or kind without a FirOpBuilder, and we do not have that in the verifier, hence the comparison of the float semantics). It is a bit of a pain for the verifier, but I think sticking to mlir::RealType is better at that point. I am ok if you just relax the check at [2] with && !(resultElementType.isa<mlir::RealType>() && outputElementType.isa<fir::RealType>())) for now. | |
262–278 | The former, it should be generic I think. |
flang/lib/Lower/ConvertExprToHLFIR.cpp | ||
---|---|---|
260 | Just to clarify, by mlir::RealType do you mean mlir::FloatType? I can't seem to find any classes named RealType in the docs. |
flang/lib/Lower/ConvertExprToHLFIR.cpp | ||
---|---|---|
260 | Yes, I wrote the comment too fast... it is mlir::FloatType. |
Nit: the lowering code is following LLVM/MLIR coding convention: https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements