Index: llvm/trunk/include/llvm/Analysis/TargetFolder.h =================================================================== --- llvm/trunk/include/llvm/Analysis/TargetFolder.h +++ llvm/trunk/include/llvm/Analysis/TargetFolder.h @@ -124,6 +124,10 @@ return Fold(ConstantExpr::getNot(C)); } + Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const { + return Fold(ConstantExpr::get(Opc, C)); + } + //===--------------------------------------------------------------------===// // Memory Instructions //===--------------------------------------------------------------------===// Index: llvm/trunk/include/llvm/IR/ConstantFolder.h =================================================================== --- llvm/trunk/include/llvm/IR/ConstantFolder.h +++ llvm/trunk/include/llvm/IR/ConstantFolder.h @@ -134,6 +134,10 @@ return ConstantExpr::getNot(C); } + Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const { + return ConstantExpr::get(Opc, C); + } + //===--------------------------------------------------------------------===// // Memory Instructions //===--------------------------------------------------------------------===// Index: llvm/trunk/include/llvm/IR/IRBuilder.h =================================================================== --- llvm/trunk/include/llvm/IR/IRBuilder.h +++ llvm/trunk/include/llvm/IR/IRBuilder.h @@ -1372,6 +1372,17 @@ 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 //===--------------------------------------------------------------------===// Index: llvm/trunk/include/llvm/IR/InstrTypes.h =================================================================== --- llvm/trunk/include/llvm/IR/InstrTypes.h +++ llvm/trunk/include/llvm/IR/InstrTypes.h @@ -77,7 +77,8 @@ // 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 @@ 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)); + } }; //===----------------------------------------------------------------------===// Index: llvm/trunk/include/llvm/IR/NoFolder.h =================================================================== --- llvm/trunk/include/llvm/IR/NoFolder.h +++ llvm/trunk/include/llvm/IR/NoFolder.h @@ -203,6 +203,10 @@ return BinaryOperator::CreateNot(C); } + Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const { + return UnaryOperator::Create(Opc, C); + } + //===--------------------------------------------------------------------===// // Memory Instructions //===--------------------------------------------------------------------===// Index: llvm/trunk/unittests/IR/IRBuilderTest.cpp =================================================================== --- llvm/trunk/unittests/IR/IRBuilderTest.cpp +++ llvm/trunk/unittests/IR/IRBuilderTest.cpp @@ -202,6 +202,18 @@ 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;