| Issue |
173021
|
| Summary |
Implement expansion for modf intrinsic without libcall
|
| Labels |
good first issue,
llvm:globalisel,
floating-point,
llvm:SelectionDAG
|
| Assignees |
|
| Reporter |
arsenm
|
Currently the legalization does only supports expansion of the modf intrinsic to a library call, and [the legalizer will error](https://godbolt.org/z/3nn1M91Go)
The inline expansion of this is not long and manageable by the compiler.
```
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s
define { half, half } @test_modf_f16(half %x) {
%modf = call { half, half } @llvm.modf.f16(half %x)
ret { half, half } %modf
}
define { float, float } @test_modf_f32(float %x) {
%modf = call { float, float } @llvm.modf.f32(float %x)
ret { float, float } %modf
}
define { double, double } @test_modf_f64(double %x) {
%modf = call { double, double } @llvm.modf.f64(double %x)
ret { double, double } %modf
}
```
A reference implementation of the C function looks something like:
```
float modf(float x, float *iptr)
{
float tx = truncf(x); // ISD::FTRUNC
float ret = x - tx; // ISD::FSUB
ret = isinf(x) ? 0.0f : ret; // ISD::SETCC, ISD::SELECT
*iptr = tx;
return copysignf(ret, x); // ISD::FCOPYSIGN
}
```
The intrinsic doesn't use a pointer argument, and instead returns a struct. In SelectionDAG this is represented as a node with multiple return values, but this implementation should map directly onto SelectionDAG operations.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs