summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2016-03-03 17:20:43 +0000
committerMichael Kruse <llvm@meinersbur.de>2016-03-03 17:20:43 +0000
commitfaedfcbf6db7739bea35108b0b850490366145e3 (patch)
treea4bf9c42382ce4d2b1aab28f37b8bf512cd8fa0d
parent0ce261d052c83800b37de1b51e82e4ee139734f0 (diff)
downloadbcm5719-llvm-faedfcbf6db7739bea35108b0b850490366145e3.tar.gz
bcm5719-llvm-faedfcbf6db7739bea35108b0b850490366145e3.zip
[BlockGenerator] Fix PHI merges for MK_Arrays.
Value merging is only necessary for scalars when they are used outside of the scop. While an array's base pointer can be used after the scop, it gets an extra ScopArrayInfo of type MK_Value. We used to generate phi's for both of them, where one was assuming the reault of the other phi would be the original value, because it has already been replaced by the previous phi. This resulted in IR that the current IR verifier allows, but is probably illegal. This reduces the number of LNT test-suite fails with -polly-position=before-vectorizer -polly-process-unprofitable from 16 to 10. Also see llvm.org/PR26718. llvm-svn: 262629
-rw-r--r--polly/include/polly/ScopInfo.h6
-rw-r--r--polly/lib/CodeGen/BlockGenerators.cpp10
-rw-r--r--polly/test/Isl/CodeGen/multiple_sai_fro_same_base_address.ll44
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
OpenPOWER on IntegriCloud