summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorCameron McInally <cameron.mcinally@nyu.edu>2019-05-05 16:07:09 +0000
committerCameron McInally <cameron.mcinally@nyu.edu>2019-05-05 16:07:09 +0000
commit1d0c845d9dce577c2ef14cd7d5fcf0b9c17f9ed2 (patch)
treebc2a42daa117355c7d3a43a82ce69c34ea357883 /llvm/lib/IR/ConstantFold.cpp
parent70ee2def906e928624f59611c3de732fe121b8a4 (diff)
downloadbcm5719-llvm-1d0c845d9dce577c2ef14cd7d5fcf0b9c17f9ed2.tar.gz
bcm5719-llvm-1d0c845d9dce577c2ef14cd7d5fcf0b9c17f9ed2.zip
Add FNeg IR constant folding support
llvm-svn: 359982
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 1dfd5284a97..835fbb3443b 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -918,6 +918,52 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
return ConstantVector::get(Result);
}
+Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) {
+ assert(Instruction::isUnaryOp(Opcode) && "Non-unary instruction detected");
+
+ // Handle scalar UndefValue. Vectors are always evaluated per element.
+ bool HasScalarUndef = !C->getType()->isVectorTy() && isa<UndefValue>(C);
+
+ if (HasScalarUndef) {
+ switch (static_cast<Instruction::UnaryOps>(Opcode)) {
+ case Instruction::FNeg:
+ return C; // -undef -> undef
+ case Instruction::UnaryOpsEnd:
+ llvm_unreachable("Invalid UnaryOp");
+ }
+ }
+
+ // Constant should not be UndefValue, unless these are vector constants.
+ assert(!HasScalarUndef && "Unexpected UndefValue");
+ // We only have FP UnaryOps right now.
+ assert(!isa<ConstantInt>(C) && "Unexpected Integer UnaryOp");
+
+ if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+ const APFloat &CV = CFP->getValueAPF();
+ switch (Opcode) {
+ default:
+ break;
+ case Instruction::FNeg:
+ return ConstantFP::get(C->getContext(), neg(CV));
+ }
+ } else if (VectorType *VTy = dyn_cast<VectorType>(C->getType())) {
+ // Fold each element and create a vector constant from those constants.
+ SmallVector<Constant*, 16> Result;
+ Type *Ty = IntegerType::get(VTy->getContext(), 32);
+ for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
+ Constant *ExtractIdx = ConstantInt::get(Ty, i);
+ Constant *Elt = ConstantExpr::getExtractElement(C, ExtractIdx);
+
+ Result.push_back(ConstantExpr::get(Opcode, Elt));
+ }
+
+ return ConstantVector::get(Result);
+ }
+
+ // We don't know how to fold this.
+ return nullptr;
+}
+
Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
Constant *C2) {
assert(Instruction::isBinaryOp(Opcode) && "Non-binary instruction detected");
OpenPOWER on IntegriCloud