#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/GlobalVariable.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include <cstring>
using namespace llvm;
static unsigned getOpcode(const Value *V) {
if (const Instruction *I = dyn_cast<Instruction>(V))
return I->getOpcode();
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
return CE->getOpcode();
return Instruction::UserOp1;
}
void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
APInt &KnownZero, APInt &KnownOne,
TargetData *TD, unsigned Depth) {
assert(V && "No Value?");
assert(Depth <= 6 && "Limit Search Depth");
unsigned BitWidth = Mask.getBitWidth();
assert((V->getType()->isInteger() || isa<PointerType>(V->getType())) &&
"Not integer or pointer type!");
assert((!TD || TD->getTypeSizeInBits(V->getType()) == BitWidth) &&
(!isa<IntegerType>(V->getType()) ||
V->getType()->getPrimitiveSizeInBits() == BitWidth) &&
KnownZero.getBitWidth() == BitWidth &&
KnownOne.getBitWidth() == BitWidth &&
"V, Mask, KnownOne and KnownZero should have same BitWidth");
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
KnownOne = CI->getValue() & Mask;
KnownZero = ~KnownOne & Mask;
return;
}
if (isa<ConstantPointerNull>(V)) {
KnownOne.clear();
KnownZero = Mask;
return;
}
if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
unsigned Align = GV->getAlignment();
if (Align == 0 && TD && GV->getType()->getElementType()->isSized())
Align = TD->getPrefTypeAlignment(GV->getType()->getElementType());
if (Align > 0)
KnownZero = Mask & APInt::getLowBitsSet(BitWidth,
CountTrailingZeros_32(Align));
else
KnownZero.clear();
KnownOne.clear();
return;
}
KnownZero.clear(); KnownOne.clear();
if (Depth == 6 || Mask == 0)
return;
User *I = dyn_cast<User>(V);
if (!I) return;
APInt KnownZero2(KnownZero), KnownOne2(KnownOne);
switch (getOpcode(I)) {
default: break;
case Instruction::And: {
ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, TD, Depth+1);
APInt Mask2(Mask & ~KnownZero);
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero2, KnownOne2, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
KnownOne &= KnownOne2;
KnownZero |= KnownZero2;
return;
}
case Instruction::Or: {
ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, TD, Depth+1);
APInt Mask2(Mask & ~KnownOne);
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero2, KnownOne2, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
KnownZero &= KnownZero2;
KnownOne |= KnownOne2;
return;
}
case Instruction::Xor: {
ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, TD, Depth+1);
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero2, KnownOne2, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
APInt KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);
KnownOne = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);
KnownZero = KnownZeroOut;
return;
}
case Instruction::Mul: {
APInt Mask2 = APInt::getAllOnesValue(BitWidth);
ComputeMaskedBits(I->getOperand(1), Mask2, KnownZero, KnownOne, TD,Depth+1);
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero2, KnownOne2, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
KnownOne.clear();
unsigned TrailZ = KnownZero.countTrailingOnes() +
KnownZero2.countTrailingOnes();
unsigned LeadZ = std::max(KnownZero.countLeadingOnes() +
KnownZero2.countLeadingOnes(),
BitWidth) - BitWidth;
TrailZ = std::min(TrailZ, BitWidth);
LeadZ = std::min(LeadZ, BitWidth);
KnownZero = APInt::getLowBitsSet(BitWidth, TrailZ) |
APInt::getHighBitsSet(BitWidth, LeadZ);
KnownZero &= Mask;
return;
}
case Instruction::UDiv: {
APInt AllOnes = APInt::getAllOnesValue(BitWidth);
ComputeMaskedBits(I->getOperand(0),
AllOnes, KnownZero2, KnownOne2, TD, Depth+1);
unsigned LeadZ = KnownZero2.countLeadingOnes();
KnownOne2.clear();
KnownZero2.clear();
ComputeMaskedBits(I->getOperand(1),
AllOnes, KnownZero2, KnownOne2, TD, Depth+1);
unsigned RHSUnknownLeadingOnes = KnownOne2.countLeadingZeros();
if (RHSUnknownLeadingOnes != BitWidth)
LeadZ = std::min(BitWidth,
LeadZ + BitWidth - RHSUnknownLeadingOnes - 1);
KnownZero = APInt::getHighBitsSet(BitWidth, LeadZ) & Mask;
return;
}
case Instruction::Select:
ComputeMaskedBits(I->getOperand(2), Mask, KnownZero, KnownOne, TD, Depth+1);
ComputeMaskedBits(I->getOperand(1), Mask, KnownZero2, KnownOne2, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
KnownOne &= KnownOne2;
KnownZero &= KnownZero2;
return;
case Instruction::FPTrunc:
case Instruction::FPExt:
case Instruction::FPToUI:
case Instruction::FPToSI:
case Instruction::SIToFP:
case Instruction::UIToFP:
return; case Instruction::PtrToInt:
case Instruction::IntToPtr:
if (!TD) return;
case Instruction::ZExt:
case Instruction::Trunc: {
const Type *SrcTy = I->getOperand(0)->getType();
unsigned SrcBitWidth = TD ?
TD->getTypeSizeInBits(SrcTy) :
SrcTy->getPrimitiveSizeInBits();
APInt MaskIn(Mask);
MaskIn.zextOrTrunc(SrcBitWidth);
KnownZero.zextOrTrunc(SrcBitWidth);
KnownOne.zextOrTrunc(SrcBitWidth);
ComputeMaskedBits(I->getOperand(0), MaskIn, KnownZero, KnownOne, TD,
Depth+1);
KnownZero.zextOrTrunc(BitWidth);
KnownOne.zextOrTrunc(BitWidth);
if (BitWidth > SrcBitWidth)
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
return;
}
case Instruction::BitCast: {
const Type *SrcTy = I->getOperand(0)->getType();
if (SrcTy->isInteger() || isa<PointerType>(SrcTy)) {
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, TD,
Depth+1);
return;
}
break;
}
case Instruction::SExt: {
const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
unsigned SrcBitWidth = SrcTy->getBitWidth();
APInt MaskIn(Mask);
MaskIn.trunc(SrcBitWidth);
KnownZero.trunc(SrcBitWidth);
KnownOne.trunc(SrcBitWidth);
ComputeMaskedBits(I->getOperand(0), MaskIn, KnownZero, KnownOne, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero.zext(BitWidth);
KnownOne.zext(BitWidth);
if (KnownZero[SrcBitWidth-1]) KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
else if (KnownOne[SrcBitWidth-1]) KnownOne |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
return;
}
case Instruction::Shl:
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
uint64_t ShiftAmt = SA->getLimitedValue(BitWidth);
APInt Mask2(Mask.lshr(ShiftAmt));
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero, KnownOne, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero <<= ShiftAmt;
KnownOne <<= ShiftAmt;
KnownZero |= APInt::getLowBitsSet(BitWidth, ShiftAmt); return;
}
break;
case Instruction::LShr:
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
uint64_t ShiftAmt = SA->getLimitedValue(BitWidth);
APInt Mask2(Mask.shl(ShiftAmt));
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero,KnownOne, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
KnownZero = APIntOps::lshr(KnownZero, ShiftAmt);
KnownOne = APIntOps::lshr(KnownOne, ShiftAmt);
KnownZero |= APInt::getHighBitsSet(BitWidth, ShiftAmt);
return;
}
break;
case Instruction::AShr:
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
uint64_t ShiftAmt = SA->getLimitedValue(BitWidth);
APInt Mask2(Mask.shl(ShiftAmt));
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero, KnownOne, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
KnownZero = APIntOps::lshr(KnownZero, ShiftAmt);
KnownOne = APIntOps::lshr(KnownOne, ShiftAmt);
APInt HighBits(APInt::getHighBitsSet(BitWidth, ShiftAmt));
if (KnownZero[BitWidth-ShiftAmt-1]) KnownZero |= HighBits;
else if (KnownOne[BitWidth-ShiftAmt-1]) KnownOne |= HighBits;
return;
}
break;
case Instruction::Sub: {
if (ConstantInt *CLHS = dyn_cast<ConstantInt>(I->getOperand(0))) {
if (!CLHS->getValue().isNegative()) {
unsigned NLZ = (CLHS->getValue()+1).countLeadingZeros();
APInt MaskV = APInt::getHighBitsSet(BitWidth, NLZ+1);
ComputeMaskedBits(I->getOperand(1), MaskV, KnownZero2, KnownOne2,
TD, Depth+1);
if ((KnownZero2 & MaskV) == MaskV) {
unsigned NLZ2 = CLHS->getValue().countLeadingZeros();
KnownZero = APInt::getHighBitsSet(BitWidth, NLZ2) & Mask;
}
}
}
}
case Instruction::Add: {
APInt Mask2 = APInt::getLowBitsSet(BitWidth, Mask.countTrailingOnes());
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero2, KnownOne2, TD,
Depth+1);
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
unsigned KnownZeroOut = KnownZero2.countTrailingOnes();
ComputeMaskedBits(I->getOperand(1), Mask2, KnownZero2, KnownOne2, TD,
Depth+1);
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
KnownZeroOut = std::min(KnownZeroOut,
KnownZero2.countTrailingOnes());
KnownZero |= APInt::getLowBitsSet(BitWidth, KnownZeroOut);
return;
}
case Instruction::SRem:
if (ConstantInt *Rem = dyn_cast<ConstantInt>(I->getOperand(1))) {
APInt RA = Rem->getValue();
if (RA.isPowerOf2() || (-RA).isPowerOf2()) {
APInt LowBits = RA.isStrictlyPositive() ? (RA - 1) : ~RA;
APInt Mask2 = LowBits | APInt::getSignBit(BitWidth);
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero2, KnownOne2, TD,
Depth+1);
if (KnownZero2[BitWidth-1] || ((KnownZero2 & LowBits) == LowBits))
KnownZero2 |= ~LowBits;
KnownZero |= KnownZero2 & Mask;
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
}
}
break;
case Instruction::URem: {
if (ConstantInt *Rem = dyn_cast<ConstantInt>(I->getOperand(1))) {
APInt RA = Rem->getValue();
if (RA.isPowerOf2()) {
APInt LowBits = (RA - 1);
APInt Mask2 = LowBits & Mask;
KnownZero |= ~LowBits & Mask;
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero, KnownOne, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
break;
}
}
APInt AllOnes = APInt::getAllOnesValue(BitWidth);
ComputeMaskedBits(I->getOperand(0), AllOnes, KnownZero, KnownOne,
TD, Depth+1);
ComputeMaskedBits(I->getOperand(1), AllOnes, KnownZero2, KnownOne2,
TD, Depth+1);
unsigned Leaders = std::max(KnownZero.countLeadingOnes(),
KnownZero2.countLeadingOnes());
KnownOne.clear();
KnownZero = APInt::getHighBitsSet(BitWidth, Leaders) & Mask;
break;
}
case Instruction::Alloca:
case Instruction::Malloc: {
AllocationInst *AI = cast<AllocationInst>(V);
unsigned Align = AI->getAlignment();
if (Align == 0 && TD) {
if (isa<AllocaInst>(AI))
Align = TD->getABITypeAlignment(AI->getType()->getElementType());
else if (isa<MallocInst>(AI)) {
Align = TD->getABITypeAlignment(AI->getType()->getElementType());
Align =
std::max(Align,
(unsigned)TD->getABITypeAlignment(Type::DoubleTy));
Align =
std::max(Align,
(unsigned)TD->getABITypeAlignment(Type::Int64Ty));
}
}
if (Align > 0)
KnownZero = Mask & APInt::getLowBitsSet(BitWidth,
CountTrailingZeros_32(Align));
break;
}
case Instruction::GetElementPtr: {
APInt LocalMask = APInt::getAllOnesValue(BitWidth);
APInt LocalKnownZero(BitWidth, 0), LocalKnownOne(BitWidth, 0);
ComputeMaskedBits(I->getOperand(0), LocalMask,
LocalKnownZero, LocalKnownOne, TD, Depth+1);
unsigned TrailZ = LocalKnownZero.countTrailingOnes();
gep_type_iterator GTI = gep_type_begin(I);
for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i, ++GTI) {
Value *Index = I->getOperand(i);
if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
if (!TD) return;
const StructLayout *SL = TD->getStructLayout(STy);
unsigned Idx = cast<ConstantInt>(Index)->getZExtValue();
uint64_t Offset = SL->getElementOffset(Idx);
TrailZ = std::min(TrailZ,
CountTrailingZeros_64(Offset));
} else {
const Type *IndexedTy = GTI.getIndexedType();
if (!IndexedTy->isSized()) return;
unsigned GEPOpiBits = Index->getType()->getPrimitiveSizeInBits();
uint64_t TypeSize = TD ? TD->getTypePaddedSize(IndexedTy) : 1;
LocalMask = APInt::getAllOnesValue(GEPOpiBits);
LocalKnownZero = LocalKnownOne = APInt(GEPOpiBits, 0);
ComputeMaskedBits(Index, LocalMask,
LocalKnownZero, LocalKnownOne, TD, Depth+1);
TrailZ = std::min(TrailZ,
unsigned(CountTrailingZeros_64(TypeSize) +
LocalKnownZero.countTrailingOnes()));
}
}
KnownZero = APInt::getLowBitsSet(BitWidth, TrailZ) & Mask;
break;
}
case Instruction::PHI: {
PHINode *P = cast<PHINode>(I);
if (P->getNumIncomingValues() == 2) {
for (unsigned i = 0; i != 2; ++i) {
Value *L = P->getIncomingValue(i);
Value *R = P->getIncomingValue(!i);
User *LU = dyn_cast<User>(L);
if (!LU)
continue;
unsigned Opcode = getOpcode(LU);
if (Opcode == Instruction::Add ||
Opcode == Instruction::Sub ||
Opcode == Instruction::And ||
Opcode == Instruction::Or ||
Opcode == Instruction::Mul) {
Value *LL = LU->getOperand(0);
Value *LR = LU->getOperand(1);
if (LL == I)
L = LR;
else if (LR == I)
L = LL;
else
break;
APInt Mask2 = APInt::getAllOnesValue(BitWidth);
ComputeMaskedBits(R, Mask2, KnownZero2, KnownOne2, TD, Depth+1);
Mask2 = APInt::getLowBitsSet(BitWidth,
KnownZero2.countTrailingOnes());
APInt KnownZero3(KnownZero), KnownOne3(KnownOne);
ComputeMaskedBits(L, Mask2, KnownZero3, KnownOne3, TD, Depth+1);
KnownZero = Mask &
APInt::getLowBitsSet(BitWidth,
std::min(KnownZero2.countTrailingOnes(),
KnownZero3.countTrailingOnes()));
break;
}
}
}
break;
}
case Instruction::Call:
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
switch (II->getIntrinsicID()) {
default: break;
case Intrinsic::ctpop:
case Intrinsic::ctlz:
case Intrinsic::cttz: {
unsigned LowBits = Log2_32(BitWidth)+1;
KnownZero = APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
break;
}
}
}
break;
}
}
bool llvm::MaskedValueIsZero(Value *V, const APInt &Mask,
TargetData *TD, unsigned Depth) {
APInt KnownZero(Mask.getBitWidth(), 0), KnownOne(Mask.getBitWidth(), 0);
ComputeMaskedBits(V, Mask, KnownZero, KnownOne, TD, Depth);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
return (KnownZero & Mask) == Mask;
}
unsigned llvm::ComputeNumSignBits(Value *V, TargetData *TD, unsigned Depth) {
const IntegerType *Ty = cast<IntegerType>(V->getType());
unsigned TyBits = Ty->getBitWidth();
unsigned Tmp, Tmp2;
unsigned FirstAnswer = 1;
if (Depth == 6)
return 1;
User *U = dyn_cast<User>(V);
switch (getOpcode(V)) {
default: break;
case Instruction::SExt:
Tmp = TyBits-cast<IntegerType>(U->getOperand(0)->getType())->getBitWidth();
return ComputeNumSignBits(U->getOperand(0), TD, Depth+1) + Tmp;
case Instruction::AShr:
Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1);
if (ConstantInt *C = dyn_cast<ConstantInt>(U->getOperand(1))) {
Tmp += C->getZExtValue();
if (Tmp > TyBits) Tmp = TyBits;
}
return Tmp;
case Instruction::Shl:
if (ConstantInt *C = dyn_cast<ConstantInt>(U->getOperand(1))) {
Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1);
if (C->getZExtValue() >= TyBits || C->getZExtValue() >= Tmp) break; return Tmp - C->getZExtValue();
}
break;
case Instruction::And:
case Instruction::Or:
case Instruction::Xor: Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1);
if (Tmp != 1) {
Tmp2 = ComputeNumSignBits(U->getOperand(1), TD, Depth+1);
FirstAnswer = std::min(Tmp, Tmp2);
}
break;
case Instruction::Select:
Tmp = ComputeNumSignBits(U->getOperand(1), TD, Depth+1);
if (Tmp == 1) return 1; Tmp2 = ComputeNumSignBits(U->getOperand(2), TD, Depth+1);
return std::min(Tmp, Tmp2);
case Instruction::Add:
Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1);
if (Tmp == 1) return 1;
if (ConstantInt *CRHS = dyn_cast<ConstantInt>(U->getOperand(1)))
if (CRHS->isAllOnesValue()) {
APInt KnownZero(TyBits, 0), KnownOne(TyBits, 0);
APInt Mask = APInt::getAllOnesValue(TyBits);
ComputeMaskedBits(U->getOperand(0), Mask, KnownZero, KnownOne, TD,
Depth+1);
if ((KnownZero | APInt(TyBits, 1)) == Mask)
return TyBits;
if (KnownZero.isNegative())
return Tmp;
}
Tmp2 = ComputeNumSignBits(U->getOperand(1), TD, Depth+1);
if (Tmp2 == 1) return 1;
return std::min(Tmp, Tmp2)-1;
break;
case Instruction::Sub:
Tmp2 = ComputeNumSignBits(U->getOperand(1), TD, Depth+1);
if (Tmp2 == 1) return 1;
if (ConstantInt *CLHS = dyn_cast<ConstantInt>(U->getOperand(0)))
if (CLHS->isNullValue()) {
APInt KnownZero(TyBits, 0), KnownOne(TyBits, 0);
APInt Mask = APInt::getAllOnesValue(TyBits);
ComputeMaskedBits(U->getOperand(1), Mask, KnownZero, KnownOne,
TD, Depth+1);
if ((KnownZero | APInt(TyBits, 1)) == Mask)
return TyBits;
if (KnownZero.isNegative())
return Tmp2;
}
Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1);
if (Tmp == 1) return 1; return std::min(Tmp, Tmp2)-1;
break;
case Instruction::Trunc:
break;
}
APInt KnownZero(TyBits, 0), KnownOne(TyBits, 0);
APInt Mask = APInt::getAllOnesValue(TyBits);
ComputeMaskedBits(V, Mask, KnownZero, KnownOne, TD, Depth);
if (KnownZero.isNegative()) { Mask = KnownZero;
} else if (KnownOne.isNegative()) { Mask = KnownOne;
} else {
return FirstAnswer;
}
Mask = ~Mask;
Mask <<= Mask.getBitWidth()-TyBits;
return std::max(FirstAnswer, std::min(TyBits, Mask.countLeadingZeros()));
}
bool llvm::CannotBeNegativeZero(const Value *V, unsigned Depth) {
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V))
return !CFP->getValueAPF().isNegZero();
if (Depth == 6)
return 1;
const Instruction *I = dyn_cast<Instruction>(V);
if (I == 0) return false;
if (I->getOpcode() == Instruction::Add &&
isa<ConstantFP>(I->getOperand(1)) &&
cast<ConstantFP>(I->getOperand(1))->isNullValue())
return true;
if (isa<SIToFPInst>(I) || isa<UIToFPInst>(I))
return true;
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
if (II->getIntrinsicID() == Intrinsic::sqrt)
return CannotBeNegativeZero(II->getOperand(1), Depth+1);
if (const CallInst *CI = dyn_cast<CallInst>(I))
if (const Function *F = CI->getCalledFunction()) {
if (F->isDeclaration()) {
switch (F->getNameLen()) {
case 3: if (!strcmp(F->getNameStart(), "abs")) return true;
break;
case 4: if (!strcmp(F->getNameStart(), "absf")) return true;
if (!strcmp(F->getNameStart(), "absl")) return true;
break;
}
}
}
return false;
}
Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
SmallVector<unsigned, 10> &Idxs,
unsigned IdxSkip,
Instruction *InsertBefore) {
const llvm::StructType *STy = llvm::dyn_cast<llvm::StructType>(IndexedType);
if (STy) {
Value *OrigTo = To;
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
Idxs.push_back(i);
Value *PrevTo = To;
To = BuildSubAggregate(From, To, STy->getElementType(i), Idxs, IdxSkip,
InsertBefore);
Idxs.pop_back();
if (!To) {
while (PrevTo != OrigTo) {
InsertValueInst* Del = cast<InsertValueInst>(PrevTo);
PrevTo = Del->getAggregateOperand();
Del->eraseFromParent();
}
break;
}
}
if (To)
return To;
}
Value *V = FindInsertedValue(From, Idxs.begin(), Idxs.end());
if (!V)
return NULL;
return llvm::InsertValueInst::Create(To, V, Idxs.begin() + IdxSkip,
Idxs.end(), "tmp", InsertBefore);
}
Value *BuildSubAggregate(Value *From, const unsigned *idx_begin,
const unsigned *idx_end, Instruction *InsertBefore) {
assert(InsertBefore && "Must have someplace to insert!");
const Type *IndexedType = ExtractValueInst::getIndexedType(From->getType(),
idx_begin,
idx_end);
Value *To = UndefValue::get(IndexedType);
SmallVector<unsigned, 10> Idxs(idx_begin, idx_end);
unsigned IdxSkip = Idxs.size();
return BuildSubAggregate(From, To, IndexedType, Idxs, IdxSkip, InsertBefore);
}
Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
const unsigned *idx_end, Instruction *InsertBefore) {
if (idx_begin == idx_end)
return V;
assert((isa<StructType>(V->getType()) || isa<ArrayType>(V->getType()))
&& "Not looking at a struct or array?");
assert(ExtractValueInst::getIndexedType(V->getType(), idx_begin, idx_end)
&& "Invalid indices for type?");
const CompositeType *PTy = cast<CompositeType>(V->getType());
if (isa<UndefValue>(V))
return UndefValue::get(ExtractValueInst::getIndexedType(PTy,
idx_begin,
idx_end));
else if (isa<ConstantAggregateZero>(V))
return Constant::getNullValue(ExtractValueInst::getIndexedType(PTy,
idx_begin,
idx_end));
else if (Constant *C = dyn_cast<Constant>(V)) {
if (isa<ConstantArray>(C) || isa<ConstantStruct>(C))
return FindInsertedValue(C->getOperand(*idx_begin), idx_begin + 1, idx_end,
InsertBefore);
} else if (InsertValueInst *I = dyn_cast<InsertValueInst>(V)) {
const unsigned *req_idx = idx_begin;
for (const unsigned *i = I->idx_begin(), *e = I->idx_end();
i != e; ++i, ++req_idx) {
if (req_idx == idx_end) {
if (InsertBefore)
return BuildSubAggregate(V, idx_begin, req_idx, InsertBefore);
else
return 0;
}
if (*req_idx != *i)
return FindInsertedValue(I->getAggregateOperand(), idx_begin, idx_end,
InsertBefore);
}
return FindInsertedValue(I->getInsertedValueOperand(), req_idx, idx_end,
InsertBefore);
} else if (ExtractValueInst *I = dyn_cast<ExtractValueInst>(V)) {
unsigned size = I->getNumIndices() + (idx_end - idx_begin);
SmallVector<unsigned, 5> Idxs;
Idxs.reserve(size);
for (const unsigned *i = I->idx_begin(), *e = I->idx_end();
i != e; ++i)
Idxs.push_back(*i);
for (const unsigned *i = idx_begin, *e = idx_end; i != e; ++i)
Idxs.push_back(*i);
assert(Idxs.size() == size
&& "Number of indices added not correct?");
return FindInsertedValue(I->getAggregateOperand(), Idxs.begin(), Idxs.end(),
InsertBefore);
}
return 0;
}
bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
bool StopAtNul) {
if (V == NULL) return false;
if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul);
User *GEP = 0;
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
GEP = GEPI;
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (CE->getOpcode() == Instruction::BitCast)
return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul);
if (CE->getOpcode() != Instruction::GetElementPtr)
return false;
GEP = CE;
}
if (GEP) {
if (GEP->getNumOperands() != 3)
return false;
const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
if (AT == 0 || AT->getElementType() != Type::Int8Ty)
return false;
ConstantInt *FirstIdx = dyn_cast<ConstantInt>(GEP->getOperand(1));
if (FirstIdx == 0 || !FirstIdx->isZero())
return false;
uint64_t StartIdx = 0;
if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
StartIdx = CI->getZExtValue();
else
return false;
return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset,
StopAtNul);
}
GlobalVariable* GV = dyn_cast<GlobalVariable>(V);
if (!GV || !GV->isConstant() || !GV->hasInitializer())
return false;
Constant *GlobalInit = GV->getInitializer();
if (isa<ConstantAggregateZero>(GlobalInit)) {
Str.clear();
return true;
}
ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
if (Array == 0 || Array->getType()->getElementType() != Type::Int8Ty)
return false;
uint64_t NumElts = Array->getType()->getNumElements();
if (Offset > NumElts)
return false;
Str.reserve(NumElts-Offset);
for (unsigned i = Offset; i != NumElts; ++i) {
Constant *Elt = Array->getOperand(i);
ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
if (!CI) return false;
if (StopAtNul && CI->isZero())
return true; Str += (char)CI->getZExtValue();
}
return true;
}