[polly] r259587 - Support loads with differently sized types from a single array

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 2 14:05:30 PST 2016


Author: grosser
Date: Tue Feb  2 16:05:29 2016
New Revision: 259587

URL: http://llvm.org/viewvc/llvm-project?rev=259587&view=rev
Log:
Support loads with differently sized types from a single array

We support now code such as:

void multiple_types(char *Short, char *Float, char *Double) {
  for (long i = 0; i < 100; i++) {
    Short[i] = *(short *)&Short[2 * i];
    Float[i] = *(float *)&Float[4 * i];
    Double[i] = *(double *)&Double[8 * i];
  }
}

To support such code we use as element type of the modeled array the smallest
element type of all original array accesses. Accesses with larger types are
modeled as multiple accesses with the smaller type.

For example the second load access is modeled as:

  { Stmt_bb2[i0] -> MemRef_Float[o0] : 4i0 <= o0 <= 3 + 4i0 }

To support jscop-rewritable memory accesses we need each statement instance to
only be assigned a single memory location, which will be the address at which
we load the value. Currently we obtain this address by taking the lexmin of
the access function. We may consider keeping track of the memory location more
explicitly in the future.

Added:
    polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types.ll
    polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types___%bb1---%bb22.jscop
    polly/trunk/test/ScopInfo/multiple-types-incorrect.ll
    polly/trunk/test/ScopInfo/multiple-types.ll
Removed:
    polly/trunk/test/ScopDetectionDiagnostics/ReportDifferentElementSize.ll
Modified:
    polly/trunk/include/polly/ScopDetectionDiagnostic.h
    polly/trunk/include/polly/ScopInfo.h
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/Analysis/ScopDetectionDiagnostic.cpp
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/lib/CodeGen/BlockGenerators.cpp

Modified: polly/trunk/include/polly/ScopDetectionDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopDetectionDiagnostic.h?rev=259587&r1=259586&r2=259587&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopDetectionDiagnostic.h (original)
+++ polly/trunk/include/polly/ScopDetectionDiagnostic.h Tue Feb  2 16:05:29 2016
@@ -75,7 +75,6 @@ enum RejectReasonKind {
   rrkUndefBasePtr,
   rrkVariantBasePtr,
   rrkNonAffineAccess,
-  rrkDifferentElementSize,
   rrkLastAffFunc,
 
   rrkLoopBound,
@@ -510,30 +509,6 @@ public:
 
   /// @name LLVM-RTTI interface
   //@{
-  static bool classof(const RejectReason *RR);
-  //@}
-
-  /// @name RejectReason interface
-  //@{
-  virtual std::string getMessage() const override;
-  virtual std::string getEndUserMessage() const override;
-  //@}
-};
-
-//===----------------------------------------------------------------------===//
-/// @brief Report array accesses with differing element size.
-class ReportDifferentArrayElementSize : public ReportAffFunc {
-  //===--------------------------------------------------------------------===//
-
-  // The base pointer of the memory access.
-  const Value *BaseValue;
-
-public:
-  ReportDifferentArrayElementSize(const Instruction *Inst, const Value *V)
-      : ReportAffFunc(rrkDifferentElementSize, Inst), BaseValue(V) {}
-
-  /// @name LLVM-RTTI interface
-  //@{
   static bool classof(const RejectReason *RR);
   //@}
 

Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=259587&r1=259586&r2=259587&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Tue Feb  2 16:05:29 2016
@@ -243,7 +243,7 @@ public:
   ///  @param A vector of array sizes where the rightmost array sizes need to
   ///         match the innermost array sizes already defined in SAI.
   ///  @returns Returns true if the update was successful, otherwise false.
-  bool updateSizes(ArrayRef<const SCEV *> Sizes);
+  bool updateSizes(ArrayRef<const SCEV *> Sizes, Type *ElementType);
 
   /// @brief Destructor to free the isl id of the base pointer.
   ~ScopArrayInfo();
@@ -524,7 +524,26 @@ private:
   /// @brief Subscript expression for each dimension.
   SmallVector<const SCEV *, 4> Subscripts;
 
-  /// @brief Relation from statment instances to the accessed array elements.
+  /// @brief Relation from statement instances to the accessed array elements.
+  ///
+  /// In the common case this relation is a function that maps a set of loop
+  /// indices to the memory address from which a value is loaded.
+  ///
+  /// For example:
+  ///   for i
+  ///     for j
+  /// S:     A[i + 3 j] = ...
+  ///
+  /// => { S[i,j] -> A[i + 3j] }
+  ///
+  /// For cases where the access function is not known, the access relation may
+  /// also be a one to all mapping { S[i,j] -> A[o] } describing that any
+  /// element accessible through A might be accessed.
+  ///
+  /// In case a larger element is loaded from an array that may also contain
+  /// smaller elements, the access function may relate model multiple smaller
+  /// reads. In this case, the lexicograph smallest element is the memory
+  /// address from which the largest element needs to be loaded from.
   isl_map *AccessRelation;
 
   /// @brief Updated access relation read from JSCOP file.

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=259587&r1=259586&r2=259587&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Tue Feb  2 16:05:29 2016
@@ -787,13 +787,7 @@ bool ScopDetection::isValidMemoryAccess(
   AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
 
   const SCEV *Size = SE->getElementSize(Inst);
-  if (Context.ElementSize.count(BasePointer)) {
-    if (Context.ElementSize[BasePointer] != Size)
-      return invalid<ReportDifferentArrayElementSize>(Context, /*Assert=*/true,
-                                                      Inst, BaseValue);
-  } else {
-    Context.ElementSize[BasePointer] = Size;
-  }
+  Context.ElementSize[BasePointer] = Size;
 
   bool isVariantInNonAffineLoop = false;
   SetVector<const Loop *> Loops;

Modified: polly/trunk/lib/Analysis/ScopDetectionDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetectionDiagnostic.cpp?rev=259587&r1=259586&r2=259587&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetectionDiagnostic.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetectionDiagnostic.cpp Tue Feb  2 16:05:29 2016
@@ -270,24 +270,6 @@ bool ReportVariantBasePtr::classof(const
 }
 
 //===----------------------------------------------------------------------===//
-// ReportDifferentArrayElementSize
-
-std::string ReportDifferentArrayElementSize::getMessage() const {
-  return "Access to one array through data types of different size";
-}
-
-bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) {
-  return RR->getKind() == rrkDifferentElementSize;
-}
-
-std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
-  llvm::StringRef BaseName = BaseValue->getName();
-  std::string Name = (BaseName.size() > 0) ? BaseName : "UNKNOWN";
-  return "The array \"" + Name + "\" is accessed through elements that differ "
-                                 "in size";
-}
-
-//===----------------------------------------------------------------------===//
 // ReportNonAffineAccess.
 
 std::string ReportNonAffineAccess::getMessage() const {

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=259587&r1=259586&r2=259587&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Tue Feb  2 16:05:29 2016
@@ -182,7 +182,7 @@ ScopArrayInfo::ScopArrayInfo(Value *Base
       getIslCompatibleName("MemRef_", BasePtr, Kind == MK_PHI ? "__phi" : "");
   Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
 
-  updateSizes(Sizes);
+  updateSizes(Sizes, ElementType);
   BasePtrOriginSAI = identifyBasePtrOriginSAI(S, BasePtr);
   if (BasePtrOriginSAI)
     const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
@@ -195,7 +195,23 @@ __isl_give isl_space *ScopArrayInfo::get
   return Space;
 }
 
-bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes) {
+bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes,
+                                Type *NewElementType) {
+  auto OldElementSize = DL.getTypeAllocSize(ElementType);
+  auto NewElementSize = DL.getTypeAllocSize(NewElementType);
+
+  if (OldElementSize != NewElementSize) {
+    if (OldElementSize < NewElementSize &&
+        NewElementSize % OldElementSize == 0) {
+      ; // fallthrough
+    } else if (NewElementSize < OldElementSize &&
+               OldElementSize % NewElementSize == 0) {
+      ElementType = NewElementType;
+    } else {
+      return false;
+    }
+  }
+
   int SharedDims = std::min(NewSizes.size(), DimensionSizes.size());
   int ExtraDimsNew = NewSizes.size() - SharedDims;
   int ExtraDimsOld = DimensionSizes.size() - SharedDims;
@@ -283,8 +299,9 @@ void MemoryAccess::updateDimensionality(
   auto DimsAccess = isl_space_dim(AccessSpace, isl_dim_set);
   auto DimsMissing = DimsArray - DimsAccess;
 
-  auto Map = isl_map_from_domain_and_range(isl_set_universe(AccessSpace),
-                                           isl_set_universe(ArraySpace));
+  auto Map = isl_map_from_domain_and_range(
+      isl_set_universe(AccessSpace),
+      isl_set_universe(isl_space_copy(ArraySpace)));
 
   for (unsigned i = 0; i < DimsMissing; i++)
     Map = isl_map_fix_si(Map, isl_dim_out, i, 0);
@@ -294,6 +311,45 @@ void MemoryAccess::updateDimensionality(
 
   AccessRelation = isl_map_apply_range(AccessRelation, Map);
 
+  // Introduce multi-element accesses in case the type loaded by this memory
+  // access is larger than the canonical element type of the array.
+  //
+  // An access ((float *)A)[i] to an array char *A is modeled as
+  // {[i] -> A[o] : 4 i <= o <= 4 i + 3
+  unsigned ArrayElemSize = getScopArrayInfo()->getElemSizeInBytes();
+  if (ElemBytes > ArrayElemSize && ElemBytes % ArrayElemSize == 0) {
+    auto Map = isl_map_from_domain_and_range(
+        isl_set_universe(isl_space_copy(ArraySpace)),
+        isl_set_universe(isl_space_copy(ArraySpace)));
+    for (unsigned i = 0; i < DimsArray - 1; i++)
+      Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
+
+    isl_ctx *Ctx;
+    isl_constraint *C;
+    isl_local_space *LS;
+
+    LS = isl_local_space_from_space(isl_map_get_space(Map));
+    Ctx = isl_map_get_ctx(Map);
+    int Num = ElemBytes / getScopArrayInfo()->getElemSizeInBytes();
+
+    C = isl_constraint_alloc_inequality(isl_local_space_copy(LS));
+    C = isl_constraint_set_constant_val(C, isl_val_int_from_si(Ctx, Num - 1));
+    C = isl_constraint_set_coefficient_si(C, isl_dim_in,
+                                          DimsArray - 1 - DimsMissing, Num);
+    C = isl_constraint_set_coefficient_si(C, isl_dim_out, DimsArray - 1, -1);
+    Map = isl_map_add_constraint(Map, C);
+
+    C = isl_constraint_alloc_inequality(LS);
+    C = isl_constraint_set_coefficient_si(C, isl_dim_in,
+                                          DimsArray - 1 - DimsMissing, -Num);
+    C = isl_constraint_set_coefficient_si(C, isl_dim_out, DimsArray - 1, 1);
+    C = isl_constraint_set_constant_val(C, isl_val_int_from_si(Ctx, 0));
+    Map = isl_map_add_constraint(Map, C);
+    AccessRelation = isl_map_apply_range(AccessRelation, Map);
+  }
+
+  isl_space_free(ArraySpace);
+
   assumeNoOutOfBound();
 }
 
@@ -437,6 +493,10 @@ __isl_give isl_pw_multi_aff *MemoryAcces
   USchedule = isl_union_map_intersect_domain(USchedule, UDomain);
   Schedule = isl_map_from_union_map(USchedule);
   ScheduledAccRel = isl_map_apply_domain(getAccessRelation(), Schedule);
+
+  // For multi-element accesses we always use the lowest memory location as the
+  // actual element that is accessed.
+  ScheduledAccRel = isl_map_lexmin(ScheduledAccRel);
   return isl_pw_multi_aff_from_map(ScheduledAccRel);
 }
 
@@ -2986,7 +3046,7 @@ Scop::getOrCreateScopArrayInfo(Value *Ba
   } else {
     // In case of mismatching array sizes, we bail out by setting the run-time
     // context to false.
-    if (!SAI->updateSizes(Sizes))
+    if (!SAI->updateSizes(Sizes, ElementType))
       invalidate(DELINEARIZATION, DebugLoc());
   }
   return SAI.get();

Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=259587&r1=259586&r2=259587&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Tue Feb  2 16:05:29 2016
@@ -188,12 +188,8 @@ BlockGenerator::generateLocationAccessed
     OldPtrTy = PointerType::get(OldPtrTy->getElementType(),
                                 NewPtrTy->getPointerAddressSpace());
 
-    if (OldPtrTy != NewPtrTy) {
-      assert(OldPtrTy->getPointerElementType()->getPrimitiveSizeInBits() ==
-                 NewPtrTy->getPointerElementType()->getPrimitiveSizeInBits() &&
-             "Pointer types to elements with different size found");
+    if (OldPtrTy != NewPtrTy)
       Address = Builder.CreateBitOrPointerCast(Address, OldPtrTy);
-    }
     return Address;
   }
 

Added: polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types.ll?rev=259587&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types.ll (added)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types.ll Tue Feb  2 16:05:29 2016
@@ -0,0 +1,70 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S \
+; RUN:   -polly-codegen -S    < %s | FileCheck %s
+;
+;    // Check that accessing one array with different types works.
+;    void multiple_types(char *Short, char *Float, char *Double) {
+;      for (long i = 0; i < 100; i++) {
+;        Short[i] = *(short *)&Short[2 * i];
+;        Float[i] = *(float *)&Float[4 * i];
+;        Double[i] = *(double *)&Double[8 * i];
+;      }
+;    }
+
+; Short[0]
+; CHECK: %polly.access.Short10 = getelementptr i8, i8* %Short, i64 0
+; CHECK: %12 = bitcast i8* %polly.access.Short10 to i16*
+; CHECK: %tmp5_p_scalar_ = load i16, i16* %12
+
+; Float[8 * i]
+; CHECK: %13 = mul nsw i64 8, %polly.indvar
+; CHECK: %polly.access.Float11 = getelementptr i8, i8* %Float, i64 %13
+; CHECK: %14 = bitcast i8* %polly.access.Float11 to float*
+; CHECK: %tmp11_p_scalar_ = load float, float* %14
+
+; Double[8]
+; CHECK: %polly.access.Double13 = getelementptr i8, i8* %Double, i64 8
+; CHECK: %15 = bitcast i8* %polly.access.Double13 to double*
+; CHECK: %tmp17_p_scalar_ = load double, double* %15
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @multiple_types(i8* %Short, i8* %Float, i8* %Double) {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb20, %bb
+  %i.0 = phi i64 [ 0, %bb ], [ %tmp21, %bb20 ]
+  %exitcond = icmp ne i64 %i.0, 100
+  br i1 %exitcond, label %bb2, label %bb22
+
+bb2:                                              ; preds = %bb1
+  %tmp = shl nsw i64 %i.0, 1
+  %tmp3 = getelementptr inbounds i8, i8* %Short, i64 %tmp
+  %tmp4 = bitcast i8* %tmp3 to i16*
+  %tmp5 = load i16, i16* %tmp4, align 2
+  %tmp6 = trunc i16 %tmp5 to i8
+  %tmp7 = getelementptr inbounds i8, i8* %Short, i64 %i.0
+  store i8 %tmp6, i8* %tmp7, align 1
+  %tmp8 = shl nsw i64 %i.0, 2
+  %tmp9 = getelementptr inbounds i8, i8* %Float, i64 %tmp8
+  %tmp10 = bitcast i8* %tmp9 to float*
+  %tmp11 = load float, float* %tmp10, align 4
+  %tmp12 = fptosi float %tmp11 to i8
+  %tmp13 = getelementptr inbounds i8, i8* %Float, i64 %i.0
+  store i8 %tmp12, i8* %tmp13, align 1
+  %tmp14 = shl nsw i64 %i.0, 3
+  %tmp15 = getelementptr inbounds i8, i8* %Double, i64 %tmp14
+  %tmp16 = bitcast i8* %tmp15 to double*
+  %tmp17 = load double, double* %tmp16, align 8
+  %tmp18 = fptosi double %tmp17 to i8
+  %tmp19 = getelementptr inbounds i8, i8* %Double, i64 %i.0
+  store i8 %tmp18, i8* %tmp19, align 1
+  br label %bb20
+
+bb20:                                             ; preds = %bb2
+  %tmp21 = add nuw nsw i64 %i.0, 1
+  br label %bb1
+
+bb22:                                             ; preds = %bb1
+  ret void
+}

Added: polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types___%bb1---%bb22.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types___%25bb1---%25bb22.jscop?rev=259587&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types___%bb1---%bb22.jscop (added)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/multiple_types___%bb1---%bb22.jscop Tue Feb  2 16:05:29 2016
@@ -0,0 +1,37 @@
+{
+   "context" : "{  :  }",
+   "name" : "bb1 => bb22",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_bb2[i0] -> MemRef_Short[0]}"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_bb2[i0] -> MemRef_Short[i0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_bb2[i0] -> MemRef_Float[o0] : 8i0 <=  o0 <= 3 + 8i0 }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_bb2[i0] -> MemRef_Float[i0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_bb2[i0] -> MemRef_Double[8]}"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_bb2[i0] -> MemRef_Double[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_bb2[i0] : 0 <= i0 <= 99 }",
+         "name" : "Stmt_bb2",
+         "schedule" : "{ Stmt_bb2[i0] -> [i0] }"
+      }
+   ]
+}

Removed: polly/trunk/test/ScopDetectionDiagnostics/ReportDifferentElementSize.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetectionDiagnostics/ReportDifferentElementSize.ll?rev=259586&view=auto
==============================================================================
--- polly/trunk/test/ScopDetectionDiagnostics/ReportDifferentElementSize.ll (original)
+++ polly/trunk/test/ScopDetectionDiagnostics/ReportDifferentElementSize.ll (removed)
@@ -1,67 +0,0 @@
-; RUN: opt %loadPolly -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -analyze < %s 2>&1| FileCheck %s
-
-; 1 void differenttypes(char *A)
-; 2 {
-; 3   for (long i = 0; i < 1024; ++i)
-; 4     ((float*)A)[i] = ((double*)A)[i];
-; 5 }
-
-; CHECK: remark: /tmp/test.c:3:20: The following errors keep this region from being a Scop.
-; CHECK-NEXT: remark: /tmp/test.c:4:14: The array "A" is accessed through elements that differ in size
-; CHECK-NEXT: remark: /tmp/test.c:4:32: Invalid Scop candidate ends here.
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-define void @differenttypes(i8* nocapture %A)  !dbg !4 {
-entry:
-  br label %for.body, !dbg !10
-
-for.body:                                         ; preds = %for.body, %entry
-  %i.05 = phi i64 [ 0, %entry ], [ %tmp11, %for.body ]
-  %tmp = shl i64 %i.05, 3, !dbg !15
-  %uglygep = getelementptr i8, i8* %A, i64 %tmp
-  %arrayidx = bitcast i8* %uglygep to double*, !dbg !16
-  %tmp9 = shl i64 %i.05, 2, !dbg !15
-  %uglygep7 = getelementptr i8, i8* %A, i64 %tmp9
-  %arrayidx1 = bitcast i8* %uglygep7 to float*, !dbg !17
-  %tmp10 = load double, double* %arrayidx, align 8, !dbg !16, !tbaa !18
-  %conv = fptrunc double %tmp10 to float, !dbg !16
-  store float %conv, float* %arrayidx1, align 4, !dbg !17, !tbaa !22
-  %tmp11 = add nsw i64 %i.05, 1, !dbg !24
-  %exitcond = icmp eq i64 %tmp11, 1024, !dbg !10
-  br i1 %exitcond, label %for.end, label %for.body, !dbg !10
-
-for.end:                                          ; preds = %for.body
-  ret void, !dbg !25
-}
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!7, !8}
-!llvm.ident = !{!9}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.6.0 ", isOptimized: true, emissionKind: 2, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
-!1 = !DIFile(filename: "/tmp/test.c", directory: "/home/grosser/Projects/polly/git/tools/polly/test/ScopDetectionDiagnostics")
-!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "differenttypes", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 2, file: !1, scope: !5, type: !6, variables: !2)
-!5 = !DIFile(filename: "/tmp/test.c", directory: "/home/grosser/Projects/polly/git/tools/polly/test/ScopDetectionDiagnostics")
-!6 = !DISubroutineType(types: !2)
-!7 = !{i32 2, !"Dwarf Version", i32 4}
-!8 = !{i32 2, !"Debug Info Version", i32 3}
-!9 = !{!"clang version 3.6.0 "}
-!10 = !DILocation(line: 3, column: 20, scope: !11)
-!11 = !DILexicalBlockFile(discriminator: 2, file: !1, scope: !12)
-!12 = !DILexicalBlockFile(discriminator: 1, file: !1, scope: !13)
-!13 = distinct !DILexicalBlock(line: 3, column: 3, file: !1, scope: !14)
-!14 = distinct !DILexicalBlock(line: 3, column: 3, file: !1, scope: !4)
-!15 = !DILocation(line: 4, column: 32, scope: !13)
-!16 = !DILocation(line: 4, column: 22, scope: !13)
-!17 = !DILocation(line: 4, column: 14, scope: !13)
-!18 = !{!19, !19, i64 0}
-!19 = !{!"double", !20, i64 0}
-!20 = !{!"omnipotent char", !21, i64 0}
-!21 = !{!"Simple C/C++ TBAA"}
-!22 = !{!23, !23, i64 0}
-!23 = !{!"float", !20, i64 0}
-!24 = !DILocation(line: 3, column: 30, scope: !13)
-!25 = !DILocation(line: 5, column: 1, scope: !4)

Added: polly/trunk/test/ScopInfo/multiple-types-incorrect.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multiple-types-incorrect.ll?rev=259587&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/multiple-types-incorrect.ll (added)
+++ polly/trunk/test/ScopInfo/multiple-types-incorrect.ll Tue Feb  2 16:05:29 2016
@@ -0,0 +1,52 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+;    // Check that accessing one array with different types works.
+;    void multiple_types(char *Short, char *Float, char *Double) {
+;      for (long i = 0; i < 100; i++) {
+;        Short[i] = *(short *)&Short[i];
+;        Float[i] = *(float *)&Float[i];
+;        Double[i] = *(double *)&Double[i];
+;      }
+;    }
+;
+; CHECK-NOT: Statements
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @multiple_types(i8* %Short, i8* %Float, i8* %Double) {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb17, %bb
+  %i.0 = phi i64 [ 0, %bb ], [ %tmp18, %bb17 ]
+  %exitcond = icmp ne i64 %i.0, 100
+  br i1 %exitcond, label %bb2, label %bb19
+
+bb2:                                              ; preds = %bb1
+  %tmp = getelementptr inbounds i8, i8* %Short, i64 %i.0
+  %tmp3 = bitcast i8* %tmp to i16*
+  %tmp4 = load i16, i16* %tmp3, align 2
+  %tmp5 = trunc i16 %tmp4 to i8
+  %tmp6 = getelementptr inbounds i8, i8* %Short, i64 %i.0
+  store i8 %tmp5, i8* %tmp6, align 1
+  %tmp7 = getelementptr inbounds i8, i8* %Float, i64 %i.0
+  %tmp8 = bitcast i8* %tmp7 to float*
+  %tmp9 = load float, float* %tmp8, align 4
+  %tmp10 = fptosi float %tmp9 to i8
+  %tmp11 = getelementptr inbounds i8, i8* %Float, i64 %i.0
+  store i8 %tmp10, i8* %tmp11, align 1
+  %tmp12 = getelementptr inbounds i8, i8* %Double, i64 %i.0
+  %tmp13 = bitcast i8* %tmp12 to double*
+  %tmp14 = load double, double* %tmp13, align 8
+  %tmp15 = fptosi double %tmp14 to i8
+  %tmp16 = getelementptr inbounds i8, i8* %Double, i64 %i.0
+  store i8 %tmp15, i8* %tmp16, align 1
+  br label %bb17
+
+bb17:                                             ; preds = %bb2
+  %tmp18 = add nuw nsw i64 %i.0, 1
+  br label %bb1
+
+bb19:                                             ; preds = %bb1
+  ret void
+}

Added: polly/trunk/test/ScopInfo/multiple-types.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multiple-types.ll?rev=259587&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/multiple-types.ll (added)
+++ polly/trunk/test/ScopInfo/multiple-types.ll Tue Feb  2 16:05:29 2016
@@ -0,0 +1,73 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+;    // Check that accessing one array with different types works.
+;    void multiple_types(char *Short, char *Float, char *Double) {
+;      for (long i = 0; i < 100; i++) {
+;        Short[i] = *(short *)&Short[2 * i];
+;        Float[i] = *(float *)&Float[4 * i];
+;        Double[i] = *(double *)&Double[8 * i];
+;      }
+;    }
+
+; CHECK: Statements {
+; CHECK-NEXT: Stmt_bb2
+; CHECK-NEXT: Domain :=
+; CHECK-NEXT:     { Stmt_bb2[i0] : 0 <= i0 <= 99 };
+; CHECK-NEXT: Schedule :=
+; CHECK-NEXT:     { Stmt_bb2[i0] -> [i0] };
+; CHECK-NEXT: ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT:     { Stmt_bb2[i0] -> MemRef_Short[o0] : 2i0 <= o0 <= 1 + 2i0 };
+; CHECK-NEXT: MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT:     { Stmt_bb2[i0] -> MemRef_Short[i0] };
+; CHECK-NEXT: ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT:     { Stmt_bb2[i0] -> MemRef_Float[o0] : 4i0 <= o0 <= 3 + 4i0 };
+; CHECK-NEXT: MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT:     { Stmt_bb2[i0] -> MemRef_Float[i0] };
+; CHECK-NEXT: ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT:     { Stmt_bb2[i0] -> MemRef_Double[o0] : 8i0 <= o0 <= 7 + 8i0 };
+; CHECK-NEXT: MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT:     { Stmt_bb2[i0] -> MemRef_Double[i0] };
+; CHECK-NEXT: }
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @multiple_types(i8* %Short, i8* %Float, i8* %Double) {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb20, %bb
+  %i.0 = phi i64 [ 0, %bb ], [ %tmp21, %bb20 ]
+  %exitcond = icmp ne i64 %i.0, 100
+  br i1 %exitcond, label %bb2, label %bb22
+
+bb2:                                              ; preds = %bb1
+  %tmp = shl nsw i64 %i.0, 1
+  %tmp3 = getelementptr inbounds i8, i8* %Short, i64 %tmp
+  %tmp4 = bitcast i8* %tmp3 to i16*
+  %tmp5 = load i16, i16* %tmp4, align 2
+  %tmp6 = trunc i16 %tmp5 to i8
+  %tmp7 = getelementptr inbounds i8, i8* %Short, i64 %i.0
+  store i8 %tmp6, i8* %tmp7, align 1
+  %tmp8 = shl nsw i64 %i.0, 2
+  %tmp9 = getelementptr inbounds i8, i8* %Float, i64 %tmp8
+  %tmp10 = bitcast i8* %tmp9 to float*
+  %tmp11 = load float, float* %tmp10, align 4
+  %tmp12 = fptosi float %tmp11 to i8
+  %tmp13 = getelementptr inbounds i8, i8* %Float, i64 %i.0
+  store i8 %tmp12, i8* %tmp13, align 1
+  %tmp14 = shl nsw i64 %i.0, 3
+  %tmp15 = getelementptr inbounds i8, i8* %Double, i64 %tmp14
+  %tmp16 = bitcast i8* %tmp15 to double*
+  %tmp17 = load double, double* %tmp16, align 8
+  %tmp18 = fptosi double %tmp17 to i8
+  %tmp19 = getelementptr inbounds i8, i8* %Double, i64 %i.0
+  store i8 %tmp18, i8* %tmp19, align 1
+  br label %bb20
+
+bb20:                                             ; preds = %bb2
+  %tmp21 = add nuw nsw i64 %i.0, 1
+  br label %bb1
+
+bb22:                                             ; preds = %bb1
+  ret void
+}




More information about the llvm-commits mailing list