Skip to content

Commit

Permalink
[IRBuilder] Add CreateUnOp(...) to the IRBuilder to support unary FNeg
Browse files Browse the repository at this point in the history
Also update UnaryOperator to support isa, cast, and dyn_cast.

Differential Revision: https://reviews.llvm.org/D62417

llvm-svn: 361816
  • Loading branch information
mcinally committed May 28, 2019
1 parent 6bf4ca9 commit 1485781
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 1 deletion.
4 changes: 4 additions & 0 deletions llvm/include/llvm/Analysis/TargetFolder.h
Expand Up @@ -124,6 +124,10 @@ class TargetFolder {
return Fold(ConstantExpr::getNot(C));
}

Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
return Fold(ConstantExpr::get(Opc, C));
}

//===--------------------------------------------------------------------===//
// Memory Instructions
//===--------------------------------------------------------------------===//
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/ConstantFolder.h
Expand Up @@ -134,6 +134,10 @@ class ConstantFolder {
return ConstantExpr::getNot(C);
}

Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
return ConstantExpr::get(Opc, C);
}

//===--------------------------------------------------------------------===//
// Memory Instructions
//===--------------------------------------------------------------------===//
Expand Down
11 changes: 11 additions & 0 deletions llvm/include/llvm/IR/IRBuilder.h
Expand Up @@ -1372,6 +1372,17 @@ class IRBuilder : public IRBuilderBase, public Inserter {
return Insert(BinaryOperator::CreateNot(V), Name);
}

Value *CreateUnOp(Instruction::UnaryOps Opc,
Value *V, const Twine &Name = "",
MDNode *FPMathTag = nullptr) {
if (auto *VC = dyn_cast<Constant>(V))
return Insert(Folder.CreateUnOp(Opc, VC), Name);
Instruction *UnOp = UnaryOperator::Create(Opc, V);
if (isa<FPMathOperator>(UnOp))
UnOp = setFPAttrs(UnOp, FPMathTag, FMF);
return Insert(UnOp, Name);
}

//===--------------------------------------------------------------------===//
// Instruction creation methods: Memory Instructions
//===--------------------------------------------------------------------===//
Expand Down
11 changes: 10 additions & 1 deletion llvm/include/llvm/IR/InstrTypes.h
Expand Up @@ -77,7 +77,8 @@ class UnaryInstruction : public Instruction {

// 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 ||
Expand Down Expand Up @@ -156,6 +157,14 @@ class UnaryOperator : public UnaryInstruction {
UnaryOps getOpcode() const {
return static_cast<UnaryOps>(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<Instruction>(V) && classof(cast<Instruction>(V));
}
};

//===----------------------------------------------------------------------===//
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/NoFolder.h
Expand Up @@ -203,6 +203,10 @@ class NoFolder {
return BinaryOperator::CreateNot(C);
}

Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
return UnaryOperator::Create(Opc, C);
}

//===--------------------------------------------------------------------===//
// Memory Instructions
//===--------------------------------------------------------------------===//
Expand Down
12 changes: 12 additions & 0 deletions llvm/unittests/IR/IRBuilderTest.cpp
Expand Up @@ -202,6 +202,18 @@ TEST_F(IRBuilderTest, GetIntTy) {
delete DL;
}

TEST_F(IRBuilderTest, UnaryOperators) {
IRBuilder<NoFolder> Builder(BB);
Value *V = Builder.CreateLoad(GV->getValueType(), GV);

// Test CreateUnOp
Value *U = Builder.CreateUnOp(Instruction::FNeg, V);
ASSERT_TRUE(isa<Instruction>(U));
ASSERT_TRUE(isa<FPMathOperator>(U));
ASSERT_TRUE(isa<UnaryOperator>(U));
ASSERT_FALSE(isa<BinaryOperator>(U));
}

TEST_F(IRBuilderTest, FastMathFlags) {
IRBuilder<> Builder(BB);
Value *F, *FC;
Expand Down

0 comments on commit 1485781

Please sign in to comment.