summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/lib/CodeGen/IslNodeBuilder.cpp23
-rw-r--r--polly/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll27
-rw-r--r--polly/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll45
-rw-r--r--polly/test/ScopInfo/invariant_load_access_classes_different_base_type.ll7
-rw-r--r--polly/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll5
-rw-r--r--polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll13
-rw-r--r--polly/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll15
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"
OpenPOWER on IntegriCloud