diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp | 83 |
1 files changed, 64 insertions, 19 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp b/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp index 835fbb3443b8..6e24f03c4cfd 100644 --- a/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp +++ b/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp @@ -746,7 +746,7 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, ConstantInt::get(Ty, i)); Constant *V2Element = ConstantExpr::getExtractElement(V2, ConstantInt::get(Ty, i)); - Constant *Cond = dyn_cast<Constant>(CondV->getOperand(i)); + auto *Cond = cast<Constant>(CondV->getOperand(i)); if (V1Element == V2Element) { V = V1Element; } else if (isa<UndefValue>(Cond)) { @@ -787,21 +787,41 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx) { - if (isa<UndefValue>(Val)) // ee(undef, x) -> undef + // extractelt undef, C -> undef + // extractelt C, undef -> undef + if (isa<UndefValue>(Val) || isa<UndefValue>(Idx)) return UndefValue::get(Val->getType()->getVectorElementType()); - if (Val->isNullValue()) // ee(zero, x) -> zero - return Constant::getNullValue(Val->getType()->getVectorElementType()); - // ee({w,x,y,z}, undef) -> undef - if (isa<UndefValue>(Idx)) + + auto *CIdx = dyn_cast<ConstantInt>(Idx); + if (!CIdx) + return nullptr; + + // ee({w,x,y,z}, wrong_value) -> undef + if (CIdx->uge(Val->getType()->getVectorNumElements())) return UndefValue::get(Val->getType()->getVectorElementType()); - if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) { - // ee({w,x,y,z}, wrong_value) -> undef - if (CIdx->uge(Val->getType()->getVectorNumElements())) - return UndefValue::get(Val->getType()->getVectorElementType()); - return Val->getAggregateElement(CIdx->getZExtValue()); + // ee (gep (ptr, idx0, ...), idx) -> gep (ee (ptr, idx), ee (idx0, idx), ...) + if (auto *CE = dyn_cast<ConstantExpr>(Val)) { + if (CE->getOpcode() == Instruction::GetElementPtr) { + SmallVector<Constant *, 8> Ops; + Ops.reserve(CE->getNumOperands()); + for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { + Constant *Op = CE->getOperand(i); + if (Op->getType()->isVectorTy()) { + Constant *ScalarOp = ConstantExpr::getExtractElement(Op, Idx); + if (!ScalarOp) + return nullptr; + Ops.push_back(ScalarOp); + } else + Ops.push_back(Op); + } + return CE->getWithOperands(Ops, CE->getType()->getVectorElementType(), + false, + Ops[0]->getType()->getPointerElementType()); + } } - return nullptr; + + return Val->getAggregateElement(CIdx); } Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, @@ -813,6 +833,12 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx); if (!CIdx) return nullptr; + // Do not iterate on scalable vector. The num of elements is unknown at + // compile-time. + VectorType *ValTy = cast<VectorType>(Val->getType()); + if (ValTy->isScalable()) + return nullptr; + unsigned NumElts = Val->getType()->getVectorNumElements(); if (CIdx->uge(NumElts)) return UndefValue::get(Val->getType()); @@ -847,6 +873,12 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, // Don't break the bitcode reader hack. if (isa<ConstantExpr>(Mask)) return nullptr; + // Do not iterate on scalable vector. The num of elements is unknown at + // compile-time. + VectorType *ValTy = cast<VectorType>(V1->getType()); + if (ValTy->isScalable()) + return nullptr; + unsigned SrcNumElts = V1->getType()->getVectorNumElements(); // Loop over the shuffle mask, evaluating each element. @@ -968,6 +1000,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, Constant *C2) { assert(Instruction::isBinaryOp(Opcode) && "Non-binary instruction detected"); + // Simplify BinOps with their identity values first. They are no-ops and we + // can always return the other value, including undef or poison values. + // FIXME: remove unnecessary duplicated identity patterns below. + // FIXME: Use AllowRHSConstant with getBinOpIdentity to handle additional ops, + // like X << 0 = X. + Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, C1->getType()); + if (Identity) { + if (C1 == Identity) + return C2; + if (C2 == Identity) + return C1; + } + // Handle scalar UndefValue. Vectors are always evaluated per element. bool HasScalarUndef = !C1->getType()->isVectorTy() && (isa<UndefValue>(C1) || isa<UndefValue>(C2)); @@ -1125,7 +1170,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, isa<GlobalValue>(CE1->getOperand(0))) { GlobalValue *GV = cast<GlobalValue>(CE1->getOperand(0)); - unsigned GVAlign; + MaybeAlign GVAlign; if (Module *TheModule = GV->getParent()) { GVAlign = GV->getPointerAlignment(TheModule->getDataLayout()); @@ -1139,19 +1184,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, // increased code size (see https://reviews.llvm.org/D55115) // FIXME: This code should be deleted once existing targets have // appropriate defaults - if (GVAlign == 0U && isa<Function>(GV)) - GVAlign = 4U; + if (!GVAlign && isa<Function>(GV)) + GVAlign = Align(4); } else if (isa<Function>(GV)) { // Without a datalayout we have to assume the worst case: that the // function pointer isn't aligned at all. - GVAlign = 0U; + GVAlign = llvm::None; } else { - GVAlign = GV->getAlignment(); + GVAlign = MaybeAlign(GV->getAlignment()); } - if (GVAlign > 1) { + if (GVAlign && *GVAlign > 1) { unsigned DstWidth = CI2->getType()->getBitWidth(); - unsigned SrcWidth = std::min(DstWidth, Log2_32(GVAlign)); + unsigned SrcWidth = std::min(DstWidth, Log2(*GVAlign)); APInt BitsNotSet(APInt::getLowBitsSet(DstWidth, SrcWidth)); // If checking bits we know are clear, return zero. |
