From 8286b83f97106fde561b28c7cb1fe7d5a479de6e Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Mon, 2 Nov 2015 11:29:32 +0000 Subject: [PATCH] ScopInfo: Bail out in case of mismatching array dimension sizes In some cases different memory accesses access the very same array using a different multi-dimensional array layout where the same dimensions have different sizes. Instead of asserting when encountering this issue, we gracefully bail out for this scop. This fixes llvm.org/PR25252 llvm-svn: 251791 --- polly/include/polly/ScopInfo.h | 3 +- polly/lib/Analysis/ScopInfo.cpp | 26 +++++---- .../ScopInfo/mismatching-array-dimensions.ll | 55 +++++++++++++++++++ 3 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 polly/test/ScopInfo/mismatching-array-dimensions.ll diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index 6496717daf84..94a8355e66a3 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -103,7 +103,8 @@ public: /// /// @param A vector of array sizes where the rightmost array sizes need to /// match the innermost array sizes already defined in SAI. - void updateSizes(ArrayRef Sizes); + /// @returns Returns true if the update was successful, otherwise false. + bool updateSizes(ArrayRef Sizes); /// @brief Destructor to free the isl id of the base pointer. ~ScopArrayInfo(); diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index fdcf0065d10f..2c99d47307cd 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -173,16 +173,16 @@ __isl_give isl_space *ScopArrayInfo::getSpace() const { return Space; } -void ScopArrayInfo::updateSizes(ArrayRef NewSizes) { -#ifndef NDEBUG +bool ScopArrayInfo::updateSizes(ArrayRef NewSizes) { int SharedDims = std::min(NewSizes.size(), DimensionSizes.size()); int ExtraDimsNew = NewSizes.size() - SharedDims; int ExtraDimsOld = DimensionSizes.size() - SharedDims; - for (int i = 0; i < SharedDims; i++) { - assert(NewSizes[i + ExtraDimsNew] == DimensionSizes[i + ExtraDimsOld] && - "Array update with non-matching dimension sizes"); - } -#endif + for (int i = 0; i < SharedDims; i++) + if (NewSizes[i + ExtraDimsNew] != DimensionSizes[i + ExtraDimsOld]) + return false; + + if (DimensionSizes.size() >= NewSizes.size()) + return true; DimensionSizes.clear(); DimensionSizes.insert(DimensionSizes.begin(), NewSizes.begin(), @@ -194,6 +194,7 @@ void ScopArrayInfo::updateSizes(ArrayRef NewSizes) { isl_pw_aff *Size = S.getPwAff(Expr); DimensionSizesPw.push_back(Size); } + return true; } ScopArrayInfo::~ScopArrayInfo() { @@ -2377,9 +2378,12 @@ void Scop::init(AliasAnalysis &AA) { Loop *L = getLoopSurroundingRegion(R, LI); LoopSchedules[L]; buildSchedule(&R, LoopSchedules); - updateAccessDimensionality(); Schedule = LoopSchedules[L].first; + if (isl_set_is_empty(AssumedContext)) + return; + + updateAccessDimensionality(); realignParams(); addParameterBounds(); addUserContext(); @@ -2640,8 +2644,10 @@ Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType, SAI.reset(new ScopArrayInfo(BasePtr, AccessType, getIslCtx(), Sizes, IsPHI, this)); } else { - if (Sizes.size() > SAI->getNumberOfDimensions()) - SAI->updateSizes(Sizes); + // In case of mismatching array sizes, we bail out by setting the run-time + // context to false. + if (!SAI->updateSizes(Sizes)) + addAssumption(isl_set_empty(getParamSpace())); } return SAI.get(); } diff --git a/polly/test/ScopInfo/mismatching-array-dimensions.ll b/polly/test/ScopInfo/mismatching-array-dimensions.ll new file mode 100644 index 000000000000..0cf4a435d37a --- /dev/null +++ b/polly/test/ScopInfo/mismatching-array-dimensions.ll @@ -0,0 +1,55 @@ +; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s + +; CHECK-NOT: AssumedContext + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.9.0" + +; Function Attrs: nounwind ssp uwtable +define void @hoge([38 x [64 x float]]* %arg, [32 x [2 x float]]* %arg5, i32 %arg6) #0 { +bb: + br i1 undef, label %bb7, label %bb25 + +bb7: ; preds = %bb21, %bb + %tmp8 = phi i64 [ %tmp22, %bb21 ], [ 0, %bb ] + %tmp9 = icmp sgt i32 %arg6, 0 + br i1 %tmp9, label %bb10, label %bb21 + +bb10: ; preds = %bb10, %bb7 + %tmp11 = getelementptr inbounds [32 x [2 x float]], [32 x [2 x float]]* %arg5, i64 %tmp8, i64 0 + %tmp = bitcast [2 x float]* %tmp11 to i32* + %tmp12 = load i32, i32* %tmp, align 4, !tbaa !4 + %tmp13 = getelementptr inbounds [32 x [2 x float]], [32 x [2 x float]]* %arg5, i64 %tmp8, i64 0, i64 1 + %tmp14 = bitcast float* %tmp13 to i32* + %tmp15 = load i32, i32* %tmp14, align 4, !tbaa !4 + %tmp16 = getelementptr inbounds [38 x [64 x float]], [38 x [64 x float]]* %arg, i64 1, i64 0, i64 %tmp8 + %tmp17 = bitcast float* %tmp16 to i32* + store i32 %tmp15, i32* %tmp17, align 4, !tbaa !4 + %tmp18 = add nuw nsw i64 0, 1 + %tmp19 = trunc i64 %tmp18 to i32 + %tmp20 = icmp ne i32 %tmp19, %arg6 + br i1 %tmp20, label %bb10, label %bb21 + +bb21: ; preds = %bb10, %bb7 + %tmp22 = add nsw i64 %tmp8, 1 + %tmp23 = trunc i64 %tmp22 to i32 + %tmp24 = icmp ne i32 %tmp23, 64 + br i1 %tmp24, label %bb7, label %bb25 + +bb25: ; preds = %bb21, %bb + ret void +} + +attributes #0 = { nounwind ssp uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="core2" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0, !1, !2} +!llvm.ident = !{!3} + +!0 = !{i32 2, !"Dwarf Version", i32 2} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = !{i32 1, !"PIC Level", i32 2} +!3 = !{!"clang version 3.8.0 (trunk 251760) (llvm/trunk 251765)"} +!4 = !{!5, !5, i64 0} +!5 = !{!"float", !6, i64 0} +!6 = !{!"omnipotent char", !7, i64 0} +!7 = !{!"Simple C/C++ TBAA"}