diff options
-rw-r--r-- | polly/include/polly/ScopInfo.h | 6 | ||||
-rw-r--r-- | polly/lib/CodeGen/BlockGenerators.cpp | 10 | ||||
-rw-r--r-- | polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll | 44 |
3 files changed, 60 insertions, 0 deletions
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index 2d0b9e7a753..5c189712902 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -319,6 +319,9 @@ public: /// @brief Return the isl id for the base pointer. __isl_give isl_id *getBasePtrId() const; + /// @brief Is this array info modeling an llvm::Value? + bool isValueKind() const { return Kind == MK_Value; }; + /// @brief Is this array info modeling special PHI node memory? /// /// During code generation of PHI nodes, there is a need for two kinds of @@ -331,6 +334,9 @@ public: /// normal scalar array modeling. bool isPHIKind() const { return Kind == MK_PHI; }; + /// @brief Is this array info modeling an MK_ExitPHI? + bool isExitPHIKind() const { return Kind == MK_ExitPHI; }; + /// @brief Is this array info modeling an array? bool isArrayKind() const { return Kind == MK_Array; }; diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp index 4beb30ab994..e643ada9eed 100644 --- a/polly/lib/CodeGen/BlockGenerators.cpp +++ b/polly/lib/CodeGen/BlockGenerators.cpp @@ -601,6 +601,13 @@ void BlockGenerator::createExitPHINodeMerges(Scop &S) { auto &SAI = Pair.second; auto *Val = SAI->getBasePtr(); + // Only Value-like scalars need a merge PHI. Exit block PHIs receive either + // the original PHI's value or the reloaded incoming values from the + // generated code. An llvm::Value is merged between the original code's + // value or the generated one. + if (!SAI->isValueKind() && !SAI->isExitPHIKind()) + continue; + PHINode *PHI = dyn_cast<PHINode>(Val); if (!PHI) continue; @@ -613,6 +620,9 @@ void BlockGenerator::createExitPHINodeMerges(Scop &S) { Value *Reload = Builder.CreateLoad(ScalarAddr, Name + ".ph.final_reload"); Reload = Builder.CreateBitOrPointerCast(Reload, PHI->getType()); Value *OriginalValue = PHI->getIncomingValueForBlock(MergeBB); + assert((!isa<Instruction>(OriginalValue) || + cast<Instruction>(OriginalValue)->getParent() != MergeBB) && + "Original value must no be one we just generated."); auto *MergePHI = PHINode::Create(PHI->getType(), 2, Name + ".ph.merge"); MergePHI->insertBefore(&*MergeBB->getFirstInsertionPt()); MergePHI->addIncoming(Reload, OptExitBB); diff --git a/polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll b/polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll new file mode 100644 index 00000000000..7fa431ef67e --- /dev/null +++ b/polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll @@ -0,0 +1,44 @@ +; RUN: opt %loadPolly -polly-position=before-vectorizer -polly-scops -analyze < %s | FileCheck %s --check-prefix=SCOP +; RUN: opt %loadPolly -polly-position=before-vectorizer -polly-codegen -S < %s | FileCheck %s --check-prefix=IR + +; The IR has two ScopArrayInfo for the value %next.0. This used to produce two +; phi nodes in polly.merge_new_and_old, one illegaly using the result of the +; other. There must be only one merge phi, no need to generate them for arrays +; of type MK_Array. +; Derived from test-suite/MultiSource/Applications/siod/slib.c + +%struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962 = type { i16, i16, %union.anon.1.289.321.337.353.481.545.593.625.817.897.913.961 } +%union.anon.1.289.321.337.353.481.545.593.625.817.897.913.961 = type { %struct.anon.0.288.320.336.352.480.544.592.624.816.896.912.960 } +%struct.anon.0.288.320.336.352.480.544.592.624.816.896.912.960 = type { %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962*, %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962* } + +define void @leval_or() { +entry: + br label %while.cond + +while.cond: ; preds = %sw.bb1.i30, %cond.end.i28, %entry + %next.0 = phi %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962* [ null, %entry ], [ %1, %sw.bb1.i30 ], [ null, %cond.end.i28 ] + br i1 undef, label %cond.end.i28, label %if.then + +if.then: ; preds = %while.cond + ret void + +cond.end.i28: ; preds = %while.cond + %type.i24 = getelementptr inbounds %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962, %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962* %next.0, i64 0, i32 1 + %0 = load i16, i16* %type.i24, align 2 + br i1 false, label %sw.bb1.i30, label %while.cond + +sw.bb1.i30: ; preds = %cond.end.i28 + %cdr.i29 = getelementptr inbounds %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962, %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962* %next.0, i64 0, i32 2, i32 0, i32 1 + %1 = load %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962*, %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962** %cdr.i29, align 8 + br label %while.cond +} + +; SCOP: Arrays { +; SCOP-NEXT: i16 MemRef_next_0[*]; +; SCOP-NEXT: %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962* MemRef_next_0; +; SCOP-NEXT: } + +; IR: polly.merge_new_and_old: +; IR-NEXT: %next.0.ph.merge = phi %struct.obj.2.290.322.338.354.482.546.594.626.818.898.914.962* [ %next.0.ph.final_reload, %polly.exiting ], [ %next.0.ph, %while.cond.region_exiting ] +; IR-NEXT: %indvar.next = add i64 %indvar, 1 +; IR-NEXT: br label %while.cond |