mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 20:51:35 +00:00
[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:
parent
240a159bd4
commit
dcfedf3505
@ -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);
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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 }
|
||||
|
@ -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 ]
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user