llvm / llvm/llvm-project

[KnownFPClass] Additional KnownFPClass information for `ldexp`

Open
#214,845 0 comments 0 reactions 0 assignees View on GitHub
floating-point llvm:support
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

https://github.com/llvm/llvm-project/blob/767aafbaa559b090656f069992f040db6bc5d6ee/llvm/lib/Support/KnownFPClass.cpp#L788-L833

Definitions for float32:
- mantissa_bits = 23
- max_normal_exponent = 254
- min_normal_exponent = 1

These are the main special cases in regards to the bounds on the exponent:
- If `exponent >= mantissa_bits`, then the result cannot be subnormal
- If `exponent >= 0`, then subnormal or zero values cannot be introduced
- If `exponent <= 0`, then infinity cannot be introduced

However there are other cases that are missed:
- If `exponent >= -mantissa_bits`, then a normal input cannot become zero (depending on the `DenormalMode`).
- If `exponent <= max_normal_exponent - min_normal_exponent + 1`, then a subnormal input cannot become infinity.

***

There is additional `KnownFPClass` information that can be extracted via the `KnownBits` interface. For example (assuming float32), if we have `ldexpf(subnormal_value, cond ? 0 : 1024)`, then `cond ? 0 : 1024` will be represented by `KnownBits` as `0?00'0000'0000`. The only two possibilities is for the exponent to remain unchanged (result will still be subnormal), or for the exponent to overflow to infinity. The result will never be normal. But if we pass this into the range interface for `KnownFPClass::ldexp`, it will only know that `0 <= exponent <= 1024`, and will have no way of knowing that the exponent is either 0 or 1024, so it will be unable to mark the result as not normal.

The main benefit of this analysis would be determining cases where the non-contiguous ranges representable by `KnownBits` are able to completely skip a `KnownFPClass`. Here is a complete enumeration of these cases:
- `subnormal --> zero OR normal`
- `subnormal --> zero OR infinity`
- `subnormal --> zero OR subnormal OR infinity`
- `subnormal --> zero OR normal OR infinity`
- `subnormal --> subnormal OR infinity`
- `normal --> zero OR normal`
- `normal --> zero OR infinity`
- `normal --> zero OR subnormal OR infinity`
- `normal --> zero OR normal OR infinity`
- `normal --> subnormal OR infinity`

Similar `KnownBits` deductions could also apply to the `KnownBits` interface for `KnownFPClass::powi`

```c++
KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc,
const APInt &ConstantRangeExpMin,
const APInt &ConstantRangeExpMax,
const fltSemantics &Flt, DenormalMode Mode);

KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc,
const KnownBits &ExpBits,
const fltSemantics &Flt, DenormalMode Mode) {
return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
ExpBits.getSignedMaxValue(), Flt, Mode);
}
```

Contributor guide

Open the contributing guide

Research direction

Start with KnownFPClass::ldexp in llvm/lib/Support/KnownFPClass.cpp at the linked lines, then review the KnownBits interface and the proposed overload signature. Use the listed exponent and floating-point-class cases to define the additional deductions, including DenormalMode behavior; done means the KnownBits path preserves the non-contiguous cases that the range interface misses.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.