diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-02-16 19:10:02 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-02-16 19:10:02 +0000 |
commit | 8b77454dff820832259acefe45e4254203760f19 (patch) | |
tree | 20289202a3e0593649cd841eb71c35f8fb3c4618 /llvm/lib/IR/ConstantFold.cpp | |
parent | 83570247f1f3dfebba12d13f41a9b6b500419e88 (diff) | |
download | llvm-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.cpp | 49 |
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 { |