summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Doerfert <doerfert@cs.uni-saarland.de>2016-01-19 00:17:21 +0000
committerJohannes Doerfert <doerfert@cs.uni-saarland.de>2016-01-19 00:17:21 +0000
commit370cf00c9f685c70ed083b228f4a8e2ea42c294e (patch)
tree29a8ac70bc448d8a28c46a1b38431cc459a2a5e0
parent3a6a0a01099536d9f2c3c822c3bf59954b277a58 (diff)
downloadbcm5719-llvm-370cf00c9f685c70ed083b228f4a8e2ea42c294e.tar.gz
bcm5719-llvm-370cf00c9f685c70ed083b228f4a8e2ea42c294e.zip
Make sure we preserve alignment information after hoisting invariant load
In Polly, after hoisting loop invariant loads outside loop, the alignment information for hoisted loads are missing, this patch restore them. Contributed-by: Lawrence Hu <lawrence@codeaurora.org> Differential Revision: http://reviews.llvm.org/D16160 llvm-svn: 258105
-rw-r--r--polly/include/polly/CodeGen/IslNodeBuilder.h2
-rw-r--r--polly/lib/CodeGen/IslNodeBuilder.cpp15
-rw-r--r--polly/test/Isl/CodeGen/invaraint_load_hoist_alignment.ll31
3 files changed, 43 insertions, 5 deletions
diff --git a/polly/include/polly/CodeGen/IslNodeBuilder.h b/polly/include/polly/CodeGen/IslNodeBuilder.h
index 30be60a0299..330a19862d4 100644
--- a/polly/include/polly/CodeGen/IslNodeBuilder.h
+++ b/polly/include/polly/CodeGen/IslNodeBuilder.h
@@ -215,7 +215,7 @@ protected:
///
/// @returns The preloaded value casted to type @p Ty
Value *preloadUnconditionally(__isl_take isl_set *AccessRange,
- isl_ast_build *Build, Type *Ty);
+ isl_ast_build *Build, Instruction *AccInst);
/// @brief Preload the memory load access @p MA.
///
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp
index f75a304d07b..ee91a2cf5ae 100644
--- a/polly/lib/CodeGen/IslNodeBuilder.cpp
+++ b/polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -893,15 +893,20 @@ bool IslNodeBuilder::materializeParameters(isl_set *Set, bool All) {
}
Value *IslNodeBuilder::preloadUnconditionally(isl_set *AccessRange,
- isl_ast_build *Build, Type *Ty) {
+ isl_ast_build *Build,
+ Instruction *AccInst) {
isl_pw_multi_aff *PWAccRel = isl_pw_multi_aff_from_set(AccessRange);
PWAccRel = isl_pw_multi_aff_gist_params(PWAccRel, S.getContext());
isl_ast_expr *Access =
isl_ast_build_access_from_pw_multi_aff(Build, PWAccRel);
Value *PreloadVal = ExprBuilder.create(Access);
+ if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal))
+ PreloadInst->setAlignment(dyn_cast<LoadInst>(AccInst)->getAlignment());
+
// Correct the type as the SAI might have a different type than the user
// expects, especially if the base pointer is a struct.
+ Type *Ty = AccInst->getType();
if (Ty == PreloadVal->getType())
return PreloadVal;
@@ -916,6 +921,9 @@ Value *IslNodeBuilder::preloadUnconditionally(isl_set *AccessRange,
Ptr = Builder.CreatePointerCast(Ptr, Ty->getPointerTo(),
Ptr->getName() + ".cast");
PreloadVal = Builder.CreateLoad(Ptr, LInst->getName());
+ if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal))
+ PreloadInst->setAlignment(dyn_cast<LoadInst>(AccInst)->getAlignment());
+
LInst->eraseFromParent();
return PreloadVal;
}
@@ -940,7 +948,7 @@ Value *IslNodeBuilder::preloadInvariantLoad(const MemoryAccess &MA,
Value *PreloadVal = nullptr;
if (AlwaysExecuted) {
- PreloadVal = preloadUnconditionally(AccessRange, Build, AccInstTy);
+ PreloadVal = preloadUnconditionally(AccessRange, Build, AccInst);
isl_ast_build_free(Build);
isl_set_free(Domain);
return PreloadVal;
@@ -984,8 +992,7 @@ Value *IslNodeBuilder::preloadInvariantLoad(const MemoryAccess &MA,
Builder.CreateBr(MergeBB);
Builder.SetInsertPoint(ExecBB->getTerminator());
- Value *PreAccInst = preloadUnconditionally(AccessRange, Build, AccInstTy);
-
+ Value *PreAccInst = preloadUnconditionally(AccessRange, Build, AccInst);
Builder.SetInsertPoint(MergeBB->getTerminator());
auto *MergePHI = Builder.CreatePHI(
AccInstTy, 2, "polly.preload." + AccInst->getName() + ".merge");
diff --git a/polly/test/Isl/CodeGen/invaraint_load_hoist_alignment.ll b/polly/test/Isl/CodeGen/invaraint_load_hoist_alignment.ll
new file mode 100644
index 00000000000..b691c9b0414
--- /dev/null
+++ b/polly/test/Isl/CodeGen/invaraint_load_hoist_alignment.ll
@@ -0,0 +1,31 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen -polly-vectorizer=polly -S %s | FileCheck %s
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16
+@B = common global [1024 x i32] zeroinitializer, align 16
+
+declare i32 @foo(i32) readnone
+
+define void @force_alignment() nounwind {
+;CHECK: @force_alignment
+;CHECK-FORCED: @force_alignment
+entry:
+ br label %body
+
+body:
+ %indvar = phi i64 [ 0, %entry ], [ %indvar_next, %body ]
+ %scevgep = getelementptr [1024 x i32], [1024 x i32]* @B, i64 0, i64 %indvar
+; CHECK: [[T2:%.load]] = load i32, i32* getelementptr inbounds ([1024 x i32], [1024 x i32]* @A, i32 0, i32 0), align 4
+; CHECK: %value_p.splatinsert = insertelement <4 x i32> undef, i32 [[T2]], i32 0
+ %value = load i32, i32* getelementptr inbounds ([1024 x i32], [1024 x i32]* @A, i64 0, i64 0), align 4
+ %result = tail call i32 @foo(i32 %value) nounwind
+ store i32 %result, i32* %scevgep, align 4
+ %indvar_next = add i64 %indvar, 1
+ %exitcond = icmp eq i64 %indvar_next, 4
+ br i1 %exitcond, label %return, label %body
+
+return:
+ ret void
+}
+
OpenPOWER on IntegriCloud