mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-21 18:29:45 +00:00
Fix a logic bug when copying fast-math flags.
"Setting" does not equal "copying". This bug has sat dormant for 2 reasons: 1. The unit test was not adequate. 2. Every current user of the "copyFastMathFlags" API is operating on a new instruction. (ie, all existing fast-math flags are off). If you copy flags to an existing instruction that has some flags on already, you will not necessarily turn them off as expected. I uncovered this bug while trying to implement a fix for PR20802. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216939 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6cae39f284
commit
4211bbc568
@ -358,7 +358,7 @@ public:
|
|||||||
/// isExact - Determine whether the exact flag is set.
|
/// isExact - Determine whether the exact flag is set.
|
||||||
bool isExact() const;
|
bool isExact() const;
|
||||||
|
|
||||||
/// Convenience method to copy wrapping, exact, and fast-math flag values
|
/// Convenience method to copy supported wrapping, exact, and fast-math flags
|
||||||
/// from V to this instruction.
|
/// from V to this instruction.
|
||||||
void copyFlags(const Value *V);
|
void copyFlags(const Value *V);
|
||||||
|
|
||||||
|
@ -230,11 +230,16 @@ public:
|
|||||||
/// this flag.
|
/// this flag.
|
||||||
void setHasAllowReciprocal(bool B);
|
void setHasAllowReciprocal(bool B);
|
||||||
|
|
||||||
/// Convenience function for setting all the fast-math flags on this
|
/// Convenience function for setting multiple fast-math flags on this
|
||||||
/// instruction, which must be an operator which supports these flags. See
|
/// instruction, which must be an operator which supports these flags. See
|
||||||
/// LangRef.html for the meaning of these flags.
|
/// LangRef.html for the meaning of these flags.
|
||||||
void setFastMathFlags(FastMathFlags FMF);
|
void setFastMathFlags(FastMathFlags FMF);
|
||||||
|
|
||||||
|
/// Convenience function for transferring all fast-math flag values to this
|
||||||
|
/// instruction, which must be an operator which supports these flags. See
|
||||||
|
/// LangRef.html for the meaning of these flags.
|
||||||
|
void copyFastMathFlags(FastMathFlags FMF);
|
||||||
|
|
||||||
/// Determine whether the unsafe-algebra flag is set.
|
/// Determine whether the unsafe-algebra flag is set.
|
||||||
bool hasUnsafeAlgebra() const;
|
bool hasUnsafeAlgebra() const;
|
||||||
|
|
||||||
|
@ -257,11 +257,18 @@ private:
|
|||||||
(B * FastMathFlags::AllowReciprocal);
|
(B * FastMathFlags::AllowReciprocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function for setting all the fast-math flags
|
/// Convenience function for setting multiple fast-math flags.
|
||||||
|
/// FMF is a mask of the bits to set.
|
||||||
void setFastMathFlags(FastMathFlags FMF) {
|
void setFastMathFlags(FastMathFlags FMF) {
|
||||||
SubclassOptionalData |= FMF.Flags;
|
SubclassOptionalData |= FMF.Flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convenience function for copying all fast-math flags.
|
||||||
|
/// All values in FMF are transferred to this operator.
|
||||||
|
void copyFastMathFlags(FastMathFlags FMF) {
|
||||||
|
SubclassOptionalData = FMF.Flags;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Test whether this operation is permitted to be
|
/// Test whether this operation is permitted to be
|
||||||
/// algebraically transformed, aka the 'A' fast-math property.
|
/// algebraically transformed, aka the 'A' fast-math property.
|
||||||
|
@ -143,6 +143,11 @@ void Instruction::setFastMathFlags(FastMathFlags FMF) {
|
|||||||
cast<FPMathOperator>(this)->setFastMathFlags(FMF);
|
cast<FPMathOperator>(this)->setFastMathFlags(FMF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Instruction::copyFastMathFlags(FastMathFlags FMF) {
|
||||||
|
assert(isa<FPMathOperator>(this) && "copying fast-math flag on invalid op");
|
||||||
|
cast<FPMathOperator>(this)->copyFastMathFlags(FMF);
|
||||||
|
}
|
||||||
|
|
||||||
/// Determine whether the unsafe-algebra flag is set.
|
/// Determine whether the unsafe-algebra flag is set.
|
||||||
bool Instruction::hasUnsafeAlgebra() const {
|
bool Instruction::hasUnsafeAlgebra() const {
|
||||||
assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op");
|
assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op");
|
||||||
@ -183,7 +188,7 @@ FastMathFlags Instruction::getFastMathFlags() const {
|
|||||||
|
|
||||||
/// Copy I's fast-math flags
|
/// Copy I's fast-math flags
|
||||||
void Instruction::copyFastMathFlags(const Instruction *I) {
|
void Instruction::copyFastMathFlags(const Instruction *I) {
|
||||||
setFastMathFlags(I->getFastMathFlags());
|
copyFastMathFlags(I->getFastMathFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2043,7 +2043,7 @@ void BinaryOperator::copyFlags(const Value *V) {
|
|||||||
|
|
||||||
// Copy the fast-math flags.
|
// Copy the fast-math flags.
|
||||||
if (auto *FP = dyn_cast<FPMathOperator>(V))
|
if (auto *FP = dyn_cast<FPMathOperator>(V))
|
||||||
setFastMathFlags(FP->getFastMathFlags());
|
copyFastMathFlags(FP->getFastMathFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -189,12 +189,16 @@ TEST_F(IRBuilderTest, FastMathFlags) {
|
|||||||
|
|
||||||
Builder.clearFastMathFlags();
|
Builder.clearFastMathFlags();
|
||||||
|
|
||||||
|
// To test a copy, make sure that a '0' and a '1' change state.
|
||||||
F = Builder.CreateFDiv(F, F);
|
F = Builder.CreateFDiv(F, F);
|
||||||
ASSERT_TRUE(isa<Instruction>(F));
|
ASSERT_TRUE(isa<Instruction>(F));
|
||||||
FDiv = cast<Instruction>(F);
|
FDiv = cast<Instruction>(F);
|
||||||
EXPECT_FALSE(FDiv->getFastMathFlags().any());
|
EXPECT_FALSE(FDiv->getFastMathFlags().any());
|
||||||
|
FDiv->setHasAllowReciprocal(true);
|
||||||
|
FAdd->setHasAllowReciprocal(false);
|
||||||
FDiv->copyFastMathFlags(FAdd);
|
FDiv->copyFastMathFlags(FAdd);
|
||||||
EXPECT_TRUE(FDiv->hasNoNaNs());
|
EXPECT_TRUE(FDiv->hasNoNaNs());
|
||||||
|
EXPECT_FALSE(FDiv->hasAllowReciprocal());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user