1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[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

llvm-svn: 361816
This commit is contained in:
Cameron McInally 2019-05-28 13:00:52 +00:00
parent 2616db5718
commit 45a202d4bf
6 changed files with 45 additions and 1 deletions

View File

@ -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
//===--------------------------------------------------------------------===//

View File

@ -134,6 +134,10 @@ public:
return ConstantExpr::getNot(C);
}
Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
return ConstantExpr::get(Opc, C);
}
//===--------------------------------------------------------------------===//
// Memory Instructions
//===--------------------------------------------------------------------===//

View File

@ -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<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
//===--------------------------------------------------------------------===//

View File

@ -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<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));
}
};
//===----------------------------------------------------------------------===//

View File

@ -203,6 +203,10 @@ public:
return BinaryOperator::CreateNot(C);
}
Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
return UnaryOperator::Create(Opc, C);
}
//===--------------------------------------------------------------------===//
// Memory Instructions
//===--------------------------------------------------------------------===//

View File

@ -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;