llvm.org GIT mirror llvm / 4211bbc
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 Sanjay Patel 5 years ago
6 changed file(s) with 26 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
357357 /// isExact - Determine whether the exact flag is set.
358358 bool isExact() const;
359359
360 /// Convenience method to copy wrapping, exact, and fast-math flag values
360 /// Convenience method to copy supported wrapping, exact, and fast-math flags
361361 /// from V to this instruction.
362362 void copyFlags(const Value *V);
363363
229229 /// this flag.
230230 void setHasAllowReciprocal(bool B);
231231
232 /// Convenience function for setting all the fast-math flags on this
232 /// Convenience function for setting multiple fast-math flags on this
233233 /// instruction, which must be an operator which supports these flags. See
234234 /// LangRef.html for the meaning of these flags.
235235 void setFastMathFlags(FastMathFlags FMF);
236
237 /// Convenience function for transferring all fast-math flag values to this
238 /// instruction, which must be an operator which supports these flags. See
239 /// LangRef.html for the meaning of these flags.
240 void copyFastMathFlags(FastMathFlags FMF);
236241
237242 /// Determine whether the unsafe-algebra flag is set.
238243 bool hasUnsafeAlgebra() const;
256256 (B * FastMathFlags::AllowReciprocal);
257257 }
258258
259 /// Convenience function for setting all the fast-math flags
259 /// Convenience function for setting multiple fast-math flags.
260 /// FMF is a mask of the bits to set.
260261 void setFastMathFlags(FastMathFlags FMF) {
261262 SubclassOptionalData |= FMF.Flags;
263 }
264
265 /// Convenience function for copying all fast-math flags.
266 /// All values in FMF are transferred to this operator.
267 void copyFastMathFlags(FastMathFlags FMF) {
268 SubclassOptionalData = FMF.Flags;
262269 }
263270
264271 public:
142142 cast(this)->setFastMathFlags(FMF);
143143 }
144144
145 void Instruction::copyFastMathFlags(FastMathFlags FMF) {
146 assert(isa(this) && "copying fast-math flag on invalid op");
147 cast(this)->copyFastMathFlags(FMF);
148 }
149
145150 /// Determine whether the unsafe-algebra flag is set.
146151 bool Instruction::hasUnsafeAlgebra() const {
147152 assert(isa(this) && "getting fast-math flag on invalid op");
182187
183188 /// Copy I's fast-math flags
184189 void Instruction::copyFastMathFlags(const Instruction *I) {
185 setFastMathFlags(I->getFastMathFlags());
190 copyFastMathFlags(I->getFastMathFlags());
186191 }
187192
188193
20422042
20432043 // Copy the fast-math flags.
20442044 if (auto *FP = dyn_cast(V))
2045 setFastMathFlags(FP->getFastMathFlags());
2045 copyFastMathFlags(FP->getFastMathFlags());
20462046 }
20472047
20482048 //===----------------------------------------------------------------------===//
188188
189189 Builder.clearFastMathFlags();
190190
191 // To test a copy, make sure that a '0' and a '1' change state.
191192 F = Builder.CreateFDiv(F, F);
192193 ASSERT_TRUE(isa(F));
193194 FDiv = cast(F);
194195 EXPECT_FALSE(FDiv->getFastMathFlags().any());
196 FDiv->setHasAllowReciprocal(true);
197 FAdd->setHasAllowReciprocal(false);
195198 FDiv->copyFastMathFlags(FAdd);
196199 EXPECT_TRUE(FDiv->hasNoNaNs());
200 EXPECT_FALSE(FDiv->hasAllowReciprocal());
197201
198202 }
199203