[FIX] Cast pre-loaded values correctly or reload them with adjusted type.

Especially for structs, the SAI object of a base pointer does not
describe all the types that the user might expect when he loads from
that base pointer. While we will still cast integers and pointers we
will now reload the value with the correct type if floating point and
non-floating point values are involved. However, there are now TODOs
where we use bitcasts instead of a proper conversion or reloading.

This fixes bug 25479.

llvm-svn: 252706
This commit is contained in:
Johannes Doerfert 2015-11-11 06:20:25 +00:00
parent 240a159bd4
commit dcfedf3505
7 changed files with 113 additions and 22 deletions

View File

@ -869,7 +869,24 @@ Value *IslNodeBuilder::preloadUnconditionally(isl_set *AccessRange,
isl_ast_expr *Access =
isl_ast_build_access_from_pw_multi_aff(Build, PWAccRel);
Value *PreloadVal = ExprBuilder.create(Access);
PreloadVal = Builder.CreateBitOrPointerCast(PreloadVal, Ty);
// Correct the type as the SAI might have a different type than the user
// expects, especially if the base pointer is a struct.
if (Ty == PreloadVal->getType())
return PreloadVal;
if (!Ty->isFloatingPointTy() && !PreloadVal->getType()->isFloatingPointTy())
return PreloadVal = Builder.CreateBitOrPointerCast(PreloadVal, Ty);
// We do not want to cast floating point to non-floating point types and vice
// versa, thus we simply create a new load with a casted pointer expression.
auto *LInst = dyn_cast<LoadInst>(PreloadVal);
assert(LInst && "Preloaded value was not a load instruction");
auto *Ptr = LInst->getPointerOperand();
Ptr = Builder.CreatePointerCast(Ptr, Ty->getPointerTo(),
Ptr->getName() + ".cast");
PreloadVal = Builder.CreateLoad(Ptr, LInst->getName());
LInst->eraseFromParent();
return PreloadVal;
}
@ -992,6 +1009,8 @@ bool IslNodeBuilder::preloadInvariantEquivClass(
assert(PreloadVal->getType() == AccInst->getType());
for (const MemoryAccess *MA : MAs) {
Instruction *MAAccInst = MA->getAccessInstruction();
// TODO: The bitcast here is wrong. In case of floating and non-floating
// point values we need to reload the value or convert it.
ValueMap[MAAccInst] =
Builder.CreateBitOrPointerCast(PreloadVal, MAAccInst->getType());
}
@ -1017,6 +1036,8 @@ bool IslNodeBuilder::preloadInvariantEquivClass(
// should only change the base pointer of the derived SAI if we actually
// preloaded it.
if (BasePtr == MA->getBaseAddr()) {
// TODO: The bitcast here is wrong. In case of floating and non-floating
// point values we need to reload the value or convert it.
BasePtr =
Builder.CreateBitOrPointerCast(PreloadVal, BasePtr->getType());
DerivedSAI->setBasePtr(BasePtr);

View File

@ -0,0 +1,27 @@
; RUN: opt %loadPolly -polly-codegen < %s
;
; Check we do not crash even though we pre-load values with different types
; from the same base pointer.
;
target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"
%struct.FFIIRFilterCoeffs.0.3.6.12.15.27.36.54.57.84.87.90 = type { i32, float, i32*, float* }
; Function Attrs: nounwind ssp
define void @ff_iir_filter(%struct.FFIIRFilterCoeffs.0.3.6.12.15.27.36.54.57.84.87.90* %c, i16* %dst, i32 %dstep) #0 {
entry:
br i1 undef, label %if.end.325, label %for.body.38
for.body.38: ; preds = %for.body.38, %entry
%dst034.0180 = phi i16* [ undef, %for.body.38 ], [ %dst, %entry ]
%gain42 = getelementptr inbounds %struct.FFIIRFilterCoeffs.0.3.6.12.15.27.36.54.57.84.87.90, %struct.FFIIRFilterCoeffs.0.3.6.12.15.27.36.54.57.84.87.90* %c, i32 0, i32 1
%cy44 = getelementptr inbounds %struct.FFIIRFilterCoeffs.0.3.6.12.15.27.36.54.57.84.87.90, %struct.FFIIRFilterCoeffs.0.3.6.12.15.27.36.54.57.84.87.90* %c, i32 0, i32 3
%add.ptr88 = getelementptr inbounds i16, i16* %dst034.0180, i32 %dstep
store i16 undef, i16* %add.ptr88, align 2
%0 = load float, float* %gain42, align 4
%1 = load float*, float** %cy44, align 4
br i1 false, label %for.body.38, label %if.end.325
if.end.325: ; preds = %for.body.38, %entry
ret void
}

View File

@ -0,0 +1,45 @@
; RUN: opt %loadPolly -polly-codegen < %s
;
; Check we do not crash even though we pre-load values with different types
; from the same base pointer.
;
target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"
%struct.FFIIRFilterCoeffs.0.3.6.63.78.81.87.102.150.162.165.168.171 = type { i32, float, i32*, float* }
; Function Attrs: nounwind ssp
define void @butterworth_init_coeffs(%struct.FFIIRFilterCoeffs.0.3.6.63.78.81.87.102.150.162.165.168.171* %c) #0 {
entry:
br i1 undef, label %if.end, label %if.then
if.then: ; preds = %entry
unreachable
if.end: ; preds = %entry
br i1 undef, label %if.end.2, label %if.then.1
if.then.1: ; preds = %if.end
br label %return
if.end.2: ; preds = %if.end
br i1 undef, label %for.body.35, label %for.end.126
for.body.35: ; preds = %if.end.2
unreachable
for.end.126: ; preds = %if.end.2
%gain = getelementptr inbounds %struct.FFIIRFilterCoeffs.0.3.6.63.78.81.87.102.150.162.165.168.171, %struct.FFIIRFilterCoeffs.0.3.6.63.78.81.87.102.150.162.165.168.171* %c, i32 0, i32 1
br i1 undef, label %for.body.133, label %for.end.169
for.body.133: ; preds = %for.body.133, %for.end.126
store float undef, float* %gain, align 4
%cy = getelementptr inbounds %struct.FFIIRFilterCoeffs.0.3.6.63.78.81.87.102.150.162.165.168.171, %struct.FFIIRFilterCoeffs.0.3.6.63.78.81.87.102.150.162.165.168.171* %c, i32 0, i32 3
%0 = load float*, float** %cy, align 4
br i1 false, label %for.body.133, label %for.end.169
for.end.169: ; preds = %for.body.133, %for.end.126
br label %return
return: ; preds = %for.end.169, %if.then.1
ret void
}

View File

@ -25,13 +25,12 @@
;
; 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: %.load12 = load float, float* bitcast (i32* getelementptr (i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @S, i32 0, i32 0), i64 1) to float*)
; CODEGEN: store float %.load12, 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_add = fadd float %p_conv, %.load12
; CODEGEN: %p_conv1 = fptosi float %p_add to i32
%struct.anon = type { i32, float }

View File

@ -46,9 +46,8 @@
; CODEGEN: polly.preload.begin:
; 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: %.load12 = load float, float* bitcast (i32* getelementptr (i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @S, i32 0, i32 0), i64 1) to float*)
; CODEGEN: store float %.load12, 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 ]

View File

@ -30,10 +30,11 @@
; 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: %U.load1 = load float, float* bitcast (i32* @U to float*)
; TODO FIXME There should not be a bitcast but either a real conversion or
; another load as one type is FP the other is not.
; CODEGEN: %0 = bitcast float %U.load1 to i32
; CODEGEN: store float %U.load1, float* %U.f.preload.s2a
;
; CODEGEN: polly.merge_new_and_old:
; CODEGEN-NOT: merge = phi
@ -42,8 +43,8 @@
; 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
; CODEGEN: %p_conv = fptosi float %U.load1 to i32
; CODEGEN: %p_add = add nsw i32 %0, %p_conv
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

View File

@ -35,23 +35,22 @@
; 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: %U.load1 = load float, float* bitcast (i32* @U to float*)
; CODEGEN: %0 = bitcast float %U.load1 to i32
; CODEGEN: store float %U.load1, float* %U.f.preload.s2a
;
; CODEGEN: polly.merge_new_and_old:
; CODEGEN-DAG: %U.f.merge = phi float [ %U.f.final_reload, %polly.loop_exit ], [ %U.f, %do.cond ]
; CODEGEN-DAG: %U.i.merge = phi i32 [ %6, %polly.loop_exit ], [ %U.i, %do.cond ]
; CODEGEN-DAG: %U.i.merge = phi i32 [ %5, %polly.loop_exit ], [ %U.i, %do.cond ]
;
; CODEGEN: polly.loop_exit:
; CODEGEN-DAG: %U.f.final_reload = load float, float* %U.f.preload.s2a
; CODEGEN-DAG: %U.i.final_reload = load float, float* %U.f.preload.s2a
; CODEGEN-DAG: %6 = bitcast float %U.i.final_reload to i32
; CODEGEN-DAG: %5 = bitcast float %U.i.final_reload to i32
;
; CODEGEN: polly.stmt.do.body:
; CODEGEN: %p_conv = fptosi float %0 to i32
; CODEGEN: %p_add = add nsw i32 %1, %p_conv
; CODEGEN: %p_conv = fptosi float %U.load1 to i32
; CODEGEN: %p_add = add nsw i32 %0, %p_conv
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"