This is an archive of the discontinued LLVM Phabricator instance.

[flang] Lower complex part
ClosedPublic

Authored by elmcdonough on Feb 28 2023, 2:01 PM.

Details

Summary

Implements HLFIR lowering for %im and %re.

Diff Detail

Event Timeline

elmcdonough created this revision.Feb 28 2023, 2:01 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 28 2023, 2:01 PM
elmcdonough requested review of this revision.Feb 28 2023, 2:01 PM

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.

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.

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
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).
But the rest of lowering is now directly using the mlir floating point type for reals, so there is not much point trying to keep the KIND abstraction here.

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).
If not, better to not add this check here because would lead to think that this is possible.

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
  1. I never actually encountered a case where the box address check mattered, I just added it to be safe because I didn't realize visit unwraps the type.
  2. Will do.
jeanPerier added inline comments.Mar 2 2023, 8:19 AM
flang/lib/Lower/ConvertExprToHLFIR.cpp
260

Right, I have been a bit too strict in the designator verifier... sorry.
I see that the verifier is looking for the fir.real type here: https://github.com/llvm/llvm-project/blob/7f7ebff35a0bd1a161530f056a653741938135bb/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp#L319-L323

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.

[2]: https://github.com/llvm/llvm-project/blob/7f7ebff35a0bd1a161530f056a653741938135bb/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp#L339

262–278

The former, it should be generic I think.

elmcdonough added inline comments.Mar 2 2023, 8:54 AM
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.

jeanPerier added inline comments.Mar 3 2023, 12:20 AM
flang/lib/Lower/ConvertExprToHLFIR.cpp
260

Yes, I wrote the comment too fast... it is mlir::FloatType.

jeanPerier accepted this revision.Mar 7 2023, 12:05 AM

Looks great, thanks.

This revision is now accepted and ready to land.Mar 7 2023, 12:05 AM
This revision was automatically updated to reflect the committed changes.