From 436c90619c16bd8a7466b0105fa087c7147373c2 Mon Sep 17 00:00:00 2001 From: Michael Kruse Date: Fri, 8 Apr 2016 16:20:08 +0000 Subject: [PATCH] [ScopInfo] Fix check for element size mismatch. The way to get the elements size with getPrimitiveSizeInBits() is not the same as used in other parts of Polly which should use DataLayout::getTypeAllocSize(). Its use only queries the size of the pointer and getPrimitiveSizeInBits returns 0 for types that require a DataLayout object such as pointers. Together with r265379, this should fix PR27195. llvm-svn: 265795 --- polly/lib/Analysis/ScopInfo.cpp | 4 +- polly/test/ScopInfo/multidim_gep_pointercast.ll | 56 +++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 polly/test/ScopInfo/multidim_gep_pointercast.ll diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 24cd721..23b82c5 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -3992,7 +3992,9 @@ bool ScopInfo::buildAccessMultiDimFixed( auto *Src = BitCast->getOperand(0); auto *SrcTy = Src->getType(); auto *DstTy = BitCast->getType(); - if (SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits()) + if (SrcTy->isPointerTy() && DstTy->isPointerTy() && + DL->getTypeAllocSize(SrcTy->getPointerElementType()) == + DL->getTypeAllocSize(DstTy->getPointerElementType())) Address = Src; } diff --git a/polly/test/ScopInfo/multidim_gep_pointercast.ll b/polly/test/ScopInfo/multidim_gep_pointercast.ll new file mode 100644 index 0000000..3091767 --- /dev/null +++ b/polly/test/ScopInfo/multidim_gep_pointercast.ll @@ -0,0 +1,56 @@ +; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; +; The load access to A has a pointer-bitcast to another elements size before the +; GetElementPtr. Verify that we do not the GEP delinearization because it +; mismatches with the size of the loaded element type. +; +; void f(short A[][4], int N, int P) { +; short(*B)[4] = &A[P][0]; +; for (int i = 0; i < N; i++) +; *((<4 x short> *)&A[7 * i][0]) = *((<4 x short>)&B[7 * i][0]); +; } +; +define void @f([4 x i16]* %A, i32 %N, i32 %P) { +entry: + %arrayidx1 = getelementptr inbounds [4 x i16], [4 x i16]* %A, i32 %P, i64 0 + %tmp = bitcast i16* %arrayidx1 to [4 x i16]* + br label %for.cond + +for.cond: + %indvars.iv = phi i32 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %cmp = icmp slt i32 %indvars.iv, %N + br i1 %cmp, label %for.body, label %for.end + +for.body: + %mul = mul nsw i32 %indvars.iv, 7 + %arrayidx4 = getelementptr inbounds [4 x i16], [4 x i16]* %tmp, i32 %mul, i64 0 + %bc4 = bitcast i16* %arrayidx4 to <4 x i16>* + %tmp3 = load <4 x i16>, <4 x i16>* %bc4 + %arrayidx8 = getelementptr inbounds [4 x i16], [4 x i16]* %A, i32 %mul, i64 0 + %bc8 = bitcast i16* %arrayidx8 to <4 x i16>* + store <4 x i16> %tmp3, <4 x i16>* %bc8 + br label %for.inc + +for.inc: + %indvars.iv.next = add nuw nsw i32 %indvars.iv, 1 + br label %for.cond + +for.end: + ret void +} + + +; CHECK: Arrays { +; CHECK-NEXT: <4 x i16> MemRef_A[*]; // Element size 8 +; CHECK-NEXT: } +; CHECK: Statements { +; CHECK-NEXT: Stmt_for_body +; CHECK-NEXT: Domain := +; CHECK-NEXT: [N, P] -> { Stmt_for_body[i0] : 0 <= i0 < N }; +; CHECK-NEXT: Schedule := +; CHECK-NEXT: [N, P] -> { Stmt_for_body[i0] -> [i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [N, P] -> { Stmt_for_body[i0] -> MemRef_A[P + 7i0] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [N, P] -> { Stmt_for_body[i0] -> MemRef_A[7i0] }; +; CHECK-NEXT: } -- 2.7.4