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

Reply via email to