rrkUndefBasePtr,
rrkVariantBasePtr,
rrkNonAffineAccess,
+ rrkDifferentElementSize,
rrkLastAffFunc,
rrkLoopBound,
};
//===----------------------------------------------------------------------===//
+/// @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 {
//===--------------------------------------------------------------------===//
cl::desc("Print information about the activities of Polly"),
cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+static cl::opt<bool> 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<bool>
AllowNonAffine("polly-allow-nonaffine",
cl::desc("Allow non affine access functions in arrays"),
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<ReportDifferentArrayElementSize>(Context, /*Assert=*/true,
+ Inst, BaseValue);
+
Context.ElementSize[BasePointer] =
SE->getSMinExpr(Size, Context.ElementSize[BasePointer]);
- else
+ } else {
Context.ElementSize[BasePointer] = Size;
+ }
bool isVariantInNonAffineLoop = false;
SetVector<const Loop *> Loops;
}
//===----------------------------------------------------------------------===//
+// 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.
std::string ReportNonAffineAccess::getMessage() const {
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();
; 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.
-; 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"
-; 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
; 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
-; 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++) {
-; 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++) {
; RUN: opt %loadPolly -polly-scops -pass-remarks-analysis="polly-scops" \
+; RUN: -polly-allow-differing-element-types \
; RUN: -analyze < %s 2>&1 | FileCheck %s
;
;
; 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]) {
-; 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) {