[clang] 57148e0 - [Hexagon] Fix ABI info for returning HVX vectors

Krzysztof Parzyszek via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 11 10:39:12 PST 2020


Author: Krzysztof Parzyszek
Date: 2020-02-11T12:38:54-06:00
New Revision: 57148e0379d30ecabd2a338c5bb9abbb3a0e314f

URL: https://github.com/llvm/llvm-project/commit/57148e0379d30ecabd2a338c5bb9abbb3a0e314f
DIFF: https://github.com/llvm/llvm-project/commit/57148e0379d30ecabd2a338c5bb9abbb3a0e314f.diff

LOG: [Hexagon] Fix ABI info for returning HVX vectors

Added: 
    clang/test/CodeGen/hexagon-hvx-abi.c

Modified: 
    clang/lib/CodeGen/TargetInfo.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index a3e3a38a1033..29998f361926 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -7486,13 +7486,10 @@ void TCETargetCodeGenInfo::setTargetAttributes(
 namespace {
 
 class HexagonABIInfo : public ABIInfo {
-
-
 public:
   HexagonABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
 
 private:
-
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
@@ -7505,14 +7502,14 @@ class HexagonABIInfo : public ABIInfo {
 class HexagonTargetCodeGenInfo : public TargetCodeGenInfo {
 public:
   HexagonTargetCodeGenInfo(CodeGenTypes &CGT)
-    :TargetCodeGenInfo(new HexagonABIInfo(CGT)) {}
+    : TargetCodeGenInfo(new HexagonABIInfo(CGT)) {}
 
   int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
     return 29;
   }
 };
 
-}
+} // namespace
 
 void HexagonABIInfo::computeInfo(CGFunctionInfo &FI) const {
   if (!getCXXABI().classifyReturnType(FI))
@@ -7527,8 +7524,8 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const {
     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
       Ty = EnumTy->getDecl()->getIntegerType();
 
-    return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                          : ABIArgInfo::getDirect());
+    return Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
+                                         : ABIArgInfo::getDirect();
   }
 
   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
@@ -7539,53 +7536,56 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const {
     return ABIArgInfo::getIgnore();
 
   uint64_t Size = getContext().getTypeSize(Ty);
-  if (Size > 64)
-    return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+  if (Size <= 64) {
     // Pass in the smallest viable integer type.
-  else if (Size > 32)
-      return ABIArgInfo::getDirect(llvm::Type::getInt64Ty(getVMContext()));
-  else if (Size > 16)
-      return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
-  else if (Size > 8)
-      return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
-  else
-      return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
+    if (!llvm::isPowerOf2_64(Size))
+      Size = llvm::NextPowerOf2(Size);
+    return ABIArgInfo::getDirect(llvm::Type::getIntNTy(getVMContext(), Size));
+  }
+  return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
 }
 
 ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const {
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
 
-  // Large vector types should be returned via memory.
-  if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 64)
-    return getNaturalAlignIndirect(RetTy);
+  const TargetInfo &T = CGT.getTarget();
+  uint64_t Size = getContext().getTypeSize(RetTy);
+
+  if (const auto *VecTy = RetTy->getAs<VectorType>()) {
+    // HVX vectors are returned in vector registers or register pairs.
+    if (T.hasFeature("hvx")) {
+      assert(T.hasFeature("hvx-length64b") || T.hasFeature("hvx-length128b"));
+      uint64_t VecSize = T.hasFeature("hvx-length64b") ? 64*8 : 128*8;
+      if (Size == VecSize || Size == 2*VecSize)
+        return ABIArgInfo::getDirectInReg();
+    }
+
+    // Large vector types should be returned via memory.
+    if (Size > 64)
+      return getNaturalAlignIndirect(RetTy);
+  }
 
   if (!isAggregateTypeForABI(RetTy)) {
     // Treat an enum type as its underlying type.
     if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
       RetTy = EnumTy->getDecl()->getIntegerType();
 
-    return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
-                                             : ABIArgInfo::getDirect());
+    return RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
+                                            : ABIArgInfo::getDirect();
   }
 
   if (isEmptyRecord(getContext(), RetTy, true))
     return ABIArgInfo::getIgnore();
 
-  // Aggregates <= 8 bytes are returned in r0; other aggregates
+  // Aggregates <= 8 bytes are returned in registers, other aggregates
   // are returned indirectly.
-  uint64_t Size = getContext().getTypeSize(RetTy);
   if (Size <= 64) {
     // Return in the smallest viable integer type.
-    if (Size <= 8)
-      return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
-    if (Size <= 16)
-      return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
-    if (Size <= 32)
-      return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
-    return ABIArgInfo::getDirect(llvm::Type::getInt64Ty(getVMContext()));
+    if (!llvm::isPowerOf2_64(Size))
+      Size = llvm::NextPowerOf2(Size);
+    return ABIArgInfo::getDirect(llvm::Type::getIntNTy(getVMContext(), Size));
   }
-
   return getNaturalAlignIndirect(RetTy, /*ByVal=*/true);
 }
 

diff  --git a/clang/test/CodeGen/hexagon-hvx-abi.c b/clang/test/CodeGen/hexagon-hvx-abi.c
new file mode 100644
index 000000000000..cd70f57e4ffc
--- /dev/null
+++ b/clang/test/CodeGen/hexagon-hvx-abi.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple hexagon -emit-llvm -target-cpu hexagonv66 -target-feature +hvxv66 -target-feature +hvx-length64b -o - %s | FileCheck %s --check-prefix CHECK-HVX64
+// RUN: %clang_cc1 -triple hexagon -emit-llvm -target-cpu hexagonv66 -target-feature +hvxv66 -target-feature +hvx-length128b -o - %s | FileCheck %s --check-prefix CHECK-HVX128
+
+typedef long HVX_Vector __attribute__((__vector_size__(__HVX_LENGTH__)))
+  __attribute__((aligned(__HVX_LENGTH__)));
+typedef long HVX_VectorPair __attribute__((__vector_size__(2*__HVX_LENGTH__)))
+  __attribute__((aligned(__HVX_LENGTH__)));
+
+// CHECK-HVX64: define {{.*}} <16 x i32> @foo(<16 x i32> %a, <32 x i32> %b)
+// CHECK-HVX128: define {{.*}} <32 x i32> @foo(<32 x i32> %a, <64 x i32> %b) 
+HVX_Vector foo(HVX_Vector a, HVX_VectorPair b) {
+  return a;
+}
+
+// CHECK-HVX64: define {{.*}} <32 x i32> @bar(<16 x i32> %a, <32 x i32> %b)
+// CHECK-HVX128: define {{.*}} <64 x i32> @bar(<32 x i32> %a, <64 x i32> %b)
+HVX_VectorPair bar(HVX_Vector a, HVX_VectorPair b) {
+  return b;
+}
+


        


More information about the cfe-commits mailing list