pengfei 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())) {
----------------
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?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113107/new/

https://reviews.llvm.org/D113107

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to