aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-02-16 19:10:02 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-02-16 19:10:02 +0000
commit8b77454dff820832259acefe45e4254203760f19 (patch)
tree20289202a3e0593649cd841eb71c35f8fb3c4618 /llvm/lib/IR/ConstantFold.cpp
parent83570247f1f3dfebba12d13f41a9b6b500419e88 (diff)
downloadllvm-8b77454dff820832259acefe45e4254203760f19.zip
llvm-8b77454dff820832259acefe45e4254203760f19.tar.gz
llvm-8b77454dff820832259acefe45e4254203760f19.tar.bz2
ConstantFold: Properly fold GEP indices wider than i64
llvm-svn: 229420
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp49
1 files changed, 31 insertions, 18 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 9176bf2..16ecf1c 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -1282,15 +1282,17 @@ static int IdxCompare(Constant *C1, Constant *C2, Type *ElTy) {
if (!isa<ConstantInt>(C1) || !isa<ConstantInt>(C2))
return -2; // don't know!
- // Ok, we have two differing integer indices. Sign extend them to be the same
- // type. Long is always big enough, so we use it.
- if (!C1->getType()->isIntegerTy(64))
- C1 = ConstantExpr::getSExt(C1, Type::getInt64Ty(C1->getContext()));
+ // We cannot compare the indices if they don't fit in an int64_t.
+ if (cast<ConstantInt>(C1)->getValue().getActiveBits() > 64 ||
+ cast<ConstantInt>(C2)->getValue().getActiveBits() > 64)
+ return -2; // don't know!
- if (!C2->getType()->isIntegerTy(64))
- C2 = ConstantExpr::getSExt(C2, Type::getInt64Ty(C1->getContext()));
+ // Ok, we have two differing integer indices. Sign extend them to be the same
+ // type.
+ int64_t C1Val = cast<ConstantInt>(C1)->getSExtValue();
+ int64_t C2Val = cast<ConstantInt>(C2)->getSExtValue();
- if (C1 == C2) return 0; // They are equal
+ if (C1Val == C2Val) return 0; // They are equal
// If the type being indexed over is really just a zero sized type, there is
// no pointer difference being made here.
@@ -1299,8 +1301,7 @@ static int IdxCompare(Constant *C1, Constant *C2, Type *ElTy) {
// If they are really different, now that they are the same type, then we
// found a difference!
- if (cast<ConstantInt>(C1)->getSExtValue() <
- cast<ConstantInt>(C2)->getSExtValue())
+ if (C1Val < C2Val)
return -1;
else
return 1;
@@ -2088,9 +2089,15 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
if (!Idx0->isNullValue()) {
Type *IdxTy = Combined->getType();
if (IdxTy != Idx0->getType()) {
- Type *Int64Ty = Type::getInt64Ty(IdxTy->getContext());
- Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, Int64Ty);
- Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, Int64Ty);
+ unsigned CommonExtendedWidth =
+ std::max(IdxTy->getIntegerBitWidth(),
+ Idx0->getType()->getIntegerBitWidth());
+ CommonExtendedWidth = std::max(CommonExtendedWidth, 64U);
+
+ Type *CommonTy =
+ Type::getIntNTy(IdxTy->getContext(), CommonExtendedWidth);
+ Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, CommonTy);
+ Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, CommonTy);
Combined = ConstantExpr::get(Instruction::Add, C1, C2);
} else {
Combined =
@@ -2163,14 +2170,20 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
Constant *PrevIdx = cast<Constant>(Idxs[i-1]);
Constant *Div = ConstantExpr::getSDiv(CI, Factor);
+ unsigned CommonExtendedWidth =
+ std::max(PrevIdx->getType()->getIntegerBitWidth(),
+ Div->getType()->getIntegerBitWidth());
+ CommonExtendedWidth = std::max(CommonExtendedWidth, 64U);
+
// Before adding, extend both operands to i64 to avoid
// overflow trouble.
- if (!PrevIdx->getType()->isIntegerTy(64))
- PrevIdx = ConstantExpr::getSExt(PrevIdx,
- Type::getInt64Ty(Div->getContext()));
- if (!Div->getType()->isIntegerTy(64))
- Div = ConstantExpr::getSExt(Div,
- Type::getInt64Ty(Div->getContext()));
+ if (!PrevIdx->getType()->isIntegerTy(CommonExtendedWidth))
+ PrevIdx = ConstantExpr::getSExt(
+ PrevIdx,
+ Type::getIntNTy(Div->getContext(), CommonExtendedWidth));
+ if (!Div->getType()->isIntegerTy(CommonExtendedWidth))
+ Div = ConstantExpr::getSExt(
+ Div, Type::getIntNTy(Div->getContext(), CommonExtendedWidth));
NewIdxs[i-1] = ConstantExpr::getAdd(PrevIdx, Div);
} else {