Skip to content

Commit

Permalink
Make sure we preserve alignment information after hoisting invariant …
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
Johannes Doerfert committed Jan 19, 2016
1 parent 3a6a0a0 commit 370cf00
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
2 changes: 1 addition & 1 deletion polly/include/polly/CodeGen/IslNodeBuilder.h
Expand Up @@ -215,7 +215,7 @@ class IslNodeBuilder {
///
/// @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.
///
Expand Down
15 changes: 11 additions & 4 deletions polly/lib/CodeGen/IslNodeBuilder.cpp
Expand Up @@ -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;

Expand All @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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");
Expand Down
31 changes: 31 additions & 0 deletions 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
}

0 comments on commit 370cf00

Please sign in to comment.