diff options
author | Benji Smith <6193112+Benjins@users.noreply.github.com> | 2023-12-12 11:15:05 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-12 17:15:05 +0100 |
commit | d5c95302b9736b4e785c77463d7f2026b772ba1b (patch) | |
tree | 201f7e676b77fadd428b0a58599c34cad0b5874c /llvm/lib/IR | |
parent | ed210f9f5aab70cf4ca242535d1af0b0aa6a5781 (diff) | |
download | llvm-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.cpp | 49 |
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(); |