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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to