#include "ConstantFold.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalAlias.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Instructions.h"
-#include "llvm/Operator.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalAlias.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Operator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
foldConstantCastPair(
unsigned opc, ///< opcode of the second cast constant expression
ConstantExpr *Op, ///< the first cast constant expression
- Type *DstTy ///< desintation type of the first cast
+ Type *DstTy ///< destination type of the first cast
) {
assert(Op && Op->isCast() && "Can't fold cast of cast without a cast!");
assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type");
Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode());
Instruction::CastOps secondOp = Instruction::CastOps(opc);
- // Assume that pointers are never more than 64 bits wide.
+ // Assume that pointers are never more than 64 bits wide, and only use this
+ // for the middle type. Otherwise we could end up folding away illegal
+ // bitcasts between address spaces with different sizes.
IntegerType *FakeIntPtrTy = Type::getInt64Ty(DstTy->getContext());
// Let CastInst::isEliminableCastPair do the heavy lifting.
return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy,
- FakeIntPtrTy, FakeIntPtrTy,
- FakeIntPtrTy);
+ 0, FakeIntPtrTy, 0);
}
static Constant *FoldBitCast(Constant *V, Type *DestTy) {
if (DestTy->isFloatingPointTy())
return ConstantFP::get(DestTy->getContext(),
- APFloat(CI->getValue(),
- !DestTy->isPPC_FP128Ty()));
+ APFloat(DestTy->getFltSemantics(),
+ CI->getValue()));
// Otherwise, can't fold this (vector?)
return 0;
case Instruction::SIToFP:
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
APInt api = CI->getValue();
- APFloat apf(APInt::getNullValue(DestTy->getPrimitiveSizeInBits()),
- !DestTy->isPPC_FP128Ty() /* isEEEE */);
+ APFloat apf(DestTy->getFltSemantics(),
+ APInt::getNullValue(DestTy->getPrimitiveSizeInBits()));
(void)apf.convertFromAPInt(api,
opc==Instruction::SIToFP,
APFloat::rmNearestTiesToEven);
}
case Instruction::BitCast:
return FoldBitCast(V, DestTy);
+ case Instruction::AddrSpaceCast:
+ return 0;
}
}
else if (ArrayType *AT = dyn_cast<ArrayType>(Agg->getType()))
NumElts = AT->getNumElements();
else
- NumElts = AT->getVectorNumElements();
-
+ NumElts = Agg->getType()->getVectorNumElements();
+
SmallVector<Constant*, 32> Result;
for (unsigned i = 0; i != NumElts; ++i) {
Constant *C = Agg->getAggregateElement(i);
"Surprising getelementptr!");
return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
} else {
- // If they are different globals, we don't know what the value is,
- // but they can't be equal.
- return ICmpInst::ICMP_NE;
+ // If they are different globals, we don't know what the value is.
+ return ICmpInst::BAD_ICMP_PREDICATE;
}
}
} else {
default: break;
case Instruction::GetElementPtr:
// By far the most common case to handle is when the base pointers are
- // obviously to the same or different globals.
+ // obviously to the same global.
if (isa<GlobalValue>(CE1Op0) && isa<GlobalValue>(CE2Op0)) {
- if (CE1Op0 != CE2Op0) // Don't know relative ordering, but not equal
- return ICmpInst::ICMP_NE;
+ if (CE1Op0 != CE2Op0) // Don't know relative ordering.
+ return ICmpInst::BAD_ICMP_PREDICATE;
// Ok, we know that both getelementptr instructions are based on the
// same global. From this, we can precisely determine the relative
// ordering of the resultant pointers.
if (CE1Inverse == CE1Op0) {
// Check whether we can safely truncate the right hand side.
Constant *C2Inverse = ConstantExpr::getTrunc(C2, CE1Op0->getType());
- if (ConstantExpr::getZExt(C2Inverse, C2->getType()) == C2) {
+ if (ConstantExpr::getCast(CE1->getOpcode(), C2Inverse,
+ C2->getType()) == C2)
return ConstantExpr::getICmp(pred, CE1Inverse, C2Inverse);
- }
}
}
}
return true;
}
+/// \brief Test whether a given ConstantInt is in-range for a SequentialType.
+static bool isIndexInRangeOfSequentialType(const SequentialType *STy,
+ const ConstantInt *CI) {
+ if (const PointerType *PTy = dyn_cast<PointerType>(STy))
+ // Only handle pointers to sized types, not pointers to functions.
+ return PTy->getElementType()->isSized();
+
+ uint64_t NumElements = 0;
+ // Determine the number of elements in our sequential type.
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(STy))
+ NumElements = ATy->getNumElements();
+ else if (const VectorType *VTy = dyn_cast<VectorType>(STy))
+ NumElements = VTy->getNumElements();
+
+ assert((isa<ArrayType>(STy) || NumElements > 0) &&
+ "didn't expect non-array type to have zero elements!");
+
+ // We cannot bounds check the index if it doesn't fit in an int64_t.
+ if (CI->getValue().getActiveBits() > 64)
+ return false;
+
+ // A negative index or an index past the end of our sequential type is
+ // considered out-of-range.
+ int64_t IndexVal = CI->getSExtValue();
+ if (IndexVal < 0 || (NumElements > 0 && (uint64_t)IndexVal >= NumElements))
+ return false;
+
+ // Otherwise, it is in-range.
+ return true;
+}
+
template<typename IndexTy>
static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
bool inBounds,
I != E; ++I)
LastTy = *I;
- if ((LastTy && isa<SequentialType>(LastTy)) || Idx0->isNullValue()) {
+ // We cannot combine indices if doing so would take us outside of an
+ // array or vector. Doing otherwise could trick us if we evaluated such a
+ // GEP as part of a load.
+ //
+ // e.g. Consider if the original GEP was:
+ // i8* getelementptr ({ [2 x i8], i32, i8, [3 x i8] }* @main.c,
+ // i32 0, i32 0, i64 0)
+ //
+ // If we then tried to offset it by '8' to get to the third element,
+ // an i8, we should *not* get:
+ // i8* getelementptr ({ [2 x i8], i32, i8, [3 x i8] }* @main.c,
+ // i32 0, i32 0, i64 8)
+ //
+ // This GEP tries to index array element '8 which runs out-of-bounds.
+ // Subsequent evaluation would get confused and produce erroneous results.
+ //
+ // The following prohibits such a GEP from being formed by checking to see
+ // if the index is in-range with respect to an array or vector.
+ bool PerformFold = false;
+ if (Idx0->isNullValue())
+ PerformFold = true;
+ else if (SequentialType *STy = dyn_cast_or_null<SequentialType>(LastTy))
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx0))
+ PerformFold = isIndexInRangeOfSequentialType(STy, CI);
+
+ if (PerformFold) {
SmallVector<Value*, 16> NewIndices;
NewIndices.reserve(Idxs.size() + CE->getNumOperands());
for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i)
}
}
- // Implement folding of:
- // i32* getelementptr ([2 x i32]* bitcast ([3 x i32]* %X to [2 x i32]*),
- // i64 0, i64 0)
- // To: i32* getelementptr ([3 x i32]* %X, i64 0, i64 0)
+ // Attempt to fold casts to the same type away. For example, folding:
+ //
+ // i32* getelementptr ([2 x i32]* bitcast ([3 x i32]* %X to [2 x i32]*),
+ // i64 0, i64 0)
+ // into:
//
+ // i32* getelementptr ([3 x i32]* %X, i64 0, i64 0)
+ //
+ // Don't fold if the cast is changing address spaces.
if (CE->isCast() && Idxs.size() > 1 && Idx0->isNullValue()) {
- if (PointerType *SPT =
- dyn_cast<PointerType>(CE->getOperand(0)->getType()))
- if (ArrayType *SAT = dyn_cast<ArrayType>(SPT->getElementType()))
- if (ArrayType *CAT =
- dyn_cast<ArrayType>(cast<PointerType>(C->getType())->getElementType()))
- if (CAT->getElementType() == SAT->getElementType())
- return
- ConstantExpr::getGetElementPtr((Constant*)CE->getOperand(0),
- Idxs, inBounds);
+ PointerType *SrcPtrTy =
+ dyn_cast<PointerType>(CE->getOperand(0)->getType());
+ PointerType *DstPtrTy = dyn_cast<PointerType>(CE->getType());
+ if (SrcPtrTy && DstPtrTy) {
+ ArrayType *SrcArrayTy =
+ dyn_cast<ArrayType>(SrcPtrTy->getElementType());
+ ArrayType *DstArrayTy =
+ dyn_cast<ArrayType>(DstPtrTy->getElementType());
+ if (SrcArrayTy && DstArrayTy
+ && SrcArrayTy->getElementType() == DstArrayTy->getElementType()
+ && SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
+ return ConstantExpr::getGetElementPtr((Constant*)CE->getOperand(0),
+ Idxs, inBounds);
+ }
}
}
// Check to see if any array indices are not within the corresponding
- // notional array bounds. If so, try to determine if they can be factored
- // out into preceding dimensions.
+ // notional array or vector bounds. If so, try to determine if they can be
+ // factored out into preceding dimensions.
bool Unknown = false;
SmallVector<Constant *, 8> NewIdxs;
Type *Ty = C->getType();
for (unsigned i = 0, e = Idxs.size(); i != e;
Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) {
- if (ArrayType *ATy = dyn_cast<ArrayType>(Ty))
- if (ATy->getNumElements() <= INT64_MAX &&
- ATy->getNumElements() != 0 &&
- CI->getSExtValue() >= (int64_t)ATy->getNumElements()) {
+ if (isa<ArrayType>(Ty) || isa<VectorType>(Ty))
+ if (CI->getSExtValue() > 0 &&
+ !isIndexInRangeOfSequentialType(cast<SequentialType>(Ty), CI)) {
if (isa<SequentialType>(Prev)) {
// It's out of range, but we can factor it into the prior
// dimension.
NewIdxs.resize(Idxs.size());
- ConstantInt *Factor = ConstantInt::get(CI->getType(),
- ATy->getNumElements());
+ uint64_t NumElements = 0;
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty))
+ NumElements = ATy->getNumElements();
+ else
+ NumElements = cast<VectorType>(Ty)->getNumElements();
+
+ ConstantInt *Factor = ConstantInt::get(CI->getType(), NumElements);
NewIdxs[i] = ConstantExpr::getSRem(CI, Factor);
Constant *PrevIdx = cast<Constant>(Idxs[i-1]);