mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
ConstantFold: Properly fold GEP indices wider than i64
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229420 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
25a35b5639
commit
e6e5eaa50d
@ -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!
|
||||
|
||||
// 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!
|
||||
|
||||
// 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()));
|
||||
// type.
|
||||
int64_t C1Val = cast<ConstantInt>(C1)->getSExtValue();
|
||||
int64_t C2Val = cast<ConstantInt>(C2)->getSExtValue();
|
||||
|
||||
if (!C2->getType()->isIntegerTy(64))
|
||||
C2 = ConstantExpr::getSExt(C2, Type::getInt64Ty(C1->getContext()));
|
||||
|
||||
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 {
|
||||
|
@ -8,6 +8,12 @@
|
||||
@C = global i32* getelementptr ([2 x [3 x [5 x [7 x i32]]]]* @A, i64 3, i64 2, i64 0, i64 0, i64 7523)
|
||||
; CHECK: @C = global i32* getelementptr ([2 x [3 x [5 x [7 x i32]]]]* @A, i64 39, i64 1, i64 1, i64 4, i64 5)
|
||||
|
||||
; Verify that constant expression GEPs work with i84 indices.
|
||||
@D = external global [1 x i32]
|
||||
|
||||
@E = global i32* getelementptr inbounds ([1 x i32]* @D, i84 0, i64 1)
|
||||
; CHECK: @E = global i32* getelementptr inbounds ([1 x i32]* @D, i84 1, i64 0)
|
||||
|
||||
; Verify that i16 indices work.
|
||||
@x = external global {i32, i32}
|
||||
@y = global i32* getelementptr ({ i32, i32 }* @x, i16 42, i32 0)
|
||||
|
Loading…
Reference in New Issue
Block a user