Path: blob/main/contrib/llvm-project/llvm/lib/IR/FPEnv.cpp
35233 views
//===-- FPEnv.cpp ---- FP Environment -------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8/// @file9/// This file contains the implementations of entities that describe floating10/// point environment.11//12//===----------------------------------------------------------------------===//1314#include "llvm/IR/FPEnv.h"15#include "llvm/ADT/StringSwitch.h"16#include "llvm/IR/Instruction.h"17#include "llvm/IR/IntrinsicInst.h"18#include "llvm/IR/Intrinsics.h"19#include <optional>2021namespace llvm {2223std::optional<RoundingMode> convertStrToRoundingMode(StringRef RoundingArg) {24// For dynamic rounding mode, we use round to nearest but we will set the25// 'exact' SDNodeFlag so that the value will not be rounded.26return StringSwitch<std::optional<RoundingMode>>(RoundingArg)27.Case("round.dynamic", RoundingMode::Dynamic)28.Case("round.tonearest", RoundingMode::NearestTiesToEven)29.Case("round.tonearestaway", RoundingMode::NearestTiesToAway)30.Case("round.downward", RoundingMode::TowardNegative)31.Case("round.upward", RoundingMode::TowardPositive)32.Case("round.towardzero", RoundingMode::TowardZero)33.Default(std::nullopt);34}3536std::optional<StringRef> convertRoundingModeToStr(RoundingMode UseRounding) {37std::optional<StringRef> RoundingStr;38switch (UseRounding) {39case RoundingMode::Dynamic:40RoundingStr = "round.dynamic";41break;42case RoundingMode::NearestTiesToEven:43RoundingStr = "round.tonearest";44break;45case RoundingMode::NearestTiesToAway:46RoundingStr = "round.tonearestaway";47break;48case RoundingMode::TowardNegative:49RoundingStr = "round.downward";50break;51case RoundingMode::TowardPositive:52RoundingStr = "round.upward";53break;54case RoundingMode::TowardZero:55RoundingStr = "round.towardzero";56break;57default:58break;59}60return RoundingStr;61}6263std::optional<fp::ExceptionBehavior>64convertStrToExceptionBehavior(StringRef ExceptionArg) {65return StringSwitch<std::optional<fp::ExceptionBehavior>>(ExceptionArg)66.Case("fpexcept.ignore", fp::ebIgnore)67.Case("fpexcept.maytrap", fp::ebMayTrap)68.Case("fpexcept.strict", fp::ebStrict)69.Default(std::nullopt);70}7172std::optional<StringRef>73convertExceptionBehaviorToStr(fp::ExceptionBehavior UseExcept) {74std::optional<StringRef> ExceptStr;75switch (UseExcept) {76case fp::ebStrict:77ExceptStr = "fpexcept.strict";78break;79case fp::ebIgnore:80ExceptStr = "fpexcept.ignore";81break;82case fp::ebMayTrap:83ExceptStr = "fpexcept.maytrap";84break;85}86return ExceptStr;87}8889Intrinsic::ID getConstrainedIntrinsicID(const Instruction &Instr) {90Intrinsic::ID IID = Intrinsic::not_intrinsic;91switch (Instr.getOpcode()) {92case Instruction::FCmp:93// Unlike other instructions FCmp can be mapped to one of two intrinsic94// functions. We choose the non-signaling variant.95IID = Intrinsic::experimental_constrained_fcmp;96break;9798// Instructions99#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \100case Instruction::NAME: \101IID = Intrinsic::INTRINSIC; \102break;103#define FUNCTION(NAME, NARG, ROUND_MODE, INTRINSIC)104#define CMP_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN)105#include "llvm/IR/ConstrainedOps.def"106107// Intrinsic calls.108case Instruction::Call:109if (auto *IntrinCall = dyn_cast<IntrinsicInst>(&Instr)) {110switch (IntrinCall->getIntrinsicID()) {111#define FUNCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \112case Intrinsic::NAME: \113IID = Intrinsic::INTRINSIC; \114break;115#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC)116#define CMP_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN)117#include "llvm/IR/ConstrainedOps.def"118default:119break;120}121}122break;123default:124break;125}126127return IID;128}129130} // namespace llvm131132133