[PATCH] D42318: [ARM] Pass _Float16 as int or float

Sjoerd Meijer via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 22 09:05:59 PST 2018


SjoerdMeijer added a comment.

Thanks for reviewing!

We are trying to achieve correct AAPCS parameter passing:

"If the argument is a Half-precision Floating  Point Type its size is set to 4 bytes as if it 
had been copied to the least significant bits of a 32-bit register and the remaining bits filled
with unspecified values"

and for returning results:

"A Half-precision Floating Point Type is returned in the least significant 16 bits of r0."

Summarising: AAPCS compliance for passing/returning _Float16 values.

Ideal solution would be to lower this:

  _Float16 sub(_Float16 a, _Float16 b) {
    return a + b;
  }

to this:

  define half @sub(half %a, half %b) local_unnamed_addr {
  entry:
    %add = fadd half %a, %b
    ret half %add
  }

but with this patch we are generating:

  define float @sub(float %a.coerce, float %b.coerce) local_unnamed_addr #0 {
  entry:
    %0 = bitcast float %a.coerce to i32
    %tmp.0.extract.trunc = trunc i32 %0 to i16
    %1 = bitcast i16 %tmp.0.extract.trunc to half
    <SNIP>
    %add = fadd half %1, %3
    <SNIP>
  }

With this we achieve that we pass a float, and interpret only the lower 16 bits (and 
similar approach for the return value that I've omitted here).

Thus, we are working around the problem of legalizing f16 arguments/return values; 
we are now doing this in Clang and thus don't have to do anything at all in the backend. 
This is a 2-lines change, and enables to make progress with the Armv8.2-A FP16 tablegen 
descriptions and also to start testing/using them; adjusting the calling conventions in the backend are 
a bit more involved. I will start working on this ideal solution now, and once that is in place, 
we can properly pass the half types and remove this workaround.


https://reviews.llvm.org/D42318





More information about the cfe-commits mailing list