diff --git a/polly/include/polly/ScopDetectionDiagnostic.h b/polly/include/polly/ScopDetectionDiagnostic.h index abc60b137751..4f16a1c7b52a 100644 --- a/polly/include/polly/ScopDetectionDiagnostic.h +++ b/polly/include/polly/ScopDetectionDiagnostic.h @@ -75,6 +75,7 @@ enum RejectReasonKind { rrkUndefBasePtr, rrkVariantBasePtr, rrkNonAffineAccess, + rrkDifferentElementSize, rrkLastAffFunc, rrkLoopBound, @@ -519,6 +520,30 @@ public: //@} }; +//===----------------------------------------------------------------------===// +/// @brief Report array accesses with differing element size. +class ReportDifferentArrayElementSize : public ReportAffFunc { + //===--------------------------------------------------------------------===// + + // The base pointer of the memory access. + const Value *BaseValue; + +public: + ReportDifferentArrayElementSize(const Instruction *Inst, const Value *V) + : ReportAffFunc(rrkDifferentElementSize, Inst), BaseValue(V) {} + + /// @name LLVM-RTTI interface + //@{ + static bool classof(const RejectReason *RR); + //@} + + /// @name RejectReason interface + //@{ + virtual std::string getMessage() const override; + virtual std::string getEndUserMessage() const override; + //@} +}; + //===----------------------------------------------------------------------===// /// @brief Captures errors with non affine loop bounds. class ReportLoopBound : public RejectReason { diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index 5122c2024b10..3d24596d45d7 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -121,6 +121,11 @@ static cl::opt cl::desc("Print information about the activities of Polly"), cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); +static cl::opt AllowDifferentTypes( + "polly-allow-differing-element-types", + cl::desc("Allow different element types for array accesses"), cl::Hidden, + cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); + static cl::opt AllowNonAffine("polly-allow-nonaffine", cl::desc("Allow non affine access functions in arrays"), @@ -787,11 +792,16 @@ bool ScopDetection::isValidMemoryAccess(MemAccInst Inst, AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer); const SCEV *Size = SE->getElementSize(Inst); - if (Context.ElementSize[BasePointer]) + if (Context.ElementSize[BasePointer]) { + if (!AllowDifferentTypes && Context.ElementSize[BasePointer] != Size) + return invalid(Context, /*Assert=*/true, + Inst, BaseValue); + Context.ElementSize[BasePointer] = SE->getSMinExpr(Size, Context.ElementSize[BasePointer]); - else + } else { Context.ElementSize[BasePointer] = Size; + } bool isVariantInNonAffineLoop = false; SetVector Loops; diff --git a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp index 879449bef7ac..5d5a1a43f8ee 100644 --- a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp +++ b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp @@ -269,6 +269,24 @@ bool ReportVariantBasePtr::classof(const RejectReason *RR) { return RR->getKind() == rrkVariantBasePtr; } +//===----------------------------------------------------------------------===// +// ReportDifferentArrayElementSize + +std::string ReportDifferentArrayElementSize::getMessage() const { + return "Access to one array through data types of different size"; +} + +bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) { + return RR->getKind() == rrkDifferentElementSize; +} + +std::string ReportDifferentArrayElementSize::getEndUserMessage() const { + llvm::StringRef BaseName = BaseValue->getName(); + std::string Name = (BaseName.size() > 0) ? BaseName : "UNKNOWN"; + return "The array \"" + Name + "\" is accessed through elements that differ " + "in size"; +} + //===----------------------------------------------------------------------===// // ReportNonAffineAccess. diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp index 750c8b94ad51..12ef856303f9 100644 --- a/polly/lib/CodeGen/CodeGeneration.cpp +++ b/polly/lib/CodeGen/CodeGeneration.cpp @@ -174,9 +174,6 @@ public: fixRegionInfo(EnteringBB->getParent(), R->getParent()); } - assert(!verifyGeneratedFunction(S, *EnteringBB->getParent()) && - "Verification of generated function failed"); - // Mark the function such that we run additional cleanup passes on this // function (e.g. mem2reg to rediscover phi nodes). Function *F = EnteringBB->getParent(); diff --git a/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll b/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll index e7f097f33d07..816ff2281376 100644 --- a/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll +++ b/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S \ +; RUN: -polly-allow-differing-element-types \ ; RUN: -polly-codegen -S < %s | FileCheck %s ; ; // Check that accessing one array with different types works. diff --git a/polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll b/polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll index 32008bd9fdf1..969a87f516f2 100644 --- a/polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll +++ b/polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s +; RUN: opt %loadPolly -polly-codegen -S \ +; RUN: -polly-allow-differing-element-types < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll b/polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll index af269c1126c5..4f3ffb50f65d 100644 --- a/polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll +++ b/polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s +; RUN: opt %loadPolly -polly-codegen -S \ +; RUN: -polly-allow-differing-element-types < %s | FileCheck %s ; CHECK: polly diff --git a/polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll b/polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll index cf6ef154a40c..2001d33bb713 100644 --- a/polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll +++ b/polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -pass-remarks-analysis="polly-scops" \ +; RUN: -polly-allow-differing-element-types \ ; RUN: -analyze < %s 2>&1 | FileCheck %s ; ; // For the following accesses the offset expression from the base pointer diff --git a/polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll b/polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll index b499e0e0f646..ec0154cbbdd2 100644 --- a/polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll +++ b/polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-scops -analyze \ +; RUN: -polly-allow-differing-element-types < %s | FileCheck %s ; ; void multiple_types(i128 *A) { ; for (long i = 0; i < 100; i++) { diff --git a/polly/test/ScopInfo/multiple-types-non-power-of-two.ll b/polly/test/ScopInfo/multiple-types-non-power-of-two.ll index 5616a98116c0..f95aa120ea55 100644 --- a/polly/test/ScopInfo/multiple-types-non-power-of-two.ll +++ b/polly/test/ScopInfo/multiple-types-non-power-of-two.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-scops -analyze \ +; RUN: -polly-allow-differing-element-types < %s | FileCheck %s ; ; void multiple_types(i8 *A) { ; for (long i = 0; i < 100; i++) { diff --git a/polly/test/ScopInfo/multiple-types-two-dimensional-2.ll b/polly/test/ScopInfo/multiple-types-two-dimensional-2.ll index 9946fc062f10..116bdac3ff87 100644 --- a/polly/test/ScopInfo/multiple-types-two-dimensional-2.ll +++ b/polly/test/ScopInfo/multiple-types-two-dimensional-2.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -pass-remarks-analysis="polly-scops" \ +; RUN: -polly-allow-differing-element-types \ ; RUN: -analyze < %s 2>&1 | FileCheck %s ; ; diff --git a/polly/test/ScopInfo/multiple-types-two-dimensional.ll b/polly/test/ScopInfo/multiple-types-two-dimensional.ll index b329b54f7b53..5885595c2eb1 100644 --- a/polly/test/ScopInfo/multiple-types-two-dimensional.ll +++ b/polly/test/ScopInfo/multiple-types-two-dimensional.ll @@ -1,4 +1,5 @@ ; RUN: opt %loadPolly -polly-scops -pass-remarks-analysis="polly-scops" \ +; RUN: -polly-allow-differing-element-types \ ; RUN: -analyze < %s 2>&1 | FileCheck %s ; ; void foo(long n, long m, char A[][m]) { diff --git a/polly/test/ScopInfo/multiple-types.ll b/polly/test/ScopInfo/multiple-types.ll index 84e3935e80da..a776f3e667db 100644 --- a/polly/test/ScopInfo/multiple-types.ll +++ b/polly/test/ScopInfo/multiple-types.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-scops -analyze \ +; RUN: -polly-allow-differing-element-types < %s | FileCheck %s ; ; // Check that accessing one array with different types works. ; void multiple_types(char *Short, char *Float, char *Double) {