[PATCH] D54749: Saturating float to int casts: Basics [1/n]

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 20 03:49:49 PST 2018


nikic created this revision.
Herald added subscribers: llvm-commits, kristof.beyls, javed.absar.

This is the first part split off from https://reviews.llvm.org/D54696.

---

This patch adds support for the fptoui.sat and fptosi.sat intrinsics, which provide basically the same functionality as the existing fptoui and fptosi instructions, but will saturate (or return 0 for NaN) on values unrepresentable in the target type, instead of returning poison.

The intrinsics have overloaded source and result type and support vector operands:

  i32 @llvm.fptoui.sat.f32.i32(float %f)
  i100 @llvm.fptoui.sat.f64.i100(double %f)
  <4 x i32> @llvm.fptoui.sat.v4f16.v4i32(half %f)
  // etc

On the SelectionDAG layer two new ISD opcodes are added, FP_TO_UINT_SAT and FP_TO_SINT_SAT. These opcodes have two operands and one result. The second operand is a value type operand specifying the saturation width. The idea here is that initially the second operand and the result type are the same, but they may change during type legalization. For example:

  i19 @llvm.fptsi.sat.f32.i19(float %f)
  // builds
  i19 fp_to_sint_sat f, VT:i19
  // type legalizes (through integer result promotion)
  i32 fp_to_sint_sat f, VT:i19

I went for this approach, because saturated conversion does no compose well. There is no good way of "adjusting" a saturating conversion to i32 into one to i19 short of saturating twice. Specifying the saturation width separately allows directly saturating to the correct width.

There are two baseline expansions for the fp_to_xint_sat opcodes. If the integer bounds can be exactly represented in the float type and fminnum/fmaxnum are legal, we can expand to something like:

  f = fmaxnum f, FP(MIN)
  f = fminnum f, FP(MAX)
  i = fptoxi f
  i = select f uo f, 0, i # unnecessary if unsigned as 0 = MIN

If the bounds cannot be exactly represented, we expand to something like this instead:

  i = fptoxi f
  i = select f ult FP(MIN), MIN, i
  i = select f ogt FP(MAX), MAX, i
  i = select f uo f, 0, i # unnecessary if unsigned as 0 = MIN

It should be noted that this expansion assumes a non-trapping fptoxi.

This patch includes only basic legalizations (promoting float operands and integer results), and has asserting dummy methods to mark all the other parts that need to be implemented. We essentially have to implement the full suit of legalizations, because the fp_to_xint_sat instructions fall in the unfortunate category of having different result and operand type (so one does not legalize the other) and also having an additional value type argument that requires special handling.

I'm starting with tests for AArch64 and will move to X86 once all the legalization code is there. AArch64 is more interesting in terms of vector legalization than X86. See https://reviews.llvm.org/D54696 for a preview of where this is going.


Repository:
  rL LLVM

https://reviews.llvm.org/D54749

Files:
  docs/LangRef.rst
  include/llvm/CodeGen/ISDOpcodes.h
  include/llvm/CodeGen/TargetLowering.h
  include/llvm/IR/Intrinsics.td
  include/llvm/Target/TargetSelectionDAG.td
  lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
  lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
  lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
  lib/CodeGen/SelectionDAG/LegalizeTypes.h
  lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
  lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
  lib/CodeGen/SelectionDAG/SelectionDAG.cpp
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
  lib/CodeGen/SelectionDAG/TargetLowering.cpp
  lib/CodeGen/TargetLoweringBase.cpp
  test/CodeGen/AArch64/fptoi-sat-scalar.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54749.174743.patch
Type: text/x-patch
Size: 62559 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181120/a3444f83/attachment.bin>


More information about the llvm-commits mailing list