summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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