Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -2324,6 +2324,69 @@ */ void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node); +/** + * Returns all the fast math flags 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() + */ +int LLVMGetFastMathFlags(LLVMValueRef Inst); + +/** + * 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 LLVMHasFastMathFlags(LLVMValueRef Inst, int Flags); + +/** + * 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); + +/** + * 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 LLVMSetFastMathFlags(LLVMValueRef Inst, int Flags); + /** * 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,94 @@ MD ? unwrap(MD) : nullptr); } +/*--... Operations on Fast Math operator ...................................--*/ +/// Has at least one flag setted +int LLVMHasFastMathFlag(LLVMValueRef Inst) { + return + (unwrap(Inst)->hasUnsafeAlgebra() + || unwrap(Inst)->hasNoNaNs() + || unwrap(Inst)->hasNoInfs() + || unwrap(Inst)->hasNoSignedZeros() + || unwrap(Inst)->hasAllowReciprocal()); +} + +/// Has exactly these flags ! +int LLVMHasFastMathFlags(LLVMValueRef Inst, int Flags) { + if (0 == Flags) return false; + bool has = true; + if (Flags & FastMathFlags::UnsafeAlgebra) + has = has && unwrap(Inst)->hasUnsafeAlgebra(); + if (Flags & FastMathFlags::NoNaNs) + has = has && unwrap(Inst)->hasNoNaNs(); + if (Flags & FastMathFlags::NoInfs) + has = has && unwrap(Inst)->hasNoInfs(); + if (Flags & FastMathFlags::NoSignedZeros) + has = has && unwrap(Inst)->hasNoSignedZeros(); + if (Flags & FastMathFlags::AllowReciprocal) + has = has && unwrap(Inst)->hasAllowReciprocal(); + return has; +} + +void LLVMSetFastMathFlags(LLVMValueRef Inst, int Flags){ + if (0 == Flags){ + FastMathFlags fmf = + (unwrap(Inst)->getFastMathFlags()); + fmf.clear(); + unwrap(Inst)->setFastMathFlags(fmf); + unwrap(Inst)->setHasUnsafeAlgebra(false); + unwrap(Inst)->setHasNoNaNs(false); + unwrap(Inst)->setHasNoInfs(false); + unwrap(Inst)->setHasNoSignedZeros(false); + unwrap(Inst)->setHasAllowReciprocal(false); + return; + } + + if (Flags & FastMathFlags::UnsafeAlgebra) + unwrap(Inst)->setHasUnsafeAlgebra(true); + if (Flags & FastMathFlags::NoNaNs) + unwrap(Inst)->setHasNoNaNs(true); + if (Flags & FastMathFlags::NoInfs) + unwrap(Inst)->setHasNoInfs(true); + if (Flags & FastMathFlags::NoSignedZeros) + unwrap(Inst)->setHasNoSignedZeros(true); + if (Flags & FastMathFlags::AllowReciprocal) + unwrap(Inst)->setHasAllowReciprocal(true); +} + +int LLVMCountFastMathFlags(LLVMValueRef Inst){ + unsigned res = 0; + FastMathFlags fmf = + (unwrap(Inst)->getFastMathFlags()); + if(fmf.unsafeAlgebra()) res++; // Every flags are setted, we can return 5 + if(fmf.noNaNs()) res++; + if(fmf.noInfs()) res++; + if(fmf.noSignedZeros()) res++; + if(fmf.allowReciprocal()) res++; + + return res; +} + +/* returns an array of FMF.t through Dest */ +int LLVMGetFastMathFlags(LLVMValueRef Inst){ + if (LLVMHasFastMathFlag(Inst) == 0) { + return 0; + } + int Mask = 0; + FastMathFlags fmf = + (unwrap(Inst)->getFastMathFlags()); + if(fmf.unsafeAlgebra()) + Mask |= FastMathFlags::UnsafeAlgebra; + if(fmf.noNaNs()) + Mask |= FastMathFlags::NoNaNs; + if(fmf.noInfs()) + Mask |= FastMathFlags::NoInfs; + if(fmf.noSignedZeros()) + Mask |= FastMathFlags::NoSignedZeros; + if(fmf.allowReciprocal()) + Mask |= FastMathFlags::AllowReciprocal; + return Mask; +} + /*--.. Conversion functions ................................................--*/ #define LLVM_DEFINE_VALUE_CAST(name) \