diff options
-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 +} + |