diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2011-10-27 19:19:51 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2011-10-27 19:19:51 +0000 |
commit | c5096cbf7a42e0f9012945b00d9037a5b5a88d72 (patch) | |
tree | 84a9e447bd9b0917cdf7c57a07984d9c0b68bb76 /lib/CodeGen/CGExprScalar.cpp | |
parent | 9d31fa75bc05fe4cb903a7701550f22cfb73ea8b (diff) |
Annotate imprecise FP division with fpaccuracy metadata
The OpenCL single precision division operation is only required to
be accurate to 2.5ulp. Annotate the fdiv instruction with metadata
which signals to the backend that an imprecise divide instruction
may be used.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143136 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 582d1c4572..25b4a0a0e7 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1772,8 +1772,18 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { Builder.SetInsertPoint(DivCont); } } - if (Ops.LHS->getType()->isFPOrFPVectorTy()) - return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div"); + if (Ops.LHS->getType()->isFPOrFPVectorTy()) { + llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div"); + if (CGF.getContext().getLangOptions().OpenCL) { + // OpenCL 1.1 7.4: minimum accuracy of single precision / is 2.5ulp + llvm::Type *ValTy = Val->getType(); + if (ValTy->isFloatTy() || + (isa<llvm::VectorType>(ValTy) && + cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy())) + CGF.SetFPAccuracy(Val, 5, 2); + } + return Val; + } else if (Ops.Ty->hasUnsignedIntegerRepresentation()) return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div"); else |