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  | 

