diff options
Diffstat (limited to 'llvm/lib/IR/FPEnv.cpp')
-rw-r--r-- | llvm/lib/IR/FPEnv.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/llvm/lib/IR/FPEnv.cpp b/llvm/lib/IR/FPEnv.cpp index c6e0938e71a6..48ee84080e98 100644 --- a/llvm/lib/IR/FPEnv.cpp +++ b/llvm/lib/IR/FPEnv.cpp @@ -14,6 +14,9 @@ #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" namespace llvm { @@ -82,4 +85,46 @@ convertExceptionBehaviorToStr(fp::ExceptionBehavior UseExcept) { } 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 |