ConstantFolding: Fix a crash when encoutering a truncating inttoptr.
This was introduced in r173293. llvm-svn: 174424
This commit is contained in:
parent
3be40b56c5
commit
a5a9ec5755
|
@ -545,14 +545,18 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
|
||||||
// constant. This happens frequently when iterating over a global array.
|
// constant. This happens frequently when iterating over a global array.
|
||||||
if (Opc == Instruction::Sub && TD) {
|
if (Opc == Instruction::Sub && TD) {
|
||||||
GlobalValue *GV1, *GV2;
|
GlobalValue *GV1, *GV2;
|
||||||
APInt Offs1(TD->getPointerSizeInBits(), 0),
|
unsigned PtrSize = TD->getPointerSizeInBits();
|
||||||
Offs2(TD->getPointerSizeInBits(), 0);
|
unsigned OpSize = TD->getTypeSizeInBits(Op0->getType());
|
||||||
|
APInt Offs1(PtrSize, 0), Offs2(PtrSize, 0);
|
||||||
|
|
||||||
if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1, *TD))
|
if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1, *TD))
|
||||||
if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2, *TD) &&
|
if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2, *TD) &&
|
||||||
GV1 == GV2) {
|
GV1 == GV2) {
|
||||||
// (&GV+C1) - (&GV+C2) -> C1-C2, pointer arithmetic cannot overflow.
|
// (&GV+C1) - (&GV+C2) -> C1-C2, pointer arithmetic cannot overflow.
|
||||||
return ConstantInt::get(Op0->getType(), Offs1-Offs2);
|
// PtrToInt may change the bitwidth so we have convert to the right size
|
||||||
|
// first.
|
||||||
|
return ConstantInt::get(Op0->getType(), Offs1.zextOrTrunc(OpSize) -
|
||||||
|
Offs2.zextOrTrunc(OpSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,3 +57,22 @@ define <4 x i32> @ptrdiff4(<4 x i8*> %arg) nounwind {
|
||||||
%sub = sub <4 x i32> %p1, %p2
|
%sub = sub <4 x i32> %p1, %p2
|
||||||
ret <4 x i32> %sub
|
ret <4 x i32> %sub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%struct.ham = type { i32, [2 x [2 x i32]] }
|
||||||
|
|
||||||
|
@global = internal global %struct.ham zeroinitializer, align 4
|
||||||
|
|
||||||
|
define i32 @ptrdiff5() nounwind {
|
||||||
|
bb:
|
||||||
|
%tmp = getelementptr inbounds %struct.ham* @global, i32 0, i32 1
|
||||||
|
%tmp1 = getelementptr inbounds [2 x [2 x i32]]* %tmp, i32 0, i32 0
|
||||||
|
%tmp2 = bitcast [2 x i32]* %tmp1 to i32*
|
||||||
|
%tmp3 = ptrtoint i32* %tmp2 to i32
|
||||||
|
%tmp4 = getelementptr inbounds %struct.ham* @global, i32 0, i32 1
|
||||||
|
%tmp5 = getelementptr inbounds [2 x [2 x i32]]* %tmp4, i32 0, i32 0
|
||||||
|
%tmp6 = ptrtoint [2 x i32]* %tmp5 to i32
|
||||||
|
%tmp7 = sub i32 %tmp3, %tmp6
|
||||||
|
ret i32 %tmp7
|
||||||
|
; CHECK: @ptrdiff5
|
||||||
|
; CHECK: ret i32 0
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue