diff options
author | Duncan Sands <baldrick@free.fr> | 2012-04-16 16:28:59 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2012-04-16 16:28:59 +0000 |
commit | 8883c43ddc13e5f92ba8dfe00f2116a153a570d5 (patch) | |
tree | 40b5bad6be11275bb56cb7f227d1e4ee6544718d /lib/VMCore | |
parent | 9e67db4af13abb967cae5858502207a43d26bf84 (diff) | |
download | external_llvm-8883c43ddc13e5f92ba8dfe00f2116a153a570d5.zip external_llvm-8883c43ddc13e5f92ba8dfe00f2116a153a570d5.tar.gz external_llvm-8883c43ddc13e5f92ba8dfe00f2116a153a570d5.tar.bz2 |
Make it possible to indicate relaxed floating point requirements at the IR level
through the use of 'fpmath' metadata. Currently this only provides a 'fpaccuracy'
value, which may be a number in ULPs or the keyword 'fast', however the intent is
that this will be extended with additional information about NaN's, infinities
etc later. No optimizations have been hooked up to this so far.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154822 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/Instructions.cpp | 38 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 16 |
2 files changed, 48 insertions, 6 deletions
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 8db6ac9..185cd05 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -2003,6 +2003,44 @@ bool BinaryOperator::isExact() const { } //===----------------------------------------------------------------------===// +// FPMathOperator Class +//===----------------------------------------------------------------------===// + +/// getFPAccuracy - Get the maximum error permitted by this operation in ULPs. +/// An accuracy of 0.0 means that the operation should be performed with the +/// default precision. A huge value is returned if the accuracy is 'fast'. +float FPMathOperator::getFPAccuracy() const { + const MDNode *MD = + cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath); + if (!MD) + return 0.0; + Value *Op = MD->getOperand(0); + if (const ConstantFP *Accuracy = dyn_cast<ConstantFP>(Op)) + return Accuracy->getValueAPF().convertToFloat(); + // If it's not a floating point number then it must be 'fast'. + assert(isa<MDString>(Op) && cast<MDString>(Op)->getString() == "fast" && + "Expected the 'fast' keyword!"); + return HUGE_VALF; +} + +/// isFastFPAccuracy - Return true if the accuracy is 'fast'. This says that +/// speed is more important than accuracy. +bool FPMathOperator::isFastFPAccuracy() const { + const MDNode *MD = + cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath); + if (!MD) + return false; + Value *Op = MD->getOperand(0); + if (isa<ConstantFP>(Op)) + return false; + // If it's not a floating point number then it must be 'fast'. + assert(isa<MDString>(Op) && cast<MDString>(Op)->getString() == "fast" && + "Expected the 'fast' keyword!"); + return true; +} + + +//===----------------------------------------------------------------------===// // CastInst Class //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index ab79d8c..2576766 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1657,12 +1657,16 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(I.getType()->isFPOrFPVectorTy(), "fpmath requires a floating point result!", &I); Assert1(MD->getNumOperands() == 1, "fpmath takes one operand!", &I); - ConstantFP *Op = dyn_cast_or_null<ConstantFP>(MD->getOperand(0)); - Assert1(Op, "fpmath ULPs not a floating point number!", &I); - APFloat ULPs = Op->getValueAPF(); - Assert1(ULPs.isNormal() || ULPs.isZero(), - "fpmath ULPs not a normal number!", &I); - Assert1(!ULPs.isNegative(), "fpmath ULPs is negative!", &I); + Value *Op0 = MD->getOperand(0); + if (ConstantFP *CFP0 = dyn_cast_or_null<ConstantFP>(Op0)) { + APFloat Accuracy = CFP0->getValueAPF(); + Assert1(Accuracy.isNormal() && !Accuracy.isNegative(), + "fpmath accuracy not a positive number!", &I); + } else if (MDString *S0 = dyn_cast_or_null<MDString>(Op0)) { + Assert1(S0->getString() == "fast", "wrong fpmath accuracy keyword!", &I); + } else { + Assert1(false, "invalid fpmath accuracy!", &I); + } } MDNode *MD = I.getMetadata(LLVMContext::MD_range); |