Index: include/polly/CodeGen/IslExprBuilder.h =================================================================== --- include/polly/CodeGen/IslExprBuilder.h +++ include/polly/CodeGen/IslExprBuilder.h @@ -130,6 +130,8 @@ llvm::Value *createOpBoolean(__isl_take isl_ast_expr *Expr); llvm::Value *createId(__isl_take isl_ast_expr *Expr); llvm::Value *createInt(__isl_take isl_ast_expr *Expr); + llvm::Value *createOpAddressOf(__isl_take isl_ast_expr *Expr); + llvm::Value *createAccessAddress(__isl_take isl_ast_expr *Expr); }; } Index: include/polly/ScopDetection.h =================================================================== --- include/polly/ScopDetection.h +++ include/polly/ScopDetection.h @@ -107,6 +107,7 @@ extern bool PollyTrackFailures; extern bool PollyDelinearize; +extern bool PollyUseRuntimeAliasChecks; /// @brief A function attribute which will cause Polly to skip the function extern llvm::StringRef PollySkipFnAttr; @@ -267,7 +268,7 @@ public: static char ID; - explicit ScopDetection() : FunctionPass(ID) {} + explicit ScopDetection(); /// @brief Get the RegionInfo stored in this pass. /// Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -47,6 +47,7 @@ struct isl_union_map; struct isl_space; struct isl_constraint; +struct isl_pw_multi_aff; namespace polly { @@ -493,7 +494,17 @@ /// This context contains information about the values the parameters /// can take and relations between different parameters. class Scop { - //===-------------------------------------------------------------------===// +public: + /// @brief Type to represent a pair of minimal/maximal access to an array. + using MinMaxAccessTy = std::pair; + + /// @brief Vector of minimal/maximal accesses to different arrays. + using MinMaxVectorTy = SmallVector; + + /// @brief Vector of minimal/maximal access vectors one for each alias group. + using MinMaxVectorVectorTy = SmallVector; + +private: Scop(const Scop &) LLVM_DELETED_FUNCTION; const Scop &operator=(const Scop &) LLVM_DELETED_FUNCTION; @@ -532,6 +543,21 @@ /// this scop and that need to be code generated as a run-time test. isl_set *AssumedContext; + /// @brief The set of minimal/maximal accesses for each alias group. + /// + /// When building runtime alias checks we look at all memory instructions and + /// build so called alias groups. Each group contains a set of accesses to + /// different base arrays which might alias with each other. However, between + /// alias groups there is no aliasing possible. + /// + /// In a program with int and float pointers annotated with tbaa information + /// we would probably generate two alias groups, one for the int pointers and + /// one for the float pointers. + /// + /// During code generation we will create a runtime alias check for each alias + /// group to ensure the SCoP is executed in an alias free environment. + MinMaxVectorVectorTy MinMaxAliasGroups; + /// Create the static control part with a region, max loop depth of this /// region and parameters used in this region. Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE, isl_ctx *ctx); @@ -563,9 +589,13 @@ // The scattering numbers SmallVectorImpl &Scatter, LoopInfo &LI); - /// Helper function for printing the Scop. + /// @name Helper function for printing the Scop. + /// + ///{ void printContext(raw_ostream &OS) const; void printStatements(raw_ostream &OS) const; + void printAliasAssumptions(raw_ostream &OS) const; + ///} friend class ScopInfo; @@ -661,6 +691,14 @@ /// to hold. void addAssumption(__isl_take isl_set *Set); + /// @brief Build all alias groups for this SCoP. + void buildAliasGroups(AliasAnalysis &AA); + + /// @brief Return all alias groups for this SCoP. + const MinMaxVectorVectorTy &getAliasGroups() const { + return MinMaxAliasGroups; + } + /// @brief Get an isl string representing the context. std::string getContextStr() const; Index: include/polly/Support/GICHelper.h =================================================================== --- include/polly/Support/GICHelper.h +++ include/polly/Support/GICHelper.h @@ -65,6 +65,12 @@ return OS; } +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + __isl_keep isl_pw_multi_aff *PMA) { + OS << polly::stringFromIslObj(PMA); + return OS; +} + /// @brief Return @p Prefix + @p Val->getName() + @p Suffix but Isl compatible. std::string getIslCompatibleName(std::string Prefix, const llvm::Value *Val, std::string Suffix); Index: lib/Analysis/ScopDetection.cpp =================================================================== --- lib/Analysis/ScopDetection.cpp +++ lib/Analysis/ScopDetection.cpp @@ -184,6 +184,23 @@ //===----------------------------------------------------------------------===// // ScopDetection. +ScopDetection::ScopDetection() : FunctionPass(ID) { + if (!PollyUseRuntimeAliasChecks) + return; + + if (PollyDelinearize) { + DEBUG(errs() << "WARNING: We disable runtime alias checks as " + "delinearization is enabled.\n"); + PollyUseRuntimeAliasChecks = false; + } + + if (AllowNonAffine) { + DEBUG(errs() << "WARNING: We disable runtime alias checks as non affine " + "accesses are enabled.\n"); + PollyUseRuntimeAliasChecks = false; + } +} + template inline bool ScopDetection::invalid(DetectionContext &Context, bool Assert, Args &&... Arguments) const { @@ -460,7 +477,7 @@ if (IntToPtrInst *Inst = dyn_cast(BaseValue)) return invalid(Context, /*Assert=*/true, Inst); - if (IgnoreAliasing) + if (PollyUseRuntimeAliasChecks || IgnoreAliasing) return true; // Check if the base pointer of the memory access does alias with Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -29,6 +29,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/RegionIterator.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Support/Debug.h" @@ -63,6 +64,13 @@ cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::cat(PollyCategory)); +bool polly::PollyUseRuntimeAliasChecks; +static cl::opt XPollyUseRuntimeAliasChecks( + "polly-use-runtime-alias-checks", + cl::desc("Use runtime alias checks to resolve possible aliasing."), + cl::location(PollyUseRuntimeAliasChecks), cl::Hidden, cl::ZeroOrMore, + cl::init(true), cl::cat(PollyCategory)); + /// Translate a 'const SCEV *' expression in an isl_pw_aff. struct SCEVAffinator : public SCEVVisitor { public: @@ -1128,6 +1136,104 @@ isl_set_gist_params(AssumedContext, isl_union_set_params(getDomains())); } +/// @brief Add the minimal/maximal access in @p Set to @p User. +static int buildMinMaxAccess(__isl_take isl_set *Set, void *User) { + Scop::MinMaxVectorTy *MinMaxAccesses = (Scop::MinMaxVectorTy *)User; + isl_pw_multi_aff *MinPMA, *MaxPMA; + isl_pw_aff *LastDimAff; + isl_aff *OneAff; + unsigned Pos; + + MinPMA = isl_set_lexmin_pw_multi_aff(isl_set_copy(Set)); + MaxPMA = isl_set_lexmax_pw_multi_aff(isl_set_copy(Set)); + + // Adjust the last dimension of the maximal access by one as we want to + // enclose the accessed memory region by MinPMA and MaxPMA. The pointer + // we test during code generation might now point after the end of the + // allocated array but we will never dereference it anyway. + assert(isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) && + "Assumed at least one output dimension"); + Pos = isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) - 1; + LastDimAff = isl_pw_multi_aff_get_pw_aff(MaxPMA, Pos); + OneAff = isl_aff_zero_on_domain( + isl_local_space_from_space(isl_pw_aff_get_domain_space(LastDimAff))); + OneAff = isl_aff_add_constant_si(OneAff, 1); + LastDimAff = isl_pw_aff_add(LastDimAff, isl_pw_aff_from_aff(OneAff)); + MaxPMA = isl_pw_multi_aff_set_pw_aff(MaxPMA, Pos, LastDimAff); + + MinMaxAccesses->push_back(std::make_pair(MinPMA, MaxPMA)); + + isl_set_free(Set); + return 0; +} + +void Scop::buildAliasGroups(AliasAnalysis &AA) { + // To create sound alias checks we perform the following steps: + // o) Use the alias analysis and an alias set tracker to build alias sets + // for all memory accesses inside the SCoP. + // o) For each alias set we then map the aliasing pointers back to the + // memory accesses we know, thus obtain groups of memory accesses which + // might alias. + // o) For each group with more then one base pointer we then compute minimal + // and maximal accesses to each array in this group. + using AliasGroupTy = SmallVector; + + AliasSetTracker AST(AA); + + DenseMap PtrToAcc; + for (ScopStmt *Stmt : *this) { + for (MemoryAccess *MA : *Stmt) { + if (MA->isScalar()) + continue; + Instruction *Acc = MA->getAccessInstruction(); + PtrToAcc[getPointerOperand(*Acc)] = MA; + AST.add(Acc); + } + } + + SmallVector AliasGroups; + for (AliasSet &AS : AST) { + if (AS.isMustAlias()) + continue; + AliasGroupTy AG; + for (auto PR : AS) + AG.push_back(PtrToAcc[PR.getValue()]); + assert(AG.size() > 1 && + "Alias groups should contain at least two accesses"); + AliasGroups.push_back(std::move(AG)); + } + + SmallPtrSet BaseValues; + for (auto I = AliasGroups.begin(); I != AliasGroups.end();) { + BaseValues.clear(); + for (MemoryAccess *MA : *I) + BaseValues.insert(MA->getBaseAddr()); + if (BaseValues.size() > 1) + I++; + else + I = AliasGroups.erase(I); + } + + for (AliasGroupTy &AG : AliasGroups) { + MinMaxVectorTy *MinMaxAccesses = new MinMaxVectorTy(); + MinMaxAccesses->reserve(AG.size()); + + isl_union_map *Accesses = isl_union_map_empty(getParamSpace()); + for (MemoryAccess *MA : AG) + Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation()); + Accesses = isl_union_map_intersect_domain(Accesses, getDomains()); + + isl_union_set *Locations = isl_union_map_range(Accesses); + Locations = isl_union_set_intersect_params(Locations, getAssumedContext()); + Locations = isl_union_set_coalesce(Locations); + Locations = isl_union_set_detect_equalities(Locations); + isl_union_set_foreach_set(Locations, buildMinMaxAccess, MinMaxAccesses); + isl_union_set_free(Locations); + + MinMaxAliasGroups.push_back(MinMaxAccesses); + } +} + Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution, isl_ctx *Context) : SE(&ScalarEvolution), R(tempScop.getMaxRegion()), @@ -1158,6 +1264,15 @@ // Free the statements; for (ScopStmt *Stmt : *this) delete Stmt; + + // Free the alias groups + for (MinMaxVectorTy *MinMaxAccesses : MinMaxAliasGroups) { + for (MinMaxAccessTy &MMA : *MinMaxAccesses) { + isl_pw_multi_aff_free(MMA.first); + isl_pw_multi_aff_free(MMA.second); + } + delete MinMaxAccesses; + } } std::string Scop::getContextStr() const { return stringFromIslObj(Context); } @@ -1219,6 +1334,20 @@ } } +void Scop::printAliasAssumptions(raw_ostream &OS) const { + OS.indent(4) << "Alias Groups (" << MinMaxAliasGroups.size() << "):\n"; + if (MinMaxAliasGroups.empty()) { + OS.indent(8) << "n/a\n"; + return; + } + for (MinMaxVectorTy *MinMaxAccesses : MinMaxAliasGroups) { + OS.indent(8) << "[["; + for (MinMaxAccessTy &MinMacAccess : *MinMaxAccesses) + OS << " <" << MinMacAccess.first << ", " << MinMacAccess.second << ">"; + OS << " ]]\n"; + } +} + void Scop::printStatements(raw_ostream &OS) const { OS << "Statements {\n"; @@ -1233,6 +1362,7 @@ << "\n"; OS.indent(4) << "Region: " << getNameStr() << "\n"; printContext(OS.indent(4)); + printAliasAssumptions(OS); printStatements(OS.indent(4)); } @@ -1419,11 +1549,13 @@ AU.addRequired(); AU.addRequired(); AU.addRequired(); + AU.addRequired(); AU.setPreservesAll(); } bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) { LoopInfo &LI = getAnalysis(); + AliasAnalysis &AA = getAnalysis(); ScalarEvolution &SE = getAnalysis(); TempScop *tempScop = getAnalysis().getTempScop(R); @@ -1441,6 +1573,9 @@ scop = new Scop(*tempScop, LI, SE, ctx); + if (PollyUseRuntimeAliasChecks) + scop->buildAliasGroups(AA); + return false; } @@ -1451,6 +1586,7 @@ INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops", "Polly - Create polyhedral description of Scops", false, false); +INITIALIZE_AG_DEPENDENCY(AliasAnalysis); INITIALIZE_PASS_DEPENDENCY(LoopInfo); INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); INITIALIZE_PASS_DEPENDENCY(ScalarEvolution); Index: lib/CodeGen/BlockGenerators.cpp =================================================================== --- lib/CodeGen/BlockGenerators.cpp +++ lib/CodeGen/BlockGenerators.cpp @@ -186,6 +186,7 @@ PWAccRel = isl_pw_multi_aff_pullback_pw_multi_aff(PWAccRel, PWSchedule); Expr = isl_ast_build_access_from_pw_multi_aff(Build, PWAccRel); + Expr = isl_ast_expr_address_of(Expr); return ExprBuilder->create(Expr); } Index: lib/CodeGen/IslAst.cpp =================================================================== --- lib/CodeGen/IslAst.cpp +++ lib/CodeGen/IslAst.cpp @@ -298,6 +298,34 @@ isl_pw_aff *Cond = isl_pw_aff_union_max(PwOne, PwZero); RunCondition = isl_ast_build_expr_from_pw_aff(Build, Cond); + + // Create the alias checks from the minimal/maximal accesses in each alias + // group. This operation is by construction quadratic in the number of + // elements in each alias group. + isl_ast_expr *NonAliasGroup, *MinExpr, *MaxExpr; + for (const Scop::MinMaxVectorTy *MinMaxAccesses : S->getAliasGroups()) { + auto AccEnd = MinMaxAccesses->end(); + for (auto AccIt0 = MinMaxAccesses->begin(); AccIt0 != AccEnd; ++AccIt0) { + for (auto AccIt1 = AccIt0 + 1; AccIt1 != AccEnd; ++AccIt1) { + MinExpr = + isl_ast_expr_address_of(isl_ast_build_access_from_pw_multi_aff( + Build, isl_pw_multi_aff_copy(AccIt0->first))); + MaxExpr = + isl_ast_expr_address_of(isl_ast_build_access_from_pw_multi_aff( + Build, isl_pw_multi_aff_copy(AccIt1->second))); + NonAliasGroup = isl_ast_expr_le(MaxExpr, MinExpr); + MinExpr = + isl_ast_expr_address_of(isl_ast_build_access_from_pw_multi_aff( + Build, isl_pw_multi_aff_copy(AccIt1->first))); + MaxExpr = + isl_ast_expr_address_of(isl_ast_build_access_from_pw_multi_aff( + Build, isl_pw_multi_aff_copy(AccIt0->second))); + NonAliasGroup = + isl_ast_expr_or(NonAliasGroup, isl_ast_expr_le(MaxExpr, MinExpr)); + RunCondition = isl_ast_expr_and(RunCondition, NonAliasGroup); + } + } + } } IslAst::IslAst(Scop *Scop, Dependences &D) : S(Scop) { Index: lib/CodeGen/IslCodeGeneration.cpp =================================================================== --- lib/CodeGen/IslCodeGeneration.cpp +++ lib/CodeGen/IslCodeGeneration.cpp @@ -591,7 +591,9 @@ Value *buildRTC(PollyIRBuilder &Builder, IslExprBuilder &ExprBuilder) { Builder.SetInsertPoint(Builder.GetInsertBlock()->getTerminator()); Value *RTC = ExprBuilder.create(AI->getRunCondition()); - return Builder.CreateIsNotNull(RTC); + if (!RTC->getType()->isIntegerTy(1)) + RTC = Builder.CreateIsNotNull(RTC); + return RTC; } bool runOnScop(Scop &S) { Index: lib/CodeGen/IslExprBuilder.cpp =================================================================== --- lib/CodeGen/IslExprBuilder.cpp +++ lib/CodeGen/IslExprBuilder.cpp @@ -91,7 +91,7 @@ return V; } -Value *IslExprBuilder::createOpAccess(isl_ast_expr *Expr) { +Value *IslExprBuilder::createAccessAddress(isl_ast_expr *Expr) { assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op && "isl ast expression not of type isl_ast_op"); assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_access && @@ -140,6 +140,12 @@ return Access; } +Value *IslExprBuilder::createOpAccess(isl_ast_expr *Expr) { + Value *Addr = createAccessAddress(Expr); + assert(Addr && "Could not create op access address"); + return Builder.CreateLoad(Addr, Addr->getName() + ".load"); +} + Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) { Value *LHS, *RHS, *Res; Type *MaxType; @@ -264,35 +270,38 @@ LHS = create(isl_ast_expr_get_op_arg(Expr, 0)); RHS = create(isl_ast_expr_get_op_arg(Expr, 1)); - Type *MaxType = LHS->getType(); - MaxType = getWidestType(MaxType, RHS->getType()); + bool IsPtrType = LHS->getType()->isPointerTy(); + assert((!IsPtrType || RHS->getType()->isPointerTy()) && + "Both ICmp operators should be pointer types or none of them"); - if (MaxType != RHS->getType()) - RHS = Builder.CreateSExt(RHS, MaxType); + if (!IsPtrType) { + Type *MaxType = LHS->getType(); + MaxType = getWidestType(MaxType, RHS->getType()); - if (MaxType != LHS->getType()) - LHS = Builder.CreateSExt(LHS, MaxType); + if (MaxType != RHS->getType()) + RHS = Builder.CreateSExt(RHS, MaxType); - switch (isl_ast_expr_get_op_type(Expr)) { - default: - llvm_unreachable("Unsupported ICmp isl ast expression"); - case isl_ast_op_eq: - Res = Builder.CreateICmpEQ(LHS, RHS); - break; - case isl_ast_op_le: - Res = Builder.CreateICmpSLE(LHS, RHS); - break; - case isl_ast_op_lt: - Res = Builder.CreateICmpSLT(LHS, RHS); - break; - case isl_ast_op_ge: - Res = Builder.CreateICmpSGE(LHS, RHS); - break; - case isl_ast_op_gt: - Res = Builder.CreateICmpSGT(LHS, RHS); - break; + if (MaxType != LHS->getType()) + LHS = Builder.CreateSExt(LHS, MaxType); } + isl_ast_op_type OpType = isl_ast_expr_get_op_type(Expr); + assert(OpType >= isl_ast_op_eq && OpType <= isl_ast_op_gt && + "Unsupported ICmp isl ast expression"); + assert(isl_ast_op_eq + 4 == isl_ast_op_gt && + "Isl ast op type interface changed"); + + CmpInst::Predicate Predicates[5][2] = { + {CmpInst::ICMP_EQ, CmpInst::ICMP_EQ}, + {CmpInst::ICMP_SLE, CmpInst::ICMP_ULE}, + {CmpInst::ICMP_SLT, CmpInst::ICMP_ULT}, + {CmpInst::ICMP_SGE, CmpInst::ICMP_UGE}, + {CmpInst::ICMP_SGT, CmpInst::ICMP_UGT}, + }; + + Res = Builder.CreateICmp(Predicates[OpType - isl_ast_op_eq][IsPtrType], LHS, + RHS); + isl_ast_expr_free(Expr); return Res; } @@ -324,8 +333,10 @@ // // TODO: Document in isl itself, that the unconditionally evaluating the // second part of '||' or '&&' expressions is safe. - assert(LHS->getType() == Builder.getInt1Ty() && "Expected i1 type"); - assert(RHS->getType() == Builder.getInt1Ty() && "Expected i1 type"); + if (!LHS->getType()->isIntegerTy(1)) + LHS = Builder.CreateIsNotNull(LHS); + if (!RHS->getType()->isIntegerTy(1)) + RHS = Builder.CreateIsNotNull(RHS); switch (OpType) { default: @@ -379,11 +390,31 @@ case isl_ast_op_ge: case isl_ast_op_gt: return createOpICmp(Expr); + case isl_ast_op_address_of: + return createOpAddressOf(Expr); } llvm_unreachable("Unsupported isl_ast_expr_op kind."); } +Value *IslExprBuilder::createOpAddressOf(__isl_take isl_ast_expr *Expr) { + assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op && + "Expected an isl_ast_expr_op expression."); + assert(isl_ast_expr_get_op_n_arg(Expr) == 1 && "Address of should be unary."); + + isl_ast_expr *Op = isl_ast_expr_get_op_arg(Expr, 0); + assert(isl_ast_expr_get_type(Op) == isl_ast_expr_op && + "Expected address of operator to be an isl_ast_expr_op expression."); + assert(isl_ast_expr_get_op_type(Op) == isl_ast_op_access && + "Expected address of operator to be an access expression."); + + Value *V = createAccessAddress(Op); + + isl_ast_expr_free(Expr); + + return V; +} + Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) { assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_id && "Expression not of type isl_ast_expr_ident"); Index: test/Isl/Ast/alias_simple_1.ll =================================================================== --- /dev/null +++ test/Isl/Ast/alias_simple_1.ll @@ -0,0 +1,58 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze < %s | FileCheck %s --check-prefix=NOAA +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -basicaa < %s | FileCheck %s --check-prefix=BASI +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -tbaa < %s | FileCheck %s --check-prefix=TBAA +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -scev-aa < %s | FileCheck %s --check-prefix=SCEV +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -globalsmodref-aa < %s | FileCheck %s --check-prefix=GLOB +; +; int A[1024]; +; +; +; void jd(float *B, int N) { +; for (int i = 0; i < N; i++) +; A[i] = B[i]; +; } +; +; NOAA: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; BASI: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; TBAA: if (1) +; SCEV: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; GLOB: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +@A = common global [1024 x i32] zeroinitializer, align 16 + +define void @jd(float* nocapture readonly %B, i32 %N) { +entry: + %cmp6 = icmp sgt i32 %N, 0 + br i1 %cmp6, label %for.body.preheader, label %for.end + +for.body.preheader: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.preheader, %for.body + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ] + %arrayidx = getelementptr inbounds float* %B, i64 %indvars.iv + %tmp = load float* %arrayidx, align 4, !tbaa !1 + %conv = fptosi float %tmp to i32 + %arrayidx2 = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv + store i32 %conv, i32* %arrayidx2, align 4, !tbaa !5 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %lftr.wideiv1 = trunc i64 %indvars.iv.next to i32 + %exitcond2 = icmp eq i32 %lftr.wideiv1, %N + br i1 %exitcond2, label %for.end.loopexit, label %for.body + +for.end.loopexit: ; preds = %for.body + br label %for.end + +for.end: ; preds = %for.end.loopexit, %entry + ret void +} + +!0 = metadata !{metadata !""} +!1 = metadata !{metadata !2, metadata !2, i64 0} +!2 = metadata !{metadata !"float", metadata !3, i64 0} +!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0} +!4 = metadata !{metadata !"Simple C/C++ TBAA"} +!5 = metadata !{metadata !6, metadata !6, i64 0} +!6 = metadata !{metadata !"int", metadata !3, i64 0} Index: test/Isl/Ast/alias_simple_2.ll =================================================================== --- /dev/null +++ test/Isl/Ast/alias_simple_2.ll @@ -0,0 +1,58 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze < %s | FileCheck %s --check-prefix=NOAA +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -basicaa < %s | FileCheck %s --check-prefix=BASI +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -tbaa < %s | FileCheck %s --check-prefix=TBAA +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -scev-aa < %s | FileCheck %s --check-prefix=SCEV +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -globalsmodref-aa < %s | FileCheck %s --check-prefix=GLOB +; +; int A[1024], B[1024]; +; +; +; void jd(int N) { +; for (int i = 0; i < N; i++) +; A[i] = B[i]; +; } +; +; NOAA: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; BASI: if (1) +; TBAA: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; SCEV: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; GLOB: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +@A = common global [1024 x i32] zeroinitializer, align 16 +@B = common global [1024 x i32] zeroinitializer, align 16 + +define void @jd(i32 %N) { +entry: + %cmp6 = icmp sgt i32 %N, 0 + br i1 %cmp6, label %for.body.preheader, label %for.end + +for.body.preheader: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.preheader, %for.body + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ] + %arrayidx = getelementptr inbounds [1024 x i32]* @B, i64 0, i64 %indvars.iv + %tmp = load i32* %arrayidx, align 4, !tbaa !5 + %arrayidx2 = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv + store i32 %tmp, i32* %arrayidx2, align 4, !tbaa !5 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %lftr.wideiv1 = trunc i64 %indvars.iv.next to i32 + %exitcond2 = icmp eq i32 %lftr.wideiv1, %N + br i1 %exitcond2, label %for.end.loopexit, label %for.body + +for.end.loopexit: ; preds = %for.body + br label %for.end + +for.end: ; preds = %for.end.loopexit, %entry + ret void +} + +!0 = metadata !{metadata !""} +!1 = metadata !{metadata !2, metadata !2, i64 0} +!2 = metadata !{metadata !"float", metadata !3, i64 0} +!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0} +!4 = metadata !{metadata !"Simple C/C++ TBAA"} +!5 = metadata !{metadata !6, metadata !6, i64 0} +!6 = metadata !{metadata !"int", metadata !3, i64 0} Index: test/Isl/Ast/alias_simple_3.ll =================================================================== --- /dev/null +++ test/Isl/Ast/alias_simple_3.ll @@ -0,0 +1,59 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze < %s | FileCheck %s --check-prefix=NOAA +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -basicaa < %s | FileCheck %s --check-prefix=BASI +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -tbaa < %s | FileCheck %s --check-prefix=TBAA +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -scev-aa < %s | FileCheck %s --check-prefix=SCEV +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze -globalsmodref-aa < %s | FileCheck %s --check-prefix=GLOB +; +; int A[1024]; +; float B[1024]; +; +; void jd(int N) { +; for (int i = 0; i < N; i++) +; A[i] = B[i]; +; } +; +; NOAA: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; BASI: if (1) +; TBAA: if (1) +; SCEV: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; GLOB: if (1 && (&MemRef_A[N] <= &MemRef_B[0] || &MemRef_B[N] <= &MemRef_A[0])) +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +@A = common global [1024 x i32] zeroinitializer, align 16 +@B = common global [1024 x float] zeroinitializer, align 16 + +define void @jd(i32 %N) { +entry: + %cmp6 = icmp sgt i32 %N, 0 + br i1 %cmp6, label %for.body.preheader, label %for.end + +for.body.preheader: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.preheader, %for.body + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ] + %arrayidx = getelementptr inbounds [1024 x float]* @B, i64 0, i64 %indvars.iv + %tmp = load float* %arrayidx, align 4, !tbaa !1 + %conv = fptosi float %tmp to i32 + %arrayidx2 = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv + store i32 %conv, i32* %arrayidx2, align 4, !tbaa !5 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %lftr.wideiv1 = trunc i64 %indvars.iv.next to i32 + %exitcond2 = icmp eq i32 %lftr.wideiv1, %N + br i1 %exitcond2, label %for.end.loopexit, label %for.body + +for.end.loopexit: ; preds = %for.body + br label %for.end + +for.end: ; preds = %for.end.loopexit, %entry + ret void +} + +!0 = metadata !{metadata !""} +!1 = metadata !{metadata !2, metadata !2, i64 0} +!2 = metadata !{metadata !"float", metadata !3, i64 0} +!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0} +!4 = metadata !{metadata !"Simple C/C++ TBAA"} +!5 = metadata !{metadata !6, metadata !6, i64 0} +!6 = metadata !{metadata !"int", metadata !3, i64 0} Index: test/Isl/Ast/aliasing_multiple_alias_groups.ll =================================================================== --- /dev/null +++ test/Isl/Ast/aliasing_multiple_alias_groups.ll @@ -0,0 +1,54 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-ast -analyze < %s | FileCheck %s --check-prefix=NOAA +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-ast -analyze -tbaa < %s | FileCheck %s --check-prefix=TBAA +; +; void jd(int *Int0, int *Int1, float *Float0, float *Float1) { +; for (int i = 0; i < 1024; i++) { +; Int0[i] = Int1[i]; +; Float0[i] = Float1[i]; +; } +; } +; +; NOAA: if (1 && ( +; NOAA-DAG: &MemRef_Float0[1024] <= &MemRef_Int0[0] || &MemRef_Int0[1024] <= &MemRef_Float0[0] +; NOAA-DAG: &MemRef_Float1[1024] <= &MemRef_Int0[0] || &MemRef_Int0[1024] <= &MemRef_Float1[0] +; NOAA-DAG: &MemRef_Int1[1024] <= &MemRef_Int0[0] || &MemRef_Int0[1024] <= &MemRef_Int1[0] +; NOAA-DAG: &MemRef_Float1[1024] <= &MemRef_Float0[0] || &MemRef_Float0[1024] <= &MemRef_Float1[0] +; NOAA-DAG: &MemRef_Int1[1024] <= &MemRef_Float0[0] || &MemRef_Float0[1024] <= &MemRef_Int1[0] +; NOAA-DAG: &MemRef_Int1[1024] <= &MemRef_Float1[0] || &MemRef_Float1[1024] <= &MemRef_Int1[0] +; NOAA: )) +; +; TBAA: if (1 && ( +; TBAA-DAG: &MemRef_Int0[1024] <= &MemRef_Int1[0] || &MemRef_Int1[1024] <= &MemRef_Int0[0] +; TBAA-DAG: &MemRef_Float1[1024] <= &MemRef_Float0[0] || &MemRef_Float0[1024] <= &MemRef_Float1[0] +; TBAA: )) +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* nocapture %Int0, i32* nocapture readonly %Int1, float* nocapture %Float0, float* nocapture readonly %Float1) { +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] + %arrayidx = getelementptr inbounds i32* %Int1, i64 %indvars.iv + %tmp = load i32* %arrayidx, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds i32* %Int0, i64 %indvars.iv + store i32 %tmp, i32* %arrayidx2, align 4, !tbaa !0 + %arrayidx4 = getelementptr inbounds float* %Float1, i64 %indvars.iv + %tmp1 = load float* %arrayidx4, align 4, !tbaa !4 + %arrayidx6 = getelementptr inbounds float* %Float0, i64 %indvars.iv + store float %tmp1, float* %arrayidx6, align 4, !tbaa !4 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %exitcond = icmp eq i64 %indvars.iv.next, 1024 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret void +} + +!0 = metadata !{metadata !1, metadata !1, i64 0} +!1 = metadata !{metadata !"int", metadata !2, i64 0} +!2 = metadata !{metadata !"omnipotent char", metadata !3, i64 0} +!3 = metadata !{metadata !"Simple C/C++ TBAA"} +!4 = metadata !{metadata !5, metadata !5, i64 0} +!5 = metadata !{metadata !"float", metadata !2, i64 0} Index: test/Isl/Ast/aliasing_parametric_simple_1.ll =================================================================== --- /dev/null +++ test/Isl/Ast/aliasing_parametric_simple_1.ll @@ -0,0 +1,39 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze %s | FileCheck %s +; +; void jd(int *A, int *B, int c) { +; for (int i = 0; i < 1024; i++) +; A[i] = B[c]; +; } +; +; CHECK: if (1 && (&MemRef_A[1024] <= &MemRef_B[c] || &MemRef_B[c + 1] <= &MemRef_A[0])) +; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1) +; CHECK: Stmt_for_body(c1); +; CHECK: else +; CHECK: /* original code */ +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* %A, i32* %B, i32 %c) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1024 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %idxprom = sext i32 %c to i64 + %arrayidx = getelementptr inbounds i32* %B, i64 %idxprom + %tmp = load i32* %arrayidx, align 4 + %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv + store i32 %tmp, i32* %arrayidx2, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} Index: test/Isl/Ast/aliasing_parametric_simple_2.ll =================================================================== --- /dev/null +++ test/Isl/Ast/aliasing_parametric_simple_2.ll @@ -0,0 +1,43 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks -polly-ast -analyze < %s | FileCheck %s +; +; void jd(int *A, int *B, int c) { +; for (int i = 0; i < 1024; i++) +; A[i] = B[c - 10] + B[5]; +; } +; +; CHECK: if (1 && (&MemRef_A[1024] <= &MemRef_B[c >= 15 ? 5 : c - 10] || &MemRef_B[c <= 15 ? 6 : c - 9] <= &MemRef_A[0])) +; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1) +; CHECK: Stmt_for_body(c1); +; CHECK: else +; CHECK: /* original code */ +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* %A, i32* %B, i32 %c) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1024 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %sub = add nsw i32 %c, -10 + %idxprom = sext i32 %sub to i64 + %arrayidx = getelementptr inbounds i32* %B, i64 %idxprom + %tmp = load i32* %arrayidx, align 4 + %arrayidx1 = getelementptr inbounds i32* %B, i64 5 + %tmp1 = load i32* %arrayidx1, align 4 + %add = add nsw i32 %tmp, %tmp1 + %arrayidx3 = getelementptr inbounds i32* %A, i64 %indvars.iv + store i32 %add, i32* %arrayidx3, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} Index: test/Isl/CodeGen/MemAccess/codegen_simple_float.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/MemAccess/codegen_simple_float.ll @@ -0,0 +1,41 @@ +;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-codegen-isl -instnamer < %s -S | FileCheck %s +; +;float A[100]; +; +;int codegen_simple () { +; for (int i = 0; i < 12; i++) +; A[13] = A[i] + A[i-1]; +; +; return 0; +;} +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" + +@A = common global [100 x float] zeroinitializer, align 4 + +define i32 @codegen_simple() nounwind { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %tmp1 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] + %tmp = add i32 %tmp1, -1 + %arrayidx4 = getelementptr [100 x float]* @A, i32 0, i32 %tmp + %arrayidx = getelementptr [100 x float]* @A, i32 0, i32 %tmp1 + %exitcond = icmp ne i32 %tmp1, 12 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %tmp2 = load float* %arrayidx, align 4 + %tmp5 = load float* %arrayidx4, align 4 + %add = fadd float %tmp2, %tmp5 + store float %add, float* getelementptr inbounds ([100 x float]* @A, i32 0, i32 13), align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %inc = add nsw i32 %tmp1, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret i32 0 +} +; CHECK: load float* getelementptr inbounds ([100 x float]* @A, i64 0, i64 0) Index: test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll @@ -0,0 +1,71 @@ +;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withconst -polly-codegen-isl < %s -S | FileCheck -check-prefix=WITHCONST %s +;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withoutconst -polly-codegen-isl < %s -S | FileCheck -check-prefix=WITHOUTCONST %s +;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withconst -polly-codegen-isl -polly-codegen-scev < %s -S | FileCheck -check-prefix=WITHCONST %s +;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withoutconst -polly-codegen-isl -polly-codegen-scev < %s -S | FileCheck -check-prefix=WITHOUTCONST %s +; +;float A[1040]; +; +;int codegen_simple_md() { +; for (int i = 0; i < 32; ++i) +; for (int j = 0; j < 32; ++j) +; A[32*i+j] = 100; +;} +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" + +@A = common global [1040 x float] zeroinitializer, align 4 + +define void @codegen_simple_md() nounwind { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc4, %entry + %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ] + %exitcond1 = icmp ne i32 %i.0, 32 + br i1 %exitcond1, label %for.body, label %for.end6 + +for.body: ; preds = %for.cond + br label %for.cond1 + +for.cond1: ; preds = %for.inc, %for.body + %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ] + %exitcond = icmp ne i32 %j.0, 32 + br i1 %exitcond, label %for.body3, label %for.end + +for.body3: ; preds = %for.cond1 + %mul = shl nsw i32 %i.0, 5 + %add = add nsw i32 %mul, %j.0 + %arrayidx = getelementptr inbounds [1040 x float]* @A, i32 0, i32 %add + store float 100.0, float* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body3 + %inc = add nsw i32 %j.0, 1 + br label %for.cond1 + +for.end: ; preds = %for.cond1 + br label %for.inc4 + +for.inc4: ; preds = %for.end + %inc5 = add nsw i32 %i.0, 1 + br label %for.cond + +for.end6: ; preds = %for.cond + ret void +} + +; WITHCONST: %[[IVOut:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ] +; WITHCONST: %[[IVIn:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ] +; WITHCONST: %[[MUL1:[._a-zA-Z0-9]+]] = mul nsw i64 16, %[[IVOut]] +; WITHCONST: %[[MUL2:[._a-zA-Z0-9]+]] = mul nsw i64 2, %[[IVIn]] +; WITHCONST: %[[SUM1:[._a-zA-Z0-9]+]] = add nsw i64 %[[MUL1]], %[[MUL2]] +; WITHCONST: %[[SUM2:[._a-zA-Z0-9]+]] = add nsw i64 %[[SUM1]], 5 +; WITHCONST: %[[ACC:[._a-zA-Z0-9]*]] = getelementptr [1040 x float]* @A, i64 0, i64 %[[SUM2]] +; WITHCONST: store float 1.000000e+02, float* %[[ACC]] + +; WITHOUTCONST: %[[IVOut:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ] +; WITHOUTCONST: %[[IVIn:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ] +; WITHOUTCONST: %[[MUL1:[._a-zA-Z0-9]+]] = mul nsw i64 16, %[[IVOut]] +; WITHOUTCONST: %[[MUL2:[._a-zA-Z0-9]+]] = mul nsw i64 2, %[[IVIn]] +; WITHOUTCONST: %[[SUM1:[._a-zA-Z0-9]+]] = add nsw i64 %[[MUL1]], %[[MUL2]] +; WITHOUTCONST: %[[ACC:[._a-zA-Z0-9]*]] = getelementptr [1040 x float]* @A, i64 0, i64 %[[SUM1]] +; WITHOUTCONST: store float 1.000000e+02, float* %[[ACC]] Index: test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop =================================================================== --- /dev/null +++ test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop @@ -0,0 +1,28 @@ +{ + "context" : "{ : }", + "name" : "for.cond => for.end14", + "statements" : [ + { + "accesses" : [ + { + "kind" : "write", + "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }" + } + ], + "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }", + "name" : "Stmt_for_body", + "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }" + }, + { + "accesses" : [ + { + "kind" : "write", + "relation" : "{ Stmt_for_body7[i0] -> MemRef_B[i0] }" + } + ], + "domain" : "{ Stmt_for_body7[i0] : i0 >= 0 and i0 <= 11 }", + "name" : "Stmt_for_body7", + "schedule" : "{ Stmt_for_body7[i0] -> scattering[0, i0, 0] }" + } + ] +} Index: test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop.transformed =================================================================== --- /dev/null +++ test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop.transformed @@ -0,0 +1,28 @@ +{ + "context" : "{ : }", + "name" : "for.cond => for.end14", + "statements" : [ + { + "accesses" : [ + { + "kind" : "write", + "relation" : "{ Stmt_for_body[i0] -> MemRef_A[0] }" + } + ], + "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }", + "name" : "Stmt_for_body", + "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }" + }, + { + "accesses" : [ + { + "kind" : "write", + "relation" : "{ Stmt_for_body7[i0] -> MemRef_B[0] }" + } + ], + "domain" : "{ Stmt_for_body7[i0] : i0 >= 0 and i0 <= 11 }", + "name" : "Stmt_for_body7", + "schedule" : "{ Stmt_for_body7[i0] -> scattering[0, i0, 0] }" + } + ] +} Index: test/Isl/CodeGen/MemAccess/simple_analyze.ll =================================================================== --- test/Isl/CodeGen/MemAccess/simple_analyze.ll +++ test/Isl/CodeGen/MemAccess/simple_analyze.ll @@ -43,5 +43,5 @@ for.end14: ; preds = %for.cond4 ret i32 0 } -; CHECK: New access function '{ Stmt_for_body7[i0] -> MemRef_B[0] }'detected in JSCOP file -; CHECK: New access function '{ Stmt_for_body[i0] -> MemRef_A[0] }'detected in JSCOP file +; CHECK-DAG: New access function '{ Stmt_for_body7[i0] -> MemRef_B[0] }'detected in JSCOP file +; CHECK-DAG: New access function '{ Stmt_for_body[i0] -> MemRef_A[0] }'detected in JSCOP file Index: test/Isl/CodeGen/aliasing_parametric_simple_1.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/aliasing_parametric_simple_1.ll @@ -0,0 +1,45 @@ +; RUN: opt %loadPolly -polly-codegen-isl -polly-use-runtime-alias-checks -S < %s | FileCheck %s +; +; void jd(int *A, int *B, int c) { +; for (int i = 0; i < 1024; i++) +; A[i] = B[c]; +; } +; +; CHECK: %[[AMax:[._a-zA-Z0-9]*]] = getelementptr i32* %A, i64 1024 +; CHECK: %[[BMin:[._a-zA-Z0-9]*]] = getelementptr i32* %B, i32 %c +; CHECK: %[[AltB:[._a-zA-Z0-9]*]] = icmp ule i32* %[[AMax]], %[[BMin]] +; CHECK: %[[Cext:[._a-zA-Z0-9]*]] = sext i32 %c to i64 +; CHECK: %[[Cp1:[._a-zA-Z0-9]*]] = add nsw i64 %[[Cext]], 1 +; CHECK: %[[BMax:[._a-zA-Z0-9]*]] = getelementptr i32* %B, i64 %[[Cp1]] +; CHECK: %[[AMin:[._a-zA-Z0-9]*]] = getelementptr i32* %A, i64 0 +; CHECK: %[[BltA:[._a-zA-Z0-9]*]] = icmp ule i32* %[[BMax]], %[[AMin]] +; CHECK: %[[NoAlias:[._a-zA-Z0-9]*]] = or i1 %[[AltB]], %[[BltA]] +; CHECK: %[[RTC:[._a-zA-Z0-9]*]] = and i1 true, %[[NoAlias]] +; CHECK: br i1 %[[RTC]], label %polly.start, label %for.cond +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* %A, i32* %B, i32 %c) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1024 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %idxprom = sext i32 %c to i64 + %arrayidx = getelementptr inbounds i32* %B, i64 %idxprom + %tmp = load i32* %arrayidx, align 4 + %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv + store i32 %tmp, i32* %arrayidx2, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} Index: test/Isl/CodeGen/aliasing_parametric_simple_2.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/aliasing_parametric_simple_2.ll @@ -0,0 +1,57 @@ +; RUN: opt %loadPolly -polly-codegen-isl -polly-use-runtime-alias-checks -S < %s | FileCheck %s +; +; void jd(int *A, int *B, int c) { +; for (int i = 0; i < 1024; i++) +; A[i] = B[c - 10] + B[5]; +; } +; +; CHECK: %[[AMax:[._a-zA-Z0-9]*]] = getelementptr i32* %A, i64 1024 +; CHECK: %[[m0:[._a-zA-Z0-9]*]] = sext i32 %c to i64 +; CHECK: %[[m1:[._a-zA-Z0-9]*]] = icmp sge i64 %[[m0]], 15 +; CHECK: %[[m2:[._a-zA-Z0-9]*]] = sext i32 %c to i64 +; CHECK: %[[m3:[._a-zA-Z0-9]*]] = sub nsw i64 %[[m2]], 10 +; CHECK: %[[m4:[._a-zA-Z0-9]*]] = select i1 %[[m1]], i64 5, i64 %[[m3]] +; CHECK: %[[BMin:[._a-zA-Z0-9]*]] = getelementptr i32* %B, i64 %[[m4]] +; CHECK: %[[AltB:[._a-zA-Z0-9]*]] = icmp ule i32* %[[AMax]], %[[BMin]] +; CHECK: %[[M0:[._a-zA-Z0-9]*]] = sext i32 %c to i64 +; CHECK: %[[M1:[._a-zA-Z0-9]*]] = icmp sle i64 %[[M0]], 15 +; CHECK: %[[M2:[._a-zA-Z0-9]*]] = sext i32 %c to i64 +; CHECK: %[[M3:[._a-zA-Z0-9]*]] = sub nsw i64 %[[M2]], 9 +; CHECK: %[[M4:[._a-zA-Z0-9]*]] = select i1 %[[M1]], i64 6, i64 %[[M3]] +; CHECK: %[[BMax:[._a-zA-Z0-9]*]] = getelementptr i32* %B, i64 %[[M4]] +; CHECK: %[[AMin:[._a-zA-Z0-9]*]] = getelementptr i32* %A, i64 0 +; CHECK: %[[BltA:[._a-zA-Z0-9]*]] = icmp ule i32* %[[BMax]], %[[AMin]] +; CHECK: %[[NoAlias:[._a-zA-Z0-9]*]] = or i1 %[[AltB]], %[[BltA]] +; CHECK: %[[RTC:[._a-zA-Z0-9]*]] = and i1 true, %[[NoAlias]] +; CHECK: br i1 %[[RTC]], label %polly.start, label %for.cond +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* %A, i32* %B, i32 %c) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1024 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %sub = add nsw i32 %c, -10 + %idxprom = sext i32 %sub to i64 + %arrayidx = getelementptr inbounds i32* %B, i64 %idxprom + %tmp = load i32* %arrayidx, align 4 + %arrayidx1 = getelementptr inbounds i32* %B, i64 5 + %tmp1 = load i32* %arrayidx1, align 4 + %add = add nsw i32 %tmp, %tmp1 + %arrayidx3 = getelementptr inbounds i32* %A, i64 %indvars.iv + store i32 %add, i32* %arrayidx3, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} Index: test/ScopDetect/aliasing_parametric_simple_1.ll =================================================================== --- /dev/null +++ test/ScopDetect/aliasing_parametric_simple_1.ll @@ -0,0 +1,35 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-detect -analyze < %s | FileCheck %s +; +; CHECK: Valid Region for Scop: +; +; void jd(int *A, int *B, int c) { +; for (int i = 0; i < 1024; i++) +; A[i] = B[c]; +; } +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* %A, i32* %B, i32 %c) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1024 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %idxprom = sext i32 %c to i64 + %arrayidx = getelementptr inbounds i32* %B, i64 %idxprom + %tmp = load i32* %arrayidx, align 4 + %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv + store i32 %tmp, i32* %arrayidx2, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} Index: test/ScopDetect/aliasing_parametric_simple_2.ll =================================================================== --- /dev/null +++ test/ScopDetect/aliasing_parametric_simple_2.ll @@ -0,0 +1,39 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-detect -analyze < %s | FileCheck %s +; +; CHECK: Valid Region for Scop: +; +; void jd(int *A, int *B, int c) { +; for (int i = 0; i < 1024; i++) +; A[i] = B[c - 10] + B[5]; +; } +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* %A, i32* %B, i32 %c) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1024 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %sub = add nsw i32 %c, -10 + %idxprom = sext i32 %sub to i64 + %arrayidx = getelementptr inbounds i32* %B, i64 %idxprom + %tmp = load i32* %arrayidx, align 4 + %arrayidx1 = getelementptr inbounds i32* %B, i64 5 + %tmp1 = load i32* %arrayidx1, align 4 + %add = add nsw i32 %tmp, %tmp1 + %arrayidx3 = getelementptr inbounds i32* %A, i64 %indvars.iv + store i32 %add, i32* %arrayidx3, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} Index: test/ScopDetect/aliasing_simple_1.ll =================================================================== --- /dev/null +++ test/ScopDetect/aliasing_simple_1.ll @@ -0,0 +1,33 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-detect -analyze < %s | FileCheck %s +; +; CHECK: Valid Region for Scop: +; +; void jd(int *A, int *B) { +; for (int i = 0; i < 1024; i++) +; A[i] = B[0]; +; } +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* %A, i32* %B) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1024 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %tmp = load i32* %B, align 4 + %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv + store i32 %tmp, i32* %arrayidx2, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} Index: test/ScopDetect/aliasing_simple_2.ll =================================================================== --- /dev/null +++ test/ScopDetect/aliasing_simple_2.ll @@ -0,0 +1,36 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-detect -analyze < %s | FileCheck %s +; +; CHECK: Valid Region for Scop: +; +; void jd(int *A, int *B) { +; for (int i = 0; i < 1024; i++) +; A[i] = B[0] + B[1023]; +; } +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* %A, i32* %B) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1024 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %tmp = load i32* %B, align 4 + %arrayidx1 = getelementptr inbounds i32* %B, i64 1023 + %tmp1 = load i32* %arrayidx1, align 4 + %add = add nsw i32 %tmp, %tmp1 + %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv + store i32 %add, i32* %arrayidx2, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} Index: test/ScopDetectionDiagnostics/ReportAlias-01.ll =================================================================== --- test/ScopDetectionDiagnostics/ReportAlias-01.ll +++ test/ScopDetectionDiagnostics/ReportAlias-01.ll @@ -1,4 +1,4 @@ -; RUN: opt %loadPolly -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -analyze < %s 2>&1| FileCheck %s +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=false -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -analyze < %s 2>&1| FileCheck %s ;void f(int A[], int B[]) { ; for (int i=0; i<42; i++) Index: test/ScopInfo/Alias-0.ll =================================================================== --- test/ScopInfo/Alias-0.ll +++ test/ScopInfo/Alias-0.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA ; REQUIRES: asserts target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -32,4 +33,5 @@ declare i32 @rnd(...) -; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias +; RTA: 1 polly-detect - Number of regions that a valid part of Scop +; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias Index: test/ScopInfo/Alias-1.ll =================================================================== --- test/ScopInfo/Alias-1.ll +++ test/ScopInfo/Alias-1.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA ; REQUIRES: asserts target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -33,4 +34,5 @@ declare i32 @rnd(...) -; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias +; RTA: 1 polly-detect - Number of regions that a valid part of Scop +; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias Index: test/ScopInfo/Alias-2.ll =================================================================== --- test/ScopInfo/Alias-2.ll +++ test/ScopInfo/Alias-2.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA ; REQUIRES: asserts target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -31,4 +32,5 @@ ret void } -; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias +; RTA: 1 polly-detect - Number of regions that a valid part of Scop +; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias Index: test/ScopInfo/Alias-3.ll =================================================================== --- test/ScopInfo/Alias-3.ll +++ test/ScopInfo/Alias-3.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA ; REQUIRES: asserts target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -24,4 +25,5 @@ } -; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias +; RTA: 1 polly-detect - Number of regions that a valid part of Scop +; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias Index: test/ScopInfo/Alias-4.ll =================================================================== --- test/ScopInfo/Alias-4.ll +++ test/ScopInfo/Alias-4.ll @@ -1,4 +1,5 @@ -; RUN: opt %loadPolly -basicaa -polly-analyze-ir -analyze < %s -stats 2>&1 | not FileCheck %s +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA +; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA ; REQUIRES: asserts target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -24,4 +25,5 @@ } -; CHECK: Found base address alias +; RTA: 1 polly-detect - Number of regions that a valid part of Scop +; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias Index: test/ScopInfo/aliasing_multiple_alias_groups.ll =================================================================== --- /dev/null +++ test/ScopInfo/aliasing_multiple_alias_groups.ll @@ -0,0 +1,52 @@ +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-scops -analyze < %s | FileCheck %s --check-prefix=NOAA +; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-scops -analyze -tbaa < %s | FileCheck %s --check-prefix=TBAA +; +; void jd(int *Int0, int *Int1, float *Float0, float *Float1) { +; for (int i = 0; i < 1024; i++) { +; Int0[i] = Int1[i]; +; Float0[i] = Float1[i]; +; } +; } +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @jd(i32* nocapture %Int0, i32* nocapture readonly %Int1, float* nocapture %Float0, float* nocapture readonly %Float1) { +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] + %arrayidx = getelementptr inbounds i32* %Int1, i64 %indvars.iv + %tmp = load i32* %arrayidx, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds i32* %Int0, i64 %indvars.iv + store i32 %tmp, i32* %arrayidx2, align 4, !tbaa !0 + %arrayidx4 = getelementptr inbounds float* %Float1, i64 %indvars.iv + %tmp1 = load float* %arrayidx4, align 4, !tbaa !4 + %arrayidx6 = getelementptr inbounds float* %Float0, i64 %indvars.iv + store float %tmp1, float* %arrayidx6, align 4, !tbaa !4 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %exitcond = icmp eq i64 %indvars.iv.next, 1024 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret void +} + +!0 = metadata !{metadata !1, metadata !1, i64 0} +!1 = metadata !{metadata !"int", metadata !2, i64 0} +!2 = metadata !{metadata !"omnipotent char", metadata !3, i64 0} +!3 = metadata !{metadata !"Simple C/C++ TBAA"} +!4 = metadata !{metadata !5, metadata !5, i64 0} +!5 = metadata !{metadata !"float", metadata !2, i64 0} + +; NOAA: Alias Groups (1): +; NOAA-DAG: <{ MemRef_Int0[(0)] }, { MemRef_Int0[(1024)] }> +; NOAA-DAG: <{ MemRef_Int1[(0)] }, { MemRef_Int1[(1024)] }> +; NOAA-DAG: <{ MemRef_Float0[(0)] }, { MemRef_Float0[(1024)] }> +; NOAA-DAG: <{ MemRef_Float1[(0)] }, { MemRef_Float1[(1024)] }> + +; TBAA-DAG: Alias Groups (2): +; TBAA-DAG: <{ MemRef_Int0[(0)] }, { MemRef_Int0[(1024)] }> +; TBAA-DAG: <{ MemRef_Int1[(0)] }, { MemRef_Int1[(1024)] }> +; TBAA-DAG: <{ MemRef_Float0[(0)] }, { MemRef_Float0[(1024)] }> +; TBAA-DAG: <{ MemRef_Float1[(0)] }, { MemRef_Float1[(1024)] }>