aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR
diff options
context:
space:
mode:
authorBenji Smith <6193112+Benjins@users.noreply.github.com>2023-12-12 11:15:05 -0500
committerGitHub <noreply@github.com>2023-12-12 17:15:05 +0100
commitd5c95302b9736b4e785c77463d7f2026b772ba1b (patch)
tree201f7e676b77fadd428b0a58599c34cad0b5874c /llvm/lib/IR
parented210f9f5aab70cf4ca242535d1af0b0aa6a5781 (diff)
downloadllvm-d5c95302b9736b4e785c77463d7f2026b772ba1b.zip
llvm-d5c95302b9736b4e785c77463d7f2026b772ba1b.tar.gz
llvm-d5c95302b9736b4e785c77463d7f2026b772ba1b.tar.bz2
[C API] Add getters and setters for fast-math flags on relevant instructions (#75123)
These flags are usable on floating point arithmetic, as well as call, select, and phi instructions whose resulting type is floating point, or a vector of, or an array of, a valid type. Whether or not the flags are valid for a given instruction can be checked with the new LLVMCanValueUseFastMathFlags function. These are exposed using a new LLVMFastMathFlags type, which is an alias for unsigned. An anonymous enum defines the bit values for it. Tests are added in echo.ll for select/phil/call, and the floating point types in the new float_ops.ll bindings test. Select and the floating point arithmetic instructions were not implemented in llvm-c-test/echo.cpp, so they were added as well.
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/Core.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 96629de..fb30fbc 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -3319,6 +3319,39 @@ void LLVMSetArgOperand(LLVMValueRef Funclet, unsigned i, LLVMValueRef value) {
/*--.. Arithmetic ..........................................................--*/
+static FastMathFlags mapFromLLVMFastMathFlags(LLVMFastMathFlags FMF) {
+ FastMathFlags NewFMF;
+ NewFMF.setAllowReassoc((FMF & LLVMFastMathAllowReassoc) != 0);
+ NewFMF.setNoNaNs((FMF & LLVMFastMathNoNaNs) != 0);
+ NewFMF.setNoInfs((FMF & LLVMFastMathNoInfs) != 0);
+ NewFMF.setNoSignedZeros((FMF & LLVMFastMathNoSignedZeros) != 0);
+ NewFMF.setAllowReciprocal((FMF & LLVMFastMathAllowReciprocal) != 0);
+ NewFMF.setAllowContract((FMF & LLVMFastMathAllowContract) != 0);
+ NewFMF.setApproxFunc((FMF & LLVMFastMathApproxFunc) != 0);
+
+ return NewFMF;
+}
+
+static LLVMFastMathFlags mapToLLVMFastMathFlags(FastMathFlags FMF) {
+ LLVMFastMathFlags NewFMF = LLVMFastMathNone;
+ if (FMF.allowReassoc())
+ NewFMF |= LLVMFastMathAllowReassoc;
+ if (FMF.noNaNs())
+ NewFMF |= LLVMFastMathNoNaNs;
+ if (FMF.noInfs())
+ NewFMF |= LLVMFastMathNoInfs;
+ if (FMF.noSignedZeros())
+ NewFMF |= LLVMFastMathNoSignedZeros;
+ if (FMF.allowReciprocal())
+ NewFMF |= LLVMFastMathAllowReciprocal;
+ if (FMF.allowContract())
+ NewFMF |= LLVMFastMathAllowContract;
+ if (FMF.approxFunc())
+ NewFMF |= LLVMFastMathApproxFunc;
+
+ return NewFMF;
+}
+
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name) {
return wrap(unwrap(B)->CreateAdd(unwrap(LHS), unwrap(RHS), Name));
@@ -3518,6 +3551,22 @@ void LLVMSetNNeg(LLVMValueRef NonNegInst, LLVMBool IsNonNeg) {
cast<Instruction>(P)->setNonNeg(IsNonNeg);
}
+LLVMFastMathFlags LLVMGetFastMathFlags(LLVMValueRef FPMathInst) {
+ Value *P = unwrap<Value>(FPMathInst);
+ FastMathFlags FMF = cast<Instruction>(P)->getFastMathFlags();
+ return mapToLLVMFastMathFlags(FMF);
+}
+
+void LLVMSetFastMathFlags(LLVMValueRef FPMathInst, LLVMFastMathFlags FMF) {
+ Value *P = unwrap<Value>(FPMathInst);
+ cast<Instruction>(P)->setFastMathFlags(mapFromLLVMFastMathFlags(FMF));
+}
+
+LLVMBool LLVMCanValueUseFastMathFlags(LLVMValueRef V) {
+ Value *Val = unwrap<Value>(V);
+ return isa<FPMathOperator>(Val);
+}
+
LLVMBool LLVMGetIsDisjoint(LLVMValueRef Inst) {
Value *P = unwrap<Value>(Inst);
return cast<PossiblyDisjointInst>(P)->isDisjoint();