From faf601ee936a440027447fa11ef400cf53bc1acf Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Tue, 5 Feb 2013 19:04:36 +0000 Subject: [PATCH] ConstantFolding: Fix a crash when encoutering a truncating inttoptr. This was introduced in r173293. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174424 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ConstantFolding.cpp | 10 +++++++--- test/Transforms/InstSimplify/ptr_diff.ll | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 400ce72ce6a..91424b22366 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -545,14 +545,18 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, // constant. This happens frequently when iterating over a global array. if (Opc == Instruction::Sub && TD) { GlobalValue *GV1, *GV2; - APInt Offs1(TD->getPointerSizeInBits(), 0), - Offs2(TD->getPointerSizeInBits(), 0); + unsigned PtrSize = TD->getPointerSizeInBits(); + unsigned OpSize = TD->getTypeSizeInBits(Op0->getType()); + APInt Offs1(PtrSize, 0), Offs2(PtrSize, 0); if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1, *TD)) if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2, *TD) && GV1 == GV2) { // (&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)); } } diff --git a/test/Transforms/InstSimplify/ptr_diff.ll b/test/Transforms/InstSimplify/ptr_diff.ll index 86516280696..8b4aa796013 100644 --- a/test/Transforms/InstSimplify/ptr_diff.ll +++ b/test/Transforms/InstSimplify/ptr_diff.ll @@ -57,3 +57,22 @@ define <4 x i32> @ptrdiff4(<4 x i8*> %arg) nounwind { %sub = sub <4 x i32> %p1, %p2 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 +} -- 2.34.1