From: Duncan Sands Date: Tue, 10 Apr 2012 08:22:43 +0000 (+0000) Subject: Express the number of ULPs in fpaccuracy metadata as a real rather than a X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1fd63df6930a83d9d1378d2c68e19850c652078e;p=oota-llvm.git Express the number of ULPs in fpaccuracy metadata as a real rather than a rational number, eg as 2.5 rather than 5, 2. OK'd by Peter Collingbourne. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154387 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LangRef.html b/docs/LangRef.html index e6d47a6ce5b..4f6b137ed18 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -3021,13 +3021,13 @@ call void @llvm.dbg.value(metadata !24, i64 0, metadata !25) -

The maximum relative error may be any rational number. The metadata node - shall consist of a pair of unsigned integers respectively representing - the numerator and denominator. For example, 2.5 ULP:

+

The metadata node shall consist of a single non-negative floating + point number representing the maximum relative error. For example, + 2.5 ULP:

-!0 = metadata !{ i32 5, i32 2 }
+!0 = metadata !{ float 2.5 }
 
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index d40727dfcef..2b466f900c8 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -320,6 +320,7 @@ namespace llvm { const fltSemantics &getSemantics() const { return *semantics; } bool isZero() const { return category == fcZero; } bool isNonZero() const { return category != fcZero; } + bool isNormal() const { return category == fcNormal; } bool isNaN() const { return category == fcNaN; } bool isInfinity() const { return category == fcInfinity; } bool isNegative() const { return sign; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index b6648016c66..96492e44d56 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1653,6 +1653,18 @@ void Verifier::visitInstruction(Instruction &I) { } } + if (MDNode *MD = I.getMetadata(LLVMContext::MD_fpaccuracy)) { + Assert1(I.getType()->isFPOrFPVectorTy(), + "fpaccuracy requires a floating point result!", &I); + Assert1(MD->getNumOperands() == 1, "fpaccuracy takes one operand!", &I); + ConstantFP *Op = dyn_cast_or_null(MD->getOperand(0)); + Assert1(Op, "fpaccuracy ULPs not a floating point number!", &I); + APFloat ULPs = Op->getValueAPF(); + Assert1(ULPs.isNormal() || ULPs.isZero(), + "fpaccuracy ULPs not a normal number!", &I); + Assert1(!ULPs.isNegative(), "fpaccuracy ULPs is negative!", &I); + } + MDNode *MD = I.getMetadata(LLVMContext::MD_range); Assert1(!MD || isa(I), "Ranges are only for loads!", &I); diff --git a/test/Verifier/fpaccuracy.ll b/test/Verifier/fpaccuracy.ll new file mode 100644 index 00000000000..2fefde09f18 --- /dev/null +++ b/test/Verifier/fpaccuracy.ll @@ -0,0 +1,31 @@ +; RUN: not llvm-as < %s |& FileCheck %s + +define void @foo(i32 %i, float %f, <2 x float> %g) { + %s = add i32 %i, %i, !fpaccuracy !0 +; CHECK: fpaccuracy requires a floating point result! + %t = fadd float %f, %f, !fpaccuracy !1 +; CHECK: fpaccuracy takes one operand! + %u = fadd float %f, %f, !fpaccuracy !2 +; CHECK: fpaccuracy takes one operand! + %v = fadd float %f, %f, !fpaccuracy !3 +; CHECK: fpaccuracy ULPs not a floating point number! + %w = fadd float %f, %f, !fpaccuracy !0 +; Above line is correct. + %w2 = fadd <2 x float> %g, %g, !fpaccuracy !0 +; Above line is correct. + %x = fadd float %f, %f, !fpaccuracy !4 +; CHECK: fpaccuracy ULPs is negative! + %y = fadd float %f, %f, !fpaccuracy !5 +; CHECK: fpaccuracy ULPs is negative! + %z = fadd float %f, %f, !fpaccuracy !6 +; CHECK: fpaccuracy ULPs not a normal number! + ret void +} + +!0 = metadata !{ float 1.0 } +!1 = metadata !{ } +!2 = metadata !{ float 1.0, float 1.0 } +!3 = metadata !{ i32 1 } +!4 = metadata !{ float -1.0 } +!5 = metadata !{ float -0.0 } +!6 = metadata !{ float 0x7FFFFFFF00000000 }