zahiraam marked 7 inline comments as done.
zahiraam added inline comments.
================
Comment at: clang/lib/CodeGen/CGExprComplex.cpp:896
+
+ComplexPairTy ComplexExprEmitter::EmitPromoted(const Expr *E) {
+ if (auto *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens())) {
----------------
pengfei wrote:
> rjmccall wrote:
> > pengfei wrote:
> > > rjmccall wrote:
> > > > zahiraam wrote:
> > > > > rjmccall wrote:
> > > > > > `EmitPromoted` should take the promotion type.
> > > > > >
> > > > > > You are missing the logic in this file which handles *unpromoted*
> > > > > > emission (where you have a binary operator but the context wants an
> > > > > > unpromoted value) by recognizing that you need to do a promoted
> > > > > > operation and then truncate.
> > > > > Sorry but not sure what you mean here. A case where we don't want any
> > > > > promotion would be:
> > > > >
> > > > > float _Complex add(float _Complex a, float _Complex b) {
> > > > > return a + b;
> > > > > }
> > > > >
> > > > > In this case, getPromotionType would return the null type and
> > > > > EmitBinOps would just go through the "older" control path where
> > > > > there is no promotion.
> > > > > Unless I misunderstood your comment?
> > > > >
> > > > >
> > > > I'm talking about the unpromoted emission path for an operation that we
> > > > want to *internally* promote. So like your example but using
> > > > `_Float16` — we want to emit the binary `+` as a `float` operation, but
> > > > the context needs an unpromoted value because it's going to be returned.
> > > >
> > > > The promoted emission path (the various `EmitPromoted` methods)
> > > > represents a request by the caller to produce a result that doesn't
> > > > match the formal type of the expression. The normal emission path
> > > > `Visit` etc.) represents a request by the caller to produce a result
> > > > normally, i.e. one that matches the formal type. In general, we always
> > > > start in the latter because arbitrary contexts always expect a value of
> > > > the formal type; it's only these recursive calls within promoted
> > > > emitters that contextually want a promoted value.
> > > >
> > > > In your current patch, you're entering the promoted path by
> > > > special-casing one context that frequently terminates promoted
> > > > emission: `EmitComplexExprIntoLValue`, which is used for things like
> > > > assignment. That's not the right way to handle it, though. Instead,
> > > > you should do like I asked you to do with the scalar emitter, which is
> > > > to recognize in the normal emission path for a promotable operation
> > > > (like binary `+`) that you need to promote the operation and then
> > > > unpromote the result. Then things like `EmitComplexExprIntoLValue`
> > > > will continue to simply enter the normal path because that's the kind
> > > > of value they need, and the promotion logic will do the right thing
> > > > from there to ensure we don't emit a `_Float16` operation in LLVM IR.
> > > >
> > > > Incidentally, I thought of another context that you ought to do
> > > > promotion for: when we're converting a promotable value to a larger
> > > > floating-point type, we should presumably convert the promoted value
> > > > directly rather than truncating it to the unpromoted type before the
> > > > conversion.
> > > I'm not familiar with the FE details, but I understand the background is
> > > just to promote expressions that have more than one operation. So I agree
> > > with @zahiraam, and
> > > > to ensure we don't emit a _Float16 operation in LLVM IR
> > > is not what we expected here.
> > >
> > > `_Float16` is a ABI type for which a target supported has to lower any
> > > `_Float16` operations in LLVM IR. See what we have done on X86 backend by
> > > D107082.
> > >
> > > That said, a single `a + b` can be and should be emitted as `%c = fadd
> > > half %a, %b`.
> > Well, you can provide operation-by-operation lowering support if you want
> > to, but what's going to come out of Clang IRGen in this mode is not going
> > to rely on it. It's far easier to just emit these operations differently,
> > always using `float`, than to try to recognize the special cases where all
> > the inputs are naturally `half` and so you might as well emit a `half`
> > operation.
> >
> > And I think the postcondition that `half` operations don't come out of
> > IRGen is a generally useful property even if you've already written this
> > lowering code. Among other things, it makes it easy to test that you
> > haven't missed a case where you should be doing promoted emission.
> We define `_Float16` as ABI type and require targets to support the ABI
> lowering. See
> https://clang.llvm.org/docs/LanguageExtensions.html#half-precision-floating-point
> Promoting in FE doesn't mean it works on any targets by default, so I think
> it's not much useful.
> We need to support `-fexcess-precision=16` the same as GCC does, it's easier
> to do nothing than promote and then truncate each of the operations in FE.
> I think in general, lowering operations for a type is a business of backend.
> We still need backend to do so for other FEs even we do it in Clang. A recent
> example is BF16, which people chose to lower in backend rather than mlir, see
> D126444.
>
> > Among other things, it makes it easy to test that you haven't missed a case
> > where you should be doing promoted emission.
> I don't understand, how can we check the missed cases if the promotion was
> done in FE?
This patch is doing by default what GCC is doing with the
-fexcess-precision=16. And that would be for expressions with any number of
operators. But it looks like you want promotion/truncation only for expression
with more than one operator? I think I agree with @rjmccall that it is easier
done this way than trying to recognize the special cases.
What you want is for a+b to generate fadd half (not extension, and no
truncation ) and for a+b*c to generated a set of fpext, fadd float and fptrunc?
Does GCC use their option for special cases too? I would think that when this
option is used all expression (regardless of the number of operators) are
extended/truncated right?
I am not sure I like the idea of lowering some cases in the FE and some others
in the BE. I think it would be cleaner to decide that lowering be done in FE
for all expressions and have BE react to it.
@rmjccall not sure what you mean by:
"And I think the postcondition that half operations don't come out of IRGen is
a generally useful property even if you've already written this lowering code.
Among other things, it makes it easy to test that you haven't missed a case
where you should be doing promoted emission."
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D113107/new/
https://reviews.llvm.org/D113107
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits