X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FInstructionSimplify.cpp;h=87125191ad0e77f429e177add08af6e2148b9ce6;hb=ed58a6f96f605901adc0df3ca76499d52b2d1a1a;hp=97612f46d327aac2059067141f1c999af6ce5b57;hpb=87689cfc54993959adb20b89a56bc58aad18ca56;p=oota-llvm.git diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 97612f46d32..87125191ad0 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -8,8 +8,10 @@ //===----------------------------------------------------------------------===// // // This file implements routines for folding instructions into simpler forms -// that do not require creating new instructions. For example, this does -// constant folding, and can handle identities like (X&0)->0. +// that do not require creating new instructions. This does constant folding +// ("add i32 1, 1" -> "2") but can also handle non-constant operands, either +// returning a constant ("and i32 %x, 0" -> "0") or an already existing value +// ("and i32 %x, %x" -> "%x"). // //===----------------------------------------------------------------------===// @@ -18,6 +20,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Support/PatternMatch.h" #include "llvm/Support/ValueHandle.h" +#include "llvm/Target/TargetData.h" using namespace llvm; using namespace llvm::PatternMatch; @@ -295,7 +298,7 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD, return Op0; // A & ~A = ~A & A = 0 - Value *A, *B; + Value *A = 0, *B = 0; if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getNullValue(Op0->getType()); @@ -374,7 +377,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD, return Op1; // A | ~A = ~A | A = -1 - Value *A, *B; + Value *A = 0, *B = 0; if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getAllOnesValue(Op0->getType()); @@ -449,7 +452,7 @@ static Value *SimplifyXorInst(Value *Op0, Value *Op1, const TargetData *TD, return Constant::getNullValue(Op0->getType()); // A ^ ~A = ~A ^ A = -1 - Value *A, *B; + Value *A = 0, *B = 0; if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getAllOnesValue(Op0->getType()); @@ -690,19 +693,33 @@ Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, /// fold the result. If not, this returns null. Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps, const TargetData *TD, const DominatorTree *) { + // The type of the GEP pointer operand. + const PointerType *PtrTy = cast(Ops[0]->getType()); + // getelementptr P -> P. if (NumOps == 1) return Ops[0]; - // TODO. - //if (isa(Ops[0])) - // return UndefValue::get(GEP.getType()); + if (isa(Ops[0])) { + // Compute the (pointer) type returned by the GEP instruction. + const Type *LastType = GetElementPtrInst::getIndexedType(PtrTy, &Ops[1], + NumOps-1); + const Type *GEPTy = PointerType::get(LastType, PtrTy->getAddressSpace()); + return UndefValue::get(GEPTy); + } - // getelementptr P, 0 -> P. - if (NumOps == 2) + if (NumOps == 2) { + // getelementptr P, 0 -> P. if (ConstantInt *C = dyn_cast(Ops[1])) if (C->isZero()) return Ops[0]; + // getelementptr P, N -> P if P points to a type of zero size. + if (TD) { + const Type *Ty = PtrTy->getElementType(); + if (Ty->isSized() && TD->getTypeAllocSize(Ty) == 0) + return Ops[0]; + } + } // Check to see if this is constant foldable. for (unsigned i = 0; i != NumOps; ++i)