[RISCV] Inline scalar ceil/floor/trunc/rint/round/roundeven.
authorCraig Topper <craig.topper@sifive.com>
Wed, 26 Oct 2022 21:23:51 +0000 (14:23 -0700)
committerCraig Topper <craig.topper@sifive.com>
Wed, 26 Oct 2022 21:36:49 +0000 (14:36 -0700)
commite94dc58dff1d693912904ba7ff743f67b3348d32
tree0c8234a19ecab52f642b73aee01027a69f8b9658
parent55d08a867056e6ceb62c3a1ce3643345dcfc5dde
[RISCV] Inline scalar ceil/floor/trunc/rint/round/roundeven.

This avoids the call overhead as well as the the save/restore of
fflags and the snan handling in the libm function.

The save/restore of fflags and snan handling are needed to be
correct for -ftrapping-math. I think we can ignore them in the
default environment.

The inline sequence will generate an invalid exception for nan
and an inexact exception if fractional bits are discarded.

I've used a custom inserter to explicitly create the control flow
around the float->int->float conversion.

We can probably avoid the final fsgnj after the conversion for
no signed zeros FMF, but I'll leave that for future work.

Note the comparison constant is slightly different than glibc uses.
They use 1<<53 for double, I'm using 1<<52. I believe either are valid.
Numbers >= 1<<52 can't have any fractional bits. It's ok to do the
float->int->float conversion on numbers between 1<<53 and 1<<52 since
they will all fit in 64. We only have a problem if the double can't fit
in i64

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D136508
15 files changed:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.h
llvm/lib/Target/RISCV/RISCVInstrInfoD.td
llvm/lib/Target/RISCV/RISCVInstrInfoF.td
llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
llvm/test/Analysis/CostModel/RISCV/fround.ll
llvm/test/CodeGen/RISCV/double-intrinsics.ll
llvm/test/CodeGen/RISCV/double-round-conv.ll
llvm/test/CodeGen/RISCV/float-intrinsics.ll
llvm/test/CodeGen/RISCV/float-round-conv-sat.ll
llvm/test/CodeGen/RISCV/float-round-conv.ll
llvm/test/CodeGen/RISCV/half-intrinsics.ll
llvm/test/CodeGen/RISCV/half-round-conv-sat.ll
llvm/test/CodeGen/RISCV/half-round-conv.ll