diff options
author | Yingwei Zheng <dtcxzyw2333@gmail.com> | 2025-10-13 22:28:38 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-10-13 22:28:38 +0800 |
commit | 0dc44b31347c48e5ec966901bb729f60a10a4a42 (patch) | |
tree | e041f955d83d39b301b2fb26438abea924eb67a6 /llvm/lib/IR/ConstantFPRange.cpp | |
parent | 8823efe77dad40eaea63b539c4d3d1036587ceb0 (diff) | |
download | llvm-0dc44b31347c48e5ec966901bb729f60a10a4a42.zip llvm-0dc44b31347c48e5ec966901bb729f60a10a4a42.tar.gz llvm-0dc44b31347c48e5ec966901bb729f60a10a4a42.tar.bz2 |
[ConstantFPRange] Add support for flushDenormals (#163074)
This patch provides a helper function to handle non-IEEE denormal
flushing behaviours. For the dynamic mode, it returns a union of all
possible results.
Diffstat (limited to 'llvm/lib/IR/ConstantFPRange.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantFPRange.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantFPRange.cpp b/llvm/lib/IR/ConstantFPRange.cpp index 51d2e21..e9c058e 100644 --- a/llvm/lib/IR/ConstantFPRange.cpp +++ b/llvm/lib/IR/ConstantFPRange.cpp @@ -8,6 +8,7 @@ #include "llvm/IR/ConstantFPRange.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include <cassert> @@ -506,3 +507,24 @@ ConstantFPRange ConstantFPRange::sub(const ConstantFPRange &Other) const { // fsub X, Y = fadd X, (fneg Y) return add(Other.negate()); } + +void ConstantFPRange::flushDenormals(DenormalMode::DenormalModeKind Mode) { + if (Mode == DenormalMode::IEEE) + return; + FPClassTest Class = classify(); + if (!(Class & fcSubnormal)) + return; + + auto &Sem = getSemantics(); + // PreserveSign: PosSubnormal -> PosZero, NegSubnormal -> NegZero + // PositiveZero: PosSubnormal -> PosZero, NegSubnormal -> PosZero + // Dynamic: PosSubnormal -> PosZero, NegSubnormal -> NegZero/PosZero + bool ZeroLowerNegative = + Mode != DenormalMode::PositiveZero && (Class & fcNegSubnormal); + bool ZeroUpperNegative = + Mode == DenormalMode::PreserveSign && !(Class & fcPosSubnormal); + assert((ZeroLowerNegative || !ZeroUpperNegative) && + "ZeroLower is greater than ZeroUpper."); + Lower = minnum(Lower, APFloat::getZero(Sem, ZeroLowerNegative)); + Upper = maxnum(Upper, APFloat::getZero(Sem, ZeroUpperNegative)); +} |