diff options
| author | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-01-19 00:17:21 +0000 |
|---|---|---|
| committer | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-01-19 00:17:21 +0000 |
| commit | 370cf00c9f685c70ed083b228f4a8e2ea42c294e (patch) | |
| tree | 29a8ac70bc448d8a28c46a1b38431cc459a2a5e0 | |
| parent | 3a6a0a01099536d9f2c3c822c3bf59954b277a58 (diff) | |
| download | bcm5719-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.h | 2 | ||||
| -rw-r--r-- | polly/lib/CodeGen/IslNodeBuilder.cpp | 15 | ||||
| -rw-r--r-- | polly/test/Isl/CodeGen/invaraint_load_hoist_alignment.ll | 31 |
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 +} + |

