[polly] r250654 - [FIX] Cast preloaded values
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 18 05:36:42 PDT 2015
Author: jdoerfert
Date: Sun Oct 18 07:36:42 2015
New Revision: 250654
URL: http://llvm.org/viewvc/llvm-project?rev=250654&view=rev
Log:
[FIX] Cast preloaded values
Preloaded values have to match the type of their counterpart in the
original code and not the type of the base array.
Added:
polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type.ll
polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll
polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll
Modified:
polly/trunk/include/polly/CodeGen/IslNodeBuilder.h
polly/trunk/lib/CodeGen/BlockGenerators.cpp
polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
Modified: polly/trunk/include/polly/CodeGen/IslNodeBuilder.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/IslNodeBuilder.h?rev=250654&r1=250653&r2=250654&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/IslNodeBuilder.h (original)
+++ polly/trunk/include/polly/CodeGen/IslNodeBuilder.h Sun Oct 18 07:36:42 2015
@@ -204,8 +204,10 @@ protected:
virtual void createFor(__isl_take isl_ast_node *For);
/// @brief Preload the memory access at @p AccessRange with @p Build.
+ ///
+ /// @returns The preloaded value casted to type @p Ty
Value *preloadUnconditionally(__isl_take isl_set *AccessRange,
- isl_ast_build *Build);
+ isl_ast_build *Build, Type *Ty);
/// @brief Preload the memory load access @p MA.
///
@@ -218,8 +220,7 @@ protected:
/// MA_preload = load MA;
/// use MA_preload
Value *preloadInvariantLoad(const MemoryAccess &MA,
- __isl_take isl_set *Domain,
- __isl_keep isl_ast_build *Build);
+ __isl_take isl_set *Domain);
void createForVector(__isl_take isl_ast_node *For, int VectorWidth);
void createForSequential(__isl_take isl_ast_node *For);
Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=250654&r1=250653&r2=250654&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Sun Oct 18 07:36:42 2015
@@ -541,8 +541,10 @@ void BlockGenerator::createScalarFinaliz
Value *ScalarAddr = EscapeMappingValue.first;
// Reload the demoted instruction in the optimized version of the SCoP.
- Instruction *EscapeInstReload =
+ Value *EscapeInstReload =
Builder.CreateLoad(ScalarAddr, EscapeInst->getName() + ".final_reload");
+ EscapeInstReload =
+ Builder.CreateBitOrPointerCast(EscapeInstReload, EscapeInst->getType());
// Create the merge PHI that merges the optimized and unoptimized version.
PHINode *MergePHI = PHINode::Create(EscapeInst->getType(), 2,
Modified: polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslNodeBuilder.cpp?rev=250654&r1=250653&r2=250654&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslNodeBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslNodeBuilder.cpp Sun Oct 18 07:36:42 2015
@@ -835,18 +835,20 @@ void IslNodeBuilder::materializeParamete
}
Value *IslNodeBuilder::preloadUnconditionally(isl_set *AccessRange,
- isl_ast_build *Build) {
+ isl_ast_build *Build, Type *Ty) {
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);
- return ExprBuilder.create(Access);
+ Value *PreloadVal = ExprBuilder.create(Access);
+ PreloadVal = Builder.CreateBitOrPointerCast(PreloadVal, Ty);
+ return PreloadVal;
}
Value *IslNodeBuilder::preloadInvariantLoad(const MemoryAccess &MA,
- isl_set *Domain,
- isl_ast_build *Build) {
+ isl_set *Domain) {
+ auto *Build = isl_ast_build_from_context(isl_set_universe(S.getParamSpace()));
isl_set *AccessRange = isl_map_range(MA.getAccessRelation());
materializeParameters(AccessRange, false);
@@ -854,9 +856,13 @@ Value *IslNodeBuilder::preloadInvariantL
bool AlwaysExecuted = isl_set_is_equal(Domain, Universe);
isl_set_free(Universe);
+ Instruction *AccInst = MA.getAccessInstruction();
+ Type *AccInstTy = AccInst->getType();
+
+ Value *PreloadVal;
if (AlwaysExecuted) {
isl_set_free(Domain);
- return preloadUnconditionally(AccessRange, Build);
+ PreloadVal = preloadUnconditionally(AccessRange, Build, AccInstTy);
} else {
materializeParameters(Domain, false);
@@ -890,18 +896,18 @@ Value *IslNodeBuilder::preloadInvariantL
Builder.CreateBr(MergeBB);
Builder.SetInsertPoint(ExecBB->getTerminator());
- Instruction *AccInst = MA.getAccessInstruction();
- Type *AccInstTy = AccInst->getType();
- Value *PreAccInst = preloadUnconditionally(AccessRange, Build);
+ Value *PreAccInst = preloadUnconditionally(AccessRange, Build, AccInstTy);
Builder.SetInsertPoint(MergeBB->getTerminator());
auto *MergePHI = Builder.CreatePHI(
AccInstTy, 2, "polly.preload." + AccInst->getName() + ".merge");
MergePHI->addIncoming(PreAccInst, ExecBB);
MergePHI->addIncoming(Constant::getNullValue(AccInstTy), CondBB);
-
- return MergePHI;
+ PreloadVal = MergePHI;
}
+
+ isl_ast_build_free(Build);
+ return PreloadVal;
}
void IslNodeBuilder::preloadInvariantLoads() {
@@ -918,9 +924,6 @@ void IslNodeBuilder::preloadInvariantLoa
PreLoadBB->setName("polly.preload.begin");
Builder.SetInsertPoint(PreLoadBB->begin());
- isl_ast_build *Build =
- isl_ast_build_from_context(isl_set_universe(S.getParamSpace()));
-
// For each equivalence class of invariant loads we pre-load the representing
// element with the unified execution context. However, we have to map all
// elements of the class to the one preloaded load as they are referenced
@@ -932,9 +935,12 @@ void IslNodeBuilder::preloadInvariantLoa
isl_set *Domain = isl_set_copy(IAClass.second.front().second);
Instruction *AccInst = MA->getAccessInstruction();
- Value *PreloadVal = preloadInvariantLoad(*MA, Domain, Build);
- for (const InvariantAccessTy &IA : IAClass.second)
- ValueMap[IA.first->getAccessInstruction()] = PreloadVal;
+ Value *PreloadVal = preloadInvariantLoad(*MA, Domain);
+ for (const InvariantAccessTy &IA : IAClass.second) {
+ Instruction *AccInst = IA.first->getAccessInstruction();
+ ValueMap[AccInst] =
+ Builder.CreateBitOrPointerCast(PreloadVal, AccInst->getType());
+ }
if (SE.isSCEVable(AccInst->getType())) {
isl_id *ParamId = S.getIdForParam(SE.getSCEV(AccInst));
@@ -965,8 +971,6 @@ void IslNodeBuilder::preloadInvariantLoa
EscapeMap[AccInst] = std::make_pair(Alloca, std::move(EscapeUsers));
}
-
- isl_ast_build_free(Build);
}
void IslNodeBuilder::addParameters(__isl_take isl_set *Context) {
Added: polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type.ll?rev=250654&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type.ll (added)
+++ polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type.ll Sun Oct 18 07:36:42 2015
@@ -0,0 +1,66 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen -S < %s
+;
+; struct {
+; int a;
+; float b;
+; } S;
+;
+; void f(int *A) {
+; for (int i = 0; i < 1000; i++)
+; A[i] = S.a + S.b;
+; }
+;
+; CHECK: Invariant Accesses: {
+; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: { Stmt_for_body[i0] -> MemRef_S[0] };
+; CHECK: Execution Context: { : }
+; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: { Stmt_for_body[i0] -> MemRef_S[1] };
+; CHECK: Execution Context: { : }
+; CHECK: }
+;
+; CODEGEN: %S.b.preload.s2a = alloca float
+; CODEGEN: %S.a.preload.s2a = alloca i32
+;
+; CODEGEN: %.load = load i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @S, i32 0, i32 0)
+; CODEGEN: store i32 %.load, i32* %S.a.preload.s2a
+; CODEGEN: %.load1 = load i32, i32* getelementptr (i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @S, i32 0, i32 0), i64 1)
+; CODEGEN: %0 = bitcast i32 %.load1 to float
+; CODEGEN: store float %0, float* %S.b.preload.s2a
+;
+; CODEGEN: polly.stmt.for.body:
+; CODEGEN: %p_conv = sitofp i32 %.load to float
+; CODEGEN: %p_add = fadd float %p_conv, %0
+; CODEGEN: %p_conv1 = fptosi float %p_add to i32
+
+%struct.anon = type { i32, float }
+
+ at S = common global %struct.anon zeroinitializer, align 4
+
+define void @f(i32* %A) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+ %exitcond = icmp ne i64 %indvars.iv, 1000
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %S.a = load i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @S, i64 0, i32 0), align 4
+ %conv = sitofp i32 %S.a to float
+ %S.b = load float, float* getelementptr inbounds (%struct.anon, %struct.anon* @S, i64 0, i32 1), align 4
+ %add = fadd float %conv, %S.b
+ %conv1 = fptosi float %add to i32
+ %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+ store i32 %conv1, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll?rev=250654&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll (added)
+++ polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll Sun Oct 18 07:36:42 2015
@@ -0,0 +1,99 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen -S < %s
+;
+; struct {
+; int a;
+; float b;
+; } S;
+;
+; float f(int *A) {
+; int x;
+; float y;
+; int i = 0;
+; do {
+; x = S.a;
+; y = S.b;
+; A[i] = x + y;
+; } while (i++ < 1000);
+; return x + y;
+; }
+;
+; CHECK: Invariant Accesses: {
+; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: { Stmt_do_body[i0] -> MemRef_S[0] };
+; CHECK: Execution Context: { : }
+; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: { Stmt_do_body[i0] -> MemRef_S[1] };
+; CHECK: Execution Context: { : }
+; CHECK: }
+;
+; CHECK: Statements {
+; CHECK-NOT: Access
+; CHECK: Stmt_do_body
+; CHECK: Domain :=
+; CHECK: { Stmt_do_body[i0] : i0 <= 1000 and i0 >= 0 };
+; CHECK: Schedule :=
+; CHECK: { Stmt_do_body[i0] -> [i0] };
+; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: { Stmt_do_body[i0] -> MemRef_A[i0] };
+; CHECK-NOT: Access
+; CHECK: }
+;
+; CODEGEN: entry:
+; CODEGEN: %S.b.preload.s2a = alloca float
+; CODEGEN: %S.a.preload.s2a = alloca i32
+;
+; CODEGEN: polly.preload.begin:
+; CODEGEN: %.load = load i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @S, i32 0, i32 0)
+; CODEGEN: %0 = bitcast i32 %.load to float
+; CODEGEN: store i32 %.load, i32* %S.a.preload.s2a
+; CODEGEN: %.load1 = load i32, i32* getelementptr (i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @S, i32 0, i32 0), i64 1)
+; CODEGEN: %1 = bitcast i32 %.load1 to float
+; CODEGEN: %2 = bitcast float %1 to i32
+; CODEGEN: store float %1, float* %S.b.preload.s2a
+;
+; CODEGEN: polly.merge_new_and_old:
+; CODEGEN-DAG: %S.b.merge = phi float [ %S.b.final_reload, %polly.loop_exit ], [ %S.b, %do.cond ]
+; CODEGEN-DAG: %S.a.merge = phi i32 [ %S.a.final_reload, %polly.loop_exit ], [ %S.a, %do.cond ]
+;
+; CODEGEN: do.end:
+; CODEGEN: %conv3 = sitofp i32 %S.a.merge to float
+; CODEGEN: %add4 = fadd float %conv3, %S.b.merge
+; CODEGEN: ret float %add4
+;
+; CODEGEN: polly.loop_exit:
+; CODEGEN-DAG: %S.b.final_reload = load float, float* %S.b.preload.s2a
+; CODEGEN-DAG: %S.a.final_reload = load i32, i32* %S.a.preload.s2a
+
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+%struct.anon = type { i32, float }
+
+ at S = common global %struct.anon zeroinitializer, align 4
+
+define float @f(i32* %A) {
+entry:
+ br label %do.body
+
+do.body: ; preds = %do.cond, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %do.cond ], [ 0, %entry ]
+ %S.a = load i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @S, i64 0, i32 0), align 4
+ %S.b = load float, float* getelementptr inbounds (%struct.anon, %struct.anon* @S, i64 0, i32 1), align 4
+ %conv = sitofp i32 %S.a to float
+ %add = fadd float %conv, %S.b
+ %conv1 = fptosi float %add to i32
+ %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+ store i32 %conv1, i32* %arrayidx, align 4
+ br label %do.cond
+
+do.cond: ; preds = %do.body
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp ne i64 %indvars.iv.next, 1001
+ br i1 %exitcond, label %do.body, label %do.end
+
+do.end: ; preds = %do.cond
+ %conv3 = sitofp i32 %S.a to float
+ %add4 = fadd float %conv3, %S.b
+ ret float %add4
+}
Added: polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll?rev=250654&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll (added)
+++ polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll Sun Oct 18 07:36:42 2015
@@ -0,0 +1,77 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen -S < %s
+;
+; int U;
+; void f(int *A) {
+; for (int i = 0; i < 1000; i++)
+; A[i] = (*(int *)&U) + (int)(*(float *)&U);
+; }
+;
+; CHECK: Invariant Accesses: {
+; CHECK-NOT: ReadAccess
+; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: { Stmt_for_body[i0] -> MemRef_U[0] };
+; CHECK: Execution Context: { : }
+; CHECK-NOT: ReadAccess
+; CHECK: }
+;
+; CHECK: Statements {
+; CHECK: Stmt_for_body
+; CHECK: Domain :=
+; CHECK: { Stmt_for_body[i0] : i0 <= 999 and i0 >= 0 };
+; CHECK: Schedule :=
+; CHECK: { Stmt_for_body[i0] -> [i0] };
+; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: { Stmt_for_body[i0] -> MemRef_A[i0] };
+; CHECK: }
+;
+; CODEGEN: entry:
+; CODEGEN: %U.f.preload.s2a = alloca float
+; CODEGEN: br label %polly.split_new_and_old
+;
+; CODEGEN: polly.preload.begin:
+; CODEGEN: %U.load = load i32, i32* @U
+; CODEGEN: %0 = bitcast i32 %U.load to float
+; CODEGEN: %1 = bitcast float %0 to i32
+; CODEGEN: store float %0, float* %U.f.preload.s2a
+;
+; CODEGEN: polly.merge_new_and_old:
+; CODEGEN-NOT: merge = phi
+;
+; CODEGEN: polly.loop_exit:
+; CODEGEN-NOT: final_reload
+;
+; CODEGEN: polly.stmt.for.body:
+; CODEGEN: %p_conv = fptosi float %0 to i32
+; CODEGEN: %p_add = add nsw i32 %1, %p_conv
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+ at U = common global i32 0, align 4
+
+define void @f(i32* %A) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+ %exitcond = icmp ne i64 %indvars.iv, 1000
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %U.i = load i32, i32* @U, align 4
+ %U.cast = bitcast i32 *@U to float*
+ %U.f = load float, float* %U.cast, align 4
+ %conv = fptosi float %U.f to i32
+ %add = add nsw i32 %U.i, %conv
+ %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+ store i32 %add, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
More information about the llvm-commits
mailing list