Fast-math: IRBuilder test for creating instructions with fast-math flags
authorMichael Ilseman <milseman@apple.com>
Wed, 28 Nov 2012 21:17:34 +0000 (21:17 +0000)
committerMichael Ilseman <milseman@apple.com>
Wed, 28 Nov 2012 21:17:34 +0000 (21:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168814 91177308-0d34-0410-b5e6-96231b3b80d8

unittests/VMCore/IRBuilderTest.cpp

index 9f26936df4757ef8d091d0277698444d4bdc1e43..0f3e48d76c3dfedb595aaf020b4dd02c1ebcfb6f 100644 (file)
@@ -31,6 +31,8 @@ protected:
                                           /*isVarArg=*/false);
     F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
     BB = BasicBlock::Create(getGlobalContext(), "", F);
+    GV = new GlobalVariable(Type::getFloatTy(getGlobalContext()), true,
+                            GlobalValue::ExternalLinkage);
   }
 
   virtual void TearDown() {
@@ -41,6 +43,7 @@ protected:
   OwningPtr<Module> M;
   Function *F;
   BasicBlock *BB;
+  GlobalVariable *GV;
 };
 
 TEST_F(IRBuilderTest, Lifetime) {
@@ -108,4 +111,59 @@ TEST_F(IRBuilderTest, GetIntTy) {
   EXPECT_EQ(IntPtrTy, IntegerType::get(getGlobalContext(), IntPtrBitSize));
 }
 
+TEST_F(IRBuilderTest, FastMathFlags) {
+  IRBuilder<> Builder(BB);
+  Value *F;
+  Instruction *FDiv, *FAdd;
+
+  F = Builder.CreateLoad(GV);
+  F = Builder.CreateFAdd(F, F);
+
+  EXPECT_FALSE(Builder.GetFastMathFlags().any());
+  ASSERT_TRUE(isa<Instruction>(F));
+  FAdd = cast<Instruction>(F);
+  EXPECT_FALSE(FAdd->hasNoNaNs());
+
+  FastMathFlags FMF;
+  Builder.SetFastMathFlags(FMF);
+
+  F = Builder.CreateFAdd(F, F);
+  EXPECT_FALSE(Builder.GetFastMathFlags().any());
+
+  FMF.UnsafeAlgebra = true;
+  Builder.SetFastMathFlags(FMF);
+
+  F = Builder.CreateFAdd(F, F);
+  EXPECT_TRUE(Builder.GetFastMathFlags().any());
+  ASSERT_TRUE(isa<Instruction>(F));
+  FAdd = cast<Instruction>(F);
+  EXPECT_TRUE(FAdd->hasNoNaNs());
+
+  F = Builder.CreateFDiv(F, F);
+  EXPECT_TRUE(Builder.GetFastMathFlags().any());
+  EXPECT_TRUE(Builder.GetFastMathFlags().UnsafeAlgebra);
+  ASSERT_TRUE(isa<Instruction>(F));
+  FDiv = cast<Instruction>(F);
+  EXPECT_TRUE(FDiv->hasAllowReciprocal());
+
+  Builder.ClearFastMathFlags();
+
+  F = Builder.CreateFDiv(F, F);
+  ASSERT_TRUE(isa<Instruction>(F));
+  FDiv = cast<Instruction>(F);
+  EXPECT_FALSE(FDiv->hasAllowReciprocal());
+
+  FMF.clear();
+  FMF.AllowReciprocal = true;
+  Builder.SetFastMathFlags(FMF);
+
+  F = Builder.CreateFDiv(F, F);
+  EXPECT_TRUE(Builder.GetFastMathFlags().any());
+  EXPECT_TRUE(Builder.GetFastMathFlags().AllowReciprocal);
+  ASSERT_TRUE(isa<Instruction>(F));
+  FDiv = cast<Instruction>(F);
+  EXPECT_TRUE(FDiv->hasAllowReciprocal());
+
+}
+
 }