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

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 2 14:39:05 PST 2016


While I think we should allow accesses (not only loads) to the same base
pointer with different sizes (I mentioned this multiple times before), I
do not understand your patch. It does some lexmin magic and the comments
seem to be broken. In general I was wondering why you assume
  polly/trunk/test/ScopInfo/multiple-types-incorrect.ll
to be "incorrect" (without reverting to C semantics).

This said I would like three things from you now:
  1) Please explain this patch and fix the first two comments I
     inlined.
  2) Explain why this approach is right/better than the one I proposed
     at some point (see attachment).
  3) Think about pushing such patches on the review server first. While
     I know from experience that it can take quite a while to get
     feedback there, it seems odd when changes like this are just pushed
     without any kind of discussion or code review. If I am wrong about
     the last part, I will gladly revisit my policy of pushing patches
     to the review server first.

Cheers,
  Johannes

On 02/02, Tobias Grosser via llvm-commits wrote:
> 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);
@param missing.

>    /// @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
broken sentence?
> +  /// reads. In this case, the lexicograph smallest element is the memory
typo.
> +  /// address from which the largest element needs to be loaded from.
I don't get this.

>    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
> +}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits

-- 

Johannes Doerfert
Researcher / PhD Student

Compiler Design Lab (Prof. Hack)
Saarland University, Computer Science
Building E1.3, Room 4.31

Tel. +49 (0)681 302-57521 : doerfert at cs.uni-saarland.de
Fax. +49 (0)681 302-3065  : http://www.cdl.uni-saarland.de/people/doerfert
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Polly-Allow-different-element-sizes.patch
Type: text/x-diff
Size: 4066 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160202/be336426/attachment.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160202/be336426/attachment.sig>


More information about the llvm-commits mailing list