From: Cameron McInally Date: Tue, 28 May 2019 13:00:52 +0000 (+0000) Subject: [IRBuilder] Add CreateUnOp(...) to the IRBuilder to support unary FNeg X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d492be25abee192d029cf5584f111d6034fdd1a2;p=llvm [IRBuilder] Add CreateUnOp(...) to the IRBuilder to support unary FNeg Also update UnaryOperator to support isa, cast, and dyn_cast. Differential Revision: https://reviews.llvm.org/D62417 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361816 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h index b8047a46b93..7ab6562be44 100644 --- a/include/llvm/Analysis/TargetFolder.h +++ b/include/llvm/Analysis/TargetFolder.h @@ -124,6 +124,10 @@ public: return Fold(ConstantExpr::getNot(C)); } + Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const { + return Fold(ConstantExpr::get(Opc, C)); + } + //===--------------------------------------------------------------------===// // Memory Instructions //===--------------------------------------------------------------------===// diff --git a/include/llvm/IR/ConstantFolder.h b/include/llvm/IR/ConstantFolder.h index 1971cb854e3..5a5cabfd020 100644 --- a/include/llvm/IR/ConstantFolder.h +++ b/include/llvm/IR/ConstantFolder.h @@ -134,6 +134,10 @@ public: return ConstantExpr::getNot(C); } + Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const { + return ConstantExpr::get(Opc, C); + } + //===--------------------------------------------------------------------===// // Memory Instructions //===--------------------------------------------------------------------===// diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index c2090a2186a..d052666354f 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -1372,6 +1372,17 @@ public: return Insert(BinaryOperator::CreateNot(V), Name); } + Value *CreateUnOp(Instruction::UnaryOps Opc, + Value *V, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + if (auto *VC = dyn_cast(V)) + return Insert(Folder.CreateUnOp(Opc, VC), Name); + Instruction *UnOp = UnaryOperator::Create(Opc, V); + if (isa(UnOp)) + UnOp = setFPAttrs(UnOp, FPMathTag, FMF); + return Insert(UnOp, Name); + } + //===--------------------------------------------------------------------===// // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index a595707f3a6..7ffa7a6f60e 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -77,7 +77,8 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::Alloca || + return I->isUnaryOp() || + I->getOpcode() == Instruction::Alloca || I->getOpcode() == Instruction::Load || I->getOpcode() == Instruction::VAArg || I->getOpcode() == Instruction::ExtractValue || @@ -156,6 +157,14 @@ public: UnaryOps getOpcode() const { return static_cast(Instruction::getOpcode()); } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const Instruction *I) { + return I->isUnaryOp(); + } + static bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } }; //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h index 7fd303933c2..0e3c19f4947 100644 --- a/include/llvm/IR/NoFolder.h +++ b/include/llvm/IR/NoFolder.h @@ -203,6 +203,10 @@ public: return BinaryOperator::CreateNot(C); } + Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const { + return UnaryOperator::Create(Opc, C); + } + //===--------------------------------------------------------------------===// // Memory Instructions //===--------------------------------------------------------------------===// diff --git a/unittests/IR/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp index 80744061e0c..51397ec745f 100644 --- a/unittests/IR/IRBuilderTest.cpp +++ b/unittests/IR/IRBuilderTest.cpp @@ -202,6 +202,18 @@ TEST_F(IRBuilderTest, GetIntTy) { delete DL; } +TEST_F(IRBuilderTest, UnaryOperators) { + IRBuilder Builder(BB); + Value *V = Builder.CreateLoad(GV->getValueType(), GV); + + // Test CreateUnOp + Value *U = Builder.CreateUnOp(Instruction::FNeg, V); + ASSERT_TRUE(isa(U)); + ASSERT_TRUE(isa(U)); + ASSERT_TRUE(isa(U)); + ASSERT_FALSE(isa(U)); +} + TEST_F(IRBuilderTest, FastMathFlags) { IRBuilder<> Builder(BB); Value *F, *FC;