123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- //===-- FPEnv.cpp ---- FP Environment -------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- /// @file
- /// This file contains the implementations of entities that describe floating
- /// point environment.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/IR/FPEnv.h"
- #include "llvm/ADT/StringSwitch.h"
- #include "llvm/IR/Instruction.h"
- #include "llvm/IR/IntrinsicInst.h"
- #include "llvm/IR/Intrinsics.h"
- #include <optional>
- namespace llvm {
- std::optional<RoundingMode> convertStrToRoundingMode(StringRef RoundingArg) {
- // For dynamic rounding mode, we use round to nearest but we will set the
- // 'exact' SDNodeFlag so that the value will not be rounded.
- return StringSwitch<std::optional<RoundingMode>>(RoundingArg)
- .Case("round.dynamic", RoundingMode::Dynamic)
- .Case("round.tonearest", RoundingMode::NearestTiesToEven)
- .Case("round.tonearestaway", RoundingMode::NearestTiesToAway)
- .Case("round.downward", RoundingMode::TowardNegative)
- .Case("round.upward", RoundingMode::TowardPositive)
- .Case("round.towardzero", RoundingMode::TowardZero)
- .Default(std::nullopt);
- }
- std::optional<StringRef> convertRoundingModeToStr(RoundingMode UseRounding) {
- std::optional<StringRef> RoundingStr;
- switch (UseRounding) {
- case RoundingMode::Dynamic:
- RoundingStr = "round.dynamic";
- break;
- case RoundingMode::NearestTiesToEven:
- RoundingStr = "round.tonearest";
- break;
- case RoundingMode::NearestTiesToAway:
- RoundingStr = "round.tonearestaway";
- break;
- case RoundingMode::TowardNegative:
- RoundingStr = "round.downward";
- break;
- case RoundingMode::TowardPositive:
- RoundingStr = "round.upward";
- break;
- case RoundingMode::TowardZero:
- RoundingStr = "round.towardzero";
- break;
- default:
- break;
- }
- return RoundingStr;
- }
- std::optional<fp::ExceptionBehavior>
- convertStrToExceptionBehavior(StringRef ExceptionArg) {
- return StringSwitch<std::optional<fp::ExceptionBehavior>>(ExceptionArg)
- .Case("fpexcept.ignore", fp::ebIgnore)
- .Case("fpexcept.maytrap", fp::ebMayTrap)
- .Case("fpexcept.strict", fp::ebStrict)
- .Default(std::nullopt);
- }
- std::optional<StringRef>
- convertExceptionBehaviorToStr(fp::ExceptionBehavior UseExcept) {
- std::optional<StringRef> ExceptStr;
- switch (UseExcept) {
- case fp::ebStrict:
- ExceptStr = "fpexcept.strict";
- break;
- case fp::ebIgnore:
- ExceptStr = "fpexcept.ignore";
- break;
- case fp::ebMayTrap:
- ExceptStr = "fpexcept.maytrap";
- break;
- }
- return ExceptStr;
- }
- Intrinsic::ID getConstrainedIntrinsicID(const Instruction &Instr) {
- Intrinsic::ID IID = Intrinsic::not_intrinsic;
- switch (Instr.getOpcode()) {
- case Instruction::FCmp:
- // Unlike other instructions FCmp can be mapped to one of two intrinsic
- // functions. We choose the non-signaling variant.
- IID = Intrinsic::experimental_constrained_fcmp;
- break;
- // Instructions
- #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
- case Instruction::NAME: \
- IID = Intrinsic::INTRINSIC; \
- break;
- #define FUNCTION(NAME, NARG, ROUND_MODE, INTRINSIC)
- #define CMP_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN)
- #include "llvm/IR/ConstrainedOps.def"
- // Intrinsic calls.
- case Instruction::Call:
- if (auto *IntrinCall = dyn_cast<IntrinsicInst>(&Instr)) {
- switch (IntrinCall->getIntrinsicID()) {
- #define FUNCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
- case Intrinsic::NAME: \
- IID = Intrinsic::INTRINSIC; \
- break;
- #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC)
- #define CMP_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN)
- #include "llvm/IR/ConstrainedOps.def"
- default:
- break;
- }
- }
- break;
- default:
- break;
- }
- return IID;
- }
- } // namespace llvm
|