95 lines · cpp
1//===- llvm/Support/KnownFPClass.h - Stores known fplcass -------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains a class for representing known fpclasses used by10// computeKnownFPClass.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/Support/KnownFPClass.h"15#include "llvm/Support/ErrorHandling.h"16 17using namespace llvm;18 19/// Return true if it's possible to assume IEEE treatment of input denormals in20/// \p F for \p Val.21static bool inputDenormalIsIEEE(DenormalMode Mode) {22 return Mode.Input == DenormalMode::IEEE;23}24 25static bool inputDenormalIsIEEEOrPosZero(DenormalMode Mode) {26 return Mode.Input == DenormalMode::IEEE ||27 Mode.Input == DenormalMode::PositiveZero;28}29 30bool KnownFPClass::isKnownNeverLogicalZero(DenormalMode Mode) const {31 return isKnownNeverZero() &&32 (isKnownNeverSubnormal() || inputDenormalIsIEEE(Mode));33}34 35bool KnownFPClass::isKnownNeverLogicalNegZero(DenormalMode Mode) const {36 return isKnownNeverNegZero() &&37 (isKnownNeverNegSubnormal() || inputDenormalIsIEEEOrPosZero(Mode));38}39 40bool KnownFPClass::isKnownNeverLogicalPosZero(DenormalMode Mode) const {41 if (!isKnownNeverPosZero())42 return false;43 44 // If we know there are no denormals, nothing can be flushed to zero.45 if (isKnownNeverSubnormal())46 return true;47 48 switch (Mode.Input) {49 case DenormalMode::IEEE:50 return true;51 case DenormalMode::PreserveSign:52 // Negative subnormal won't flush to +053 return isKnownNeverPosSubnormal();54 case DenormalMode::PositiveZero:55 default:56 // Both positive and negative subnormal could flush to +057 return false;58 }59 60 llvm_unreachable("covered switch over denormal mode");61}62 63void KnownFPClass::propagateDenormal(const KnownFPClass &Src,64 DenormalMode Mode) {65 KnownFPClasses = Src.KnownFPClasses;66 // If we aren't assuming the source can't be a zero, we don't have to check if67 // a denormal input could be flushed.68 if (!Src.isKnownNeverPosZero() && !Src.isKnownNeverNegZero())69 return;70 71 // If we know the input can't be a denormal, it can't be flushed to 0.72 if (Src.isKnownNeverSubnormal())73 return;74 75 if (!Src.isKnownNeverPosSubnormal() && Mode != DenormalMode::getIEEE())76 KnownFPClasses |= fcPosZero;77 78 if (!Src.isKnownNeverNegSubnormal() && Mode != DenormalMode::getIEEE()) {79 if (Mode != DenormalMode::getPositiveZero())80 KnownFPClasses |= fcNegZero;81 82 if (Mode.Input == DenormalMode::PositiveZero ||83 Mode.Output == DenormalMode::PositiveZero ||84 Mode.Input == DenormalMode::Dynamic ||85 Mode.Output == DenormalMode::Dynamic)86 KnownFPClasses |= fcPosZero;87 }88}89 90void KnownFPClass::propagateCanonicalizingSrc(const KnownFPClass &Src,91 DenormalMode Mode) {92 propagateDenormal(Src, Mode);93 propagateNaN(Src, /*PreserveSign=*/true);94}95