diff options
7 files changed, 113 insertions, 22 deletions
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp index ab762e6797a..b14c9806268 100644 --- a/polly/lib/CodeGen/IslNodeBuilder.cpp +++ b/polly/lib/CodeGen/IslNodeBuilder.cpp @@ -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); diff --git a/polly/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll b/polly/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll new file mode 100644 index 00000000000..87b0014b09d --- /dev/null +++ b/polly/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll @@ -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 +} diff --git a/polly/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll b/polly/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll new file mode 100644 index 00000000000..7afa3b969ed --- /dev/null +++ b/polly/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll @@ -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 +} diff --git a/polly/test/ScopInfo/invariant_load_access_classes_different_base_type.ll b/polly/test/ScopInfo/invariant_load_access_classes_different_base_type.ll index 18a8ed40b55..5410146287d 100644 --- a/polly/test/ScopInfo/invariant_load_access_classes_different_base_type.ll +++ b/polly/test/ScopInfo/invariant_load_access_classes_different_base_type.ll @@ -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 } diff --git a/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll b/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll index 90d09bd89dc..cb9ac0a4382 100644 --- a/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll +++ b/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll @@ -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 ] diff --git a/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll b/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll index e5fdaf27adc..4e30d818e85 100644 --- a/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll +++ b/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll @@ -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" diff --git a/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll b/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll index 9fe6e0dc492..8213fb4afd3 100644 --- a/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll +++ b/polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll @@ -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" |

