[Hexagon] Use getTypeAllocSize to compute difference between objects
authorBrendon Cahoon <bcahoon@quicinc.com>
Tue, 14 Sep 2021 00:04:00 +0000 (19:04 -0500)
committerKrzysztof Parzyszek <kparzysz@quicinc.com>
Tue, 14 Sep 2021 00:04:59 +0000 (19:04 -0500)
The code was using getTypeStoreSize to calculate the difference
between consecutive objects. The calculation was incorrect due
to padding that is added between consecutive objects. The
getTypeAllocSize includes the padding amount. For example,
if the type is [19 x i8], the difference between consecutive
objects is 32 bytes, not 19 bytes.

A second case for getTypeAllocSize is needed when computing
the pointer values for the vector accesses. The calculation needs
to account for the padding as well.

Differential Revision: https://reviews.llvm.org/D109403

llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp
llvm/test/CodeGen/Hexagon/autohvx/vector-align-addr.ll [new file with mode: 0644]

index f949a93..fb01b7c 100644 (file)
@@ -82,6 +82,7 @@ public:
 
   int getSizeOf(const Value *Val) const;
   int getSizeOf(const Type *Ty) const;
+  int getAllocSizeOf(const Type *Ty) const;
   int getTypeAlignment(Type *Ty) const;
 
   VectorType *getByteVectorTy(int ScLen) const;
@@ -443,8 +444,8 @@ auto AlignVectors::createAdjustedPointer(IRBuilder<> &Builder, Value *Ptr,
   auto *PtrTy = cast<PointerType>(Ptr->getType());
   if (!PtrTy->isOpaque()) {
     Type *ElemTy = PtrTy->getElementType();
-    int ElemSize = HVC.getSizeOf(ElemTy);
-    if (Adjust % ElemSize == 0) {
+    int ElemSize = HVC.getAllocSizeOf(ElemTy);
+    if (Adjust % ElemSize == 0 && Adjust != 0) {
       Value *Tmp0 =
           Builder.CreateGEP(ElemTy, Ptr, HVC.getConstInt(Adjust / ElemSize));
       return Builder.CreatePointerCast(Tmp0, ValTy->getPointerTo());
@@ -979,6 +980,10 @@ auto HexagonVectorCombine::getSizeOf(const Type *Ty) const -> int {
   return DL.getTypeStoreSize(const_cast<Type *>(Ty)).getFixedValue();
 }
 
+auto HexagonVectorCombine::getAllocSizeOf(const Type *Ty) const -> int {
+  return DL.getTypeAllocSize(const_cast<Type *>(Ty)).getFixedValue();
+}
+
 auto HexagonVectorCombine::getTypeAlignment(Type *Ty) const -> int {
   // The actual type may be shorter than the HVX vector, so determine
   // the alignment based on subtarget info.
@@ -1326,7 +1331,7 @@ auto HexagonVectorCombine::calculatePointerDifference(Value *Ptr0,
     return None;
 
   Builder B(Gep0->getParent());
-  int Scale = DL.getTypeStoreSize(Gep0->getSourceElementType());
+  int Scale = getAllocSizeOf(Gep0->getSourceElementType());
 
   // FIXME: for now only check GEPs with a single index.
   if (Gep0->getNumOperands() != 2 || Gep1->getNumOperands() != 2)
diff --git a/llvm/test/CodeGen/Hexagon/autohvx/vector-align-addr.ll b/llvm/test/CodeGen/Hexagon/autohvx/vector-align-addr.ll
new file mode 100644 (file)
index 0000000..25ba8e6
--- /dev/null
@@ -0,0 +1,48 @@
+; RUN: llc -march=hexagon -hexagon-hvx-widen=32 < %s | FileCheck %s
+
+; Test that the Hexagon Vector Combine pass computes the address
+; correctly when the loading objects that contain extra padding
+; between successive objects.
+
+; CHECK: [[REG:r[0-9]+]] = add(r{{[0-9]+}},#2432)
+; CHECK: = vmem([[REG]]+#0)
+
+define dllexport void @test(i8* %a0) local_unnamed_addr #0 {
+b0:
+  %v0 = add nuw nsw i32 0, 3040
+  %v1 = load i8, i8* undef, align 1
+  %v2 = insertelement <19 x i8> undef, i8 %v1, i32 0
+  %v3 = shufflevector <19 x i8> %v2, <19 x i8> undef, <19 x i32> zeroinitializer
+  %v4 = getelementptr inbounds i8, i8* %a0, i32 %v0
+  %v5 = bitcast i8* %v4 to <19 x i8>*
+  %v6 = load <19 x i8>, <19 x i8>* %v5, align 1
+  %v7 = mul <19 x i8> %v3, %v6
+  %v8 = add <19 x i8> %v7, zeroinitializer
+  %v9 = add <19 x i8> zeroinitializer, %v8
+  %v10 = add <19 x i8> zeroinitializer, %v9
+  %v11 = add <19 x i8> zeroinitializer, %v10
+  %v12 = add <19 x i8> zeroinitializer, %v11
+  %v13 = add <19 x i8> zeroinitializer, %v12
+  %v14 = add <19 x i8> zeroinitializer, %v13
+  %v15 = add <19 x i8> zeroinitializer, %v14
+  %v16 = add <19 x i8> zeroinitializer, %v15
+  %v17 = add <19 x i8> zeroinitializer, %v16
+  %v18 = add <19 x i8> zeroinitializer, %v17
+  %v19 = load i8, i8* undef, align 1
+  %v20 = insertelement <19 x i8> undef, i8 %v19, i32 0
+  %v21 = shufflevector <19 x i8> %v20, <19 x i8> undef, <19 x i32> zeroinitializer
+  %v22 = add nuw nsw i32 0, 5472
+  %v23 = getelementptr inbounds i8, i8* %a0, i32 %v22
+  %v24 = bitcast i8* %v23 to <19 x i8>*
+  %v25 = load <19 x i8>, <19 x i8>* %v24, align 1
+  %v26 = mul <19 x i8> %v21, %v25
+  %v27 = add <19 x i8> %v26, %v18
+  %v28 = add <19 x i8> zeroinitializer, %v27
+  %v29 = add <19 x i8> zeroinitializer, %v28
+  %v30 = add <19 x i8> zeroinitializer, %v29
+  %v31 = bitcast i8* %a0 to <19 x i8>*
+  store <19 x i8> %v30, <19 x i8>* %v31, align 1
+  ret void
+}
+
+attributes #0 = { "target-features"="+hvxv66,+hvx-length128b" }