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

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 10 22:20:25 PST 2015


Author: jdoerfert
Date: Wed Nov 11 00:20:25 2015
New Revision: 252706

URL: http://llvm.org/viewvc/llvm-project?rev=252706&view=rev
Log:
[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.


Added:
    polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll
    polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll
Modified:
    polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
    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
    polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll

Modified: polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslNodeBuilder.cpp?rev=252706&r1=252705&r2=252706&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslNodeBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslNodeBuilder.cpp Wed Nov 11 00:20:25 2015
@@ -869,7 +869,24 @@ Value *IslNodeBuilder::preloadUnconditio
   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::preloadInvariantEqu
   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::preloadInvariantEqu
       // 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);

Added: polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll?rev=252706&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll (added)
+++ polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_1.ll Wed Nov 11 00:20:25 2015
@@ -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
+}

Added: polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll?rev=252706&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll (added)
+++ polly/trunk/test/Isl/CodeGen/invariant_loads_from_struct_with_different_types_2.ll Wed Nov 11 00:20:25 2015
@@ -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
+}

Modified: 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=252706&r1=252705&r2=252706&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type.ll (original)
+++ polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type.ll Wed Nov 11 00:20:25 2015
@@ -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 }

Modified: 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=252706&r1=252705&r2=252706&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll (original)
+++ polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_escaping.ll Wed Nov 11 00:20:25 2015
@@ -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 ]

Modified: 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=252706&r1=252705&r2=252706&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll (original)
+++ polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer.ll Wed Nov 11 00:20:25 2015
@@ -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"
 

Modified: polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll?rev=252706&r1=252705&r2=252706&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll (original)
+++ polly/trunk/test/ScopInfo/invariant_load_access_classes_different_base_type_same_pointer_escaping.ll Wed Nov 11 00:20:25 2015
@@ -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"
 




More information about the llvm-commits mailing list