Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -415,6 +415,16 @@ LLVMDSNote } LLVMDiagnosticSeverity; +typedef enum { + LLVMFastMathFlagsNone = 0, + LLVMFastMathFlagsAllowAlgebra, + LLVMFastMathFlagsNoNaN, + LLVMFastMathFlagsNoInf, + LLVMFastMathFlagsNoSignedZero, + LLVMFastMathFlagsAllowReciprocal +} LLVMFastMathFlags; + + /** * @} */ @@ -2323,6 +2333,69 @@ */ void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node); +/** + * Set the fast math flags in Dest for an individual instruction. + * + * This only returns something if concerned operator is a + * FastMathoperator extension as frem, fadd, fdiv and fsub. + * + * @see llvm::Instruction::getFastMathFlags() + */ +void LLVMGetFastMathFlags(LLVMValueRef Inst, LLVMFastMathFlags* Dest); + +/** + * Returns the number of fast math flags setting for an instruction. + * + * This only returns something if concerned operator is a + * FastMathoperator extension as frem, fadd, fdiv and fsub. + * + */ +int LLVMCountFastMathFlags(LLVMValueRef Inst); + +/** + * Returns n != 0 if the individual instruction contains fast math flags. + * + * This only returns something if concerned operator is a + * FastMathoperator extension as frem, fadd, fdiv and fsub. + * + * @see llvm::Instruction::hasUnsafeAlgebra() + * @see llvm::Instruction::hasNoNans() + * @see llvm::Instruction::hasNoInfs() + * @see llvm::Instruction::hasNoSignedZeros() + * @see llvm::Instruction::hasAllowReciproval() + */ +int LLVMHasFastMathFlag(LLVMValueRef Inst, LLVMFastMathFlags FMF); + +/** + * Returns n != 0 if the individual instruction contains fast math flags. + * + * This only returns something if concerned operator is a + * FastMathoperator extension as frem, fadd, fdiv and fsub. + * + * @see llvm::Instruction::hasUnsafeAlgebra() + * @see llvm::Instruction::hasNoNans() + * @see llvm::Instruction::hasNoInfs() + * @see llvm::Instruction::hasNoSignedZeros() + * @see llvm::Instruction::hasAllowReciproval() + */ +int LLVMHasFastMathFlags(LLVMValueRef Inst); + +/** + * Set an uniq fast math flag on an individual instruction. + * + * This only returns something if concerned operator is a + * FastMathoperator extension as frem, fadd, fdiv and fsub. + * + * @see llvm::Instruction::setFastMathFlags() + * @see llvm::Instruction::setUnsafeAlgebra() + * @see llvm::Instruction::setNoNans() + * @see llvm::Instruction::setNoInfs() + * @see llvm::Instruction::setNoSignedZeros() + * @see llvm::Instruction::setAllowReciproval() + * @see llvm::FastMathFlags::clear() + */ +void LLVMSetFastMathFlag(LLVMValueRef Inst, LLVMFastMathFlags FMF); + /** * Obtain the basic block to which an instruction belongs. * Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -562,6 +562,104 @@ MD ? unwrap(MD) : nullptr); } + +/*--... Operations on Fast Math operator ...................................--*/ + +int LLVMHasFastMathFlags(LLVMValueRef Inst) { + return + (unwrap(Inst)->hasUnsafeAlgebra() + || unwrap(Inst)->hasNoNaNs() + || unwrap(Inst)->hasNoInfs() + || unwrap(Inst)->hasNoSignedZeros() + || unwrap(Inst)->hasAllowReciprocal()); +} + + +int LLVMHasFastMathFlag(LLVMValueRef Inst, LLVMFastMathFlags Flag) { + switch(Flag){ + case LLVMFastMathFlagsAllowAlgebra: + return unwrap(Inst)->hasUnsafeAlgebra(); + break; + case LLVMFastMathFlagsNoNaN: + return unwrap(Inst)->hasNoNaNs(); + break; + case LLVMFastMathFlagsNoInf: + return unwrap(Inst)->hasNoInfs(); + break; + case LLVMFastMathFlagsNoSignedZero: + return unwrap(Inst)->hasNoSignedZeros(); + break; + case LLVMFastMathFlagsAllowReciprocal: + return unwrap(Inst)->hasAllowReciprocal(); + break; + default: return (LLVMHasFastMathFlags(Inst) == 0); + break; + } + +} + +void LLVMSetFastMathFlag(LLVMValueRef Inst, LLVMFastMathFlags Flag){ + switch(Flag){ + case LLVMFastMathFlagsAllowAlgebra: + unwrap(Inst)->setHasUnsafeAlgebra(true); + break; + case LLVMFastMathFlagsNoNaN: + unwrap(Inst)->setHasNoNaNs(true); + break; + case LLVMFastMathFlagsNoInf: + unwrap(Inst)->setHasNoInfs(true); + break; + case LLVMFastMathFlagsNoSignedZero: + unwrap(Inst)->setHasNoSignedZeros(true); + break; + case LLVMFastMathFlagsAllowReciprocal: + unwrap(Inst)->setHasAllowReciprocal(true); + break; + default: /* we suppose LLVMFastMathFlagsNone */ + FastMathFlags fmf = + (unwrap(Inst)->getFastMathFlags()); + fmf.clear(); + unwrap(Inst)->setFastMathFlags(fmf); + break; + } +} + + +int LLVMCountFastMathFlags(LLVMValueRef Inst){ + if (LLVMHasFastMathFlags(Inst) != 0) { + unsigned res = 0; + FastMathFlags fmf = + (unwrap(Inst)->getFastMathFlags()); + if(fmf.noNaNs()) res++; + if(fmf.noInfs()) res++; + if(fmf.noSignedZeros()) res++; + if(fmf.allowReciprocal()) res++; + if(fmf.unsafeAlgebra()) res++; + return res; + } + return 0; +} + +/* returns an array of FMF.t through Dest */ +void LLVMGetFastMathFlags(LLVMValueRef Inst, LLVMFastMathFlags* Dest){ + if (LLVMHasFastMathFlags(Inst) != 0) { + unsigned i = 0; + FastMathFlags fmf = + (unwrap(Inst)->getFastMathFlags()); + if(fmf.noNaNs()) + Dest[i++] = (LLVMFastMathFlagsNoNaN); + if(fmf.noInfs()) + Dest[i++] = (LLVMFastMathFlagsNoInf); + if(fmf.noSignedZeros()) + Dest[i++] = (LLVMFastMathFlagsNoSignedZero); + if(fmf.allowReciprocal()) + Dest[i++] = (LLVMFastMathFlagsAllowReciprocal); + if(fmf.unsafeAlgebra()) + Dest[i++] = (LLVMFastMathFlagsAllowAlgebra); + } +} + + /*--.. Conversion functions ................................................--*/ #define LLVM_DEFINE_VALUE_CAST(name) \