[llvm] 7ed515d - [AIX][XCOFF] emit vector info of traceback table.

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 14 08:15:44 PDT 2021


Author: zhijian
Date: 2021-06-14T11:15:22-04:00
New Revision: 7ed515d16803f12fc06258ebf8a405931dc8a637

URL: https://github.com/llvm/llvm-project/commit/7ed515d16803f12fc06258ebf8a405931dc8a637
DIFF: https://github.com/llvm/llvm-project/commit/7ed515d16803f12fc06258ebf8a405931dc8a637.diff

LOG: [AIX][XCOFF] emit vector info of traceback table.

Summary:

emit vector info of traceback table.

Reviewers: Jason Liu,Hubert Tong
Differential Revision: https://reviews.llvm.org/D93659

Added: 
    llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll
    llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo_hasvarg.ll

Modified: 
    llvm/include/llvm/BinaryFormat/XCOFF.h
    llvm/include/llvm/CodeGen/MachineRegisterInfo.h
    llvm/include/llvm/Object/XCOFFObjectFile.h
    llvm/lib/BinaryFormat/XCOFF.cpp
    llvm/lib/CodeGen/MachineRegisterInfo.cpp
    llvm/lib/Object/XCOFFObjectFile.cpp
    llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
    llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
    llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll
    llvm/test/CodeGen/PowerPC/aix-exception.ll
    llvm/test/DebugInfo/XCOFF/explicit-section.ll
    llvm/unittests/Object/XCOFFObjectFileTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h
index bd2f0ee11d4e3..cf56adffef107 100644
--- a/llvm/include/llvm/BinaryFormat/XCOFF.h
+++ b/llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -19,6 +19,7 @@
 namespace llvm {
 class StringRef;
 template <unsigned> class SmallString;
+template <typename T> class Expected;
 
 namespace XCOFF {
 
@@ -286,7 +287,14 @@ enum SymbolAuxType : uint8_t {
 
 StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
 StringRef getRelocationTypeString(XCOFF::RelocationType Type);
-SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum);
+Expected<SmallString<32>> parseParmsType(uint32_t Value, unsigned FixedParmsNum,
+                                         unsigned FloatingParmsNum);
+Expected<SmallString<32>> parseParmsTypeWithVecInfo(uint32_t Value,
+                                                    unsigned FixedParmsNum,
+                                                    unsigned FloatingParmsNum,
+                                                    unsigned VectorParmsNum);
+Expected<SmallString<32>> parseVectorParmsType(uint32_t Value,
+                                               unsigned ParmsNum);
 
 struct TracebackTable {
   enum LanguageID : uint8_t {
@@ -381,6 +389,8 @@ struct TracebackTable {
   static constexpr uint32_t ParmTypeIsVectorShortBit = 0x4000'0000;
   static constexpr uint32_t ParmTypeIsVectorIntBit = 0x8000'0000;
   static constexpr uint32_t ParmTypeIsVectorFloatBit = 0xC000'0000;
+
+  static constexpr uint8_t WidthOfParamType = 2;
 };
 
 // Extended Traceback table flags.

diff  --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index c0cb095be3ef2..ca3dd992bbd50 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -857,9 +857,9 @@ class MachineRegisterInfo {
 
   /// Return true if the specified register is modified or read in this
   /// function. This checks that no machine operands exist for the register or
-  /// any of its aliases. The register is also considered used when it is set
-  /// in the UsedPhysRegMask.
-  bool isPhysRegUsed(MCRegister PhysReg) const;
+  /// any of its aliases. If SkipRegMaskTest is false, the register is
+  /// considered used when it is set in the UsedPhysRegMask.
+  bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest = false) const;
 
   /// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
   /// This corresponds to the bit mask attached to register mask operands.

diff  --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
index 12d550f69d597..fce555bffd9b0 100644
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -538,20 +538,19 @@ class XCOFFSymbolRef {
 };
 
 class TBVectorExt {
-  friend class XCOFFTracebackTable;
-
   uint16_t Data;
-  uint32_t VecParmsInfo;
+  SmallString<32> VecParmsInfo;
 
-  TBVectorExt(StringRef TBvectorStrRef);
+  TBVectorExt(StringRef TBvectorStrRef, Error &Err);
 
 public:
+  static Expected<TBVectorExt> create(StringRef TBvectorStrRef);
   uint8_t getNumberOfVRSaved() const;
   bool isVRSavedOnStack() const;
   bool hasVarArgs() const;
   uint8_t getNumberOfVectorParms() const;
   bool hasVMXInstruction() const;
-  SmallString<32> getVectorParmsInfoString() const;
+  SmallString<32> getVectorParmsInfo() const { return VecParmsInfo; };
 };
 
 /// This class provides methods to extract traceback table data from a buffer.

diff  --git a/llvm/lib/BinaryFormat/XCOFF.cpp b/llvm/lib/BinaryFormat/XCOFF.cpp
index 0f270a5cea1b9..fd5d8568b62ff 100644
--- a/llvm/lib/BinaryFormat/XCOFF.cpp
+++ b/llvm/lib/BinaryFormat/XCOFF.cpp
@@ -9,6 +9,8 @@
 #include "llvm/BinaryFormat/XCOFF.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
 
 using namespace llvm;
 
@@ -76,6 +78,7 @@ StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
   }
   return "Unknown";
 }
+#undef RELOC_CASE
 
 #define LANG_CASE(A)                                                           \
   case XCOFF::TracebackTable::A:                                               \
@@ -104,15 +107,25 @@ StringRef XCOFF::getNameForTracebackTableLanguageId(
 }
 #undef LANG_CASE
 
-SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
+Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,
+                                                unsigned FixedParmsNum,
+                                                unsigned FloatingParmsNum) {
   SmallString<32> ParmsType;
-  for (unsigned I = 0; I < ParmsNum; ++I) {
-    if (I != 0)
+  int Bits = 0;
+  unsigned ParsedFixedNum = 0;
+  unsigned ParsedFloatingNum = 0;
+  unsigned ParsedNum = 0;
+  unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;
+
+  while (Bits < 32 && ParsedNum < ParmsNum) {
+    if (++ParsedNum > 1)
       ParmsType += ", ";
     if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
       // Fixed parameter type.
       ParmsType += "i";
+      ++ParsedFixedNum;
       Value <<= 1;
+      ++Bits;
     } else {
       if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
         // Float parameter type.
@@ -120,11 +133,21 @@ SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
       else
         // Double parameter type.
         ParmsType += "d";
-
+      ++ParsedFloatingNum;
       Value <<= 2;
+      Bits += 2;
     }
   }
-  assert(Value == 0u && "ParmsType encodes more than ParmsNum parameters.");
+
+  // We have more parameters than the 32 Bits could encode.
+  if (ParsedNum < ParmsNum)
+    ParmsType += ", ...";
+
+  if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
+      ParsedFloatingNum > FloatingParmsNum)
+    return createStringError(errc::invalid_argument,
+                             "ParmsType encodes can not map to ParmsNum "
+                             "parameters in parseParmsType.");
   return ParmsType;
 }
 
@@ -153,4 +176,94 @@ SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
   return Res;
 }
 
-#undef RELOC_CASE
+Expected<SmallString<32>>
+XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,
+                                 unsigned FloatingParmsNum,
+                                 unsigned VectorParmsNum) {
+  SmallString<32> ParmsType;
+
+  unsigned ParsedFixedNum = 0;
+  unsigned ParsedFloatingNum = 0;
+  unsigned ParsedVectorNum = 0;
+  unsigned ParsedNum = 0;
+  unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;
+
+  for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {
+    if (++ParsedNum > 1)
+      ParmsType += ", ";
+
+    switch (Value & TracebackTable::ParmTypeMask) {
+    case TracebackTable::ParmTypeIsFixedBits:
+      ParmsType += "i";
+      ++ParsedFixedNum;
+      break;
+    case TracebackTable::ParmTypeIsVectorBits:
+      ParmsType += "v";
+      ++ParsedVectorNum;
+      break;
+    case TracebackTable::ParmTypeIsFloatingBits:
+      ParmsType += "f";
+      ++ParsedFloatingNum;
+      break;
+    case TracebackTable::ParmTypeIsDoubleBits:
+      ParmsType += "d";
+      ++ParsedFloatingNum;
+      break;
+    default:
+      assert(false && "Unrecognized bits in ParmsType.");
+    }
+    Value <<= 2;
+  }
+
+  // We have more parameters than the 32 Bits could encode.
+  if (ParsedNum < ParmsNum)
+    ParmsType += ", ...";
+
+  if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
+      ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)
+    return createStringError(
+        errc::invalid_argument,
+        "ParmsType encodes can not map to ParmsNum parameters "
+        "in parseParmsTypeWithVecInfo.");
+
+  return ParmsType;
+}
+
+Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,
+                                                      unsigned ParmsNum) {
+  SmallString<32> ParmsType;
+  unsigned ParsedNum = 0;
+  for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {
+    if (++ParsedNum > 1)
+      ParmsType += ", ";
+    switch (Value & TracebackTable::ParmTypeMask) {
+    case TracebackTable::ParmTypeIsVectorCharBit:
+      ParmsType += "vc";
+      break;
+
+    case TracebackTable::ParmTypeIsVectorShortBit:
+      ParmsType += "vs";
+      break;
+
+    case TracebackTable::ParmTypeIsVectorIntBit:
+      ParmsType += "vi";
+      break;
+
+    case TracebackTable::ParmTypeIsVectorFloatBit:
+      ParmsType += "vf";
+      break;
+    }
+
+    Value <<= 2;
+  }
+
+  // We have more parameters than the 32 Bits could encode.
+  if (ParsedNum < ParmsNum)
+    ParmsType += ", ...";
+
+  if (Value != 0u)
+    return createStringError(errc::invalid_argument,
+                             "ParmsType encodes more than ParmsNum parameters "
+                             "in parseVectorParmsType.");
+  return ParmsType;
+}

diff  --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 58bb86688d31c..3f6b11e072b48 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -582,8 +582,9 @@ bool MachineRegisterInfo::isPhysRegModified(MCRegister PhysReg,
   return false;
 }
 
-bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg) const {
-  if (UsedPhysRegMask.test(PhysReg))
+bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg,
+                                        bool SkipRegMaskTest) const {
+  if (!SkipRegMaskTest && UsedPhysRegMask.test(PhysReg))
     return true;
   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
   for (MCRegAliasIterator AliasReg(PhysReg, TRI, true); AliasReg.isValid();

diff  --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index 8c2a0ead45c82..a03627f2097e9 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -900,15 +900,34 @@ bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
   return support::endian::read32be(Bytes.data()) == 0;
 }
 
-TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
+#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
+#define GETVALUEWITHMASKSHIFT(X, S)                                            \
+  ((Data & (TracebackTable::X)) >> (TracebackTable::S))
+
+Expected<TBVectorExt> TBVectorExt::create(StringRef TBvectorStrRef) {
+  Error Err = Error::success();
+  TBVectorExt TBTVecExt(TBvectorStrRef, Err);
+  if (Err)
+    return std::move(Err);
+  return TBTVecExt;
+}
+
+TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
   const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
   Data = support::endian::read16be(Ptr);
-  VecParmsInfo = support::endian::read32be(Ptr + 2);
+  uint32_t VecParmsTypeValue = support::endian::read32be(Ptr + 2);
+  unsigned ParmsNum =
+      GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask, NumberOfVectorParmsShift);
+
+  ErrorAsOutParameter EAO(&Err);
+  Expected<SmallString<32>> VecParmsTypeOrError =
+      parseVectorParmsType(VecParmsTypeValue, ParmsNum);
+  if (!VecParmsTypeOrError)
+    Err = VecParmsTypeOrError.takeError();
+  else
+    VecParmsInfo = VecParmsTypeOrError.get();
 }
 
-#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
-#define GETVALUEWITHMASKSHIFT(X, S)                                            \
-  ((Data & (TracebackTable::X)) >> (TracebackTable::S))
 uint8_t TBVectorExt::getNumberOfVRSaved() const {
   return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
 }
@@ -920,6 +939,7 @@ bool TBVectorExt::isVRSavedOnStack() const {
 bool TBVectorExt::hasVarArgs() const {
   return GETVALUEWITHMASK(HasVarArgsMask);
 }
+
 uint8_t TBVectorExt::getNumberOfVectorParms() const {
   return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
                                NumberOfVectorParmsShift);
@@ -931,72 +951,6 @@ bool TBVectorExt::hasVMXInstruction() const {
 #undef GETVALUEWITHMASK
 #undef GETVALUEWITHMASKSHIFT
 
-SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
-  SmallString<32> ParmsType;
-  uint32_t Value = VecParmsInfo;
-  for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
-    if (I != 0)
-      ParmsType += ", ";
-    switch (Value & TracebackTable::ParmTypeMask) {
-    case TracebackTable::ParmTypeIsVectorCharBit:
-      ParmsType += "vc";
-      break;
-
-    case TracebackTable::ParmTypeIsVectorShortBit:
-      ParmsType += "vs";
-      break;
-
-    case TracebackTable::ParmTypeIsVectorIntBit:
-      ParmsType += "vi";
-      break;
-
-    case TracebackTable::ParmTypeIsVectorFloatBit:
-      ParmsType += "vf";
-      break;
-    }
-    Value <<= 2;
-  }
-  return ParmsType;
-}
-
-static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
-                                                 unsigned int ParmsNum) {
-  SmallString<32> ParmsType;
-  unsigned I = 0;
-  bool Begin = false;
-  while (I < ParmsNum || Value) {
-    if (Begin)
-      ParmsType += ", ";
-    else
-      Begin = true;
-
-    switch (Value & TracebackTable::ParmTypeMask) {
-    case TracebackTable::ParmTypeIsFixedBits:
-      ParmsType += "i";
-      ++I;
-      break;
-    case TracebackTable::ParmTypeIsVectorBits:
-      ParmsType += "v";
-      break;
-    case TracebackTable::ParmTypeIsFloatingBits:
-      ParmsType += "f";
-      ++I;
-      break;
-    case TracebackTable::ParmTypeIsDoubleBits:
-      ParmsType += "d";
-      ++I;
-      break;
-    default:
-      assert(false && "Unrecognized bits in ParmsType.");
-    }
-    Value <<= 2;
-  }
-  assert(I == ParmsNum &&
-         "The total parameters number of fixed-point or floating-point "
-         "parameters not equal to the number in the parameter type!");
-  return ParmsType;
-}
-
 Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
                                                           uint64_t &Size) {
   Error Err = Error::success();
@@ -1017,21 +971,13 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
   // Skip 8 bytes of mandatory fields.
   DE.getU64(Cur);
 
+  unsigned FixedParmsNum = getNumberOfFixedParms();
+  unsigned FloatingParmsNum = getNumberOfFPParms();
+  uint32_t ParamsTypeValue = 0;
+
   // Begin to parse optional fields.
-  if (Cur) {
-    unsigned ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
-
-    // As long as there are no "fixed-point" or floating-point parameters, this
-    // field remains not present even when hasVectorInfo gives true and
-    // indicates the presence of vector parameters.
-    if (ParmNum > 0) {
-      uint32_t ParamsTypeValue = DE.getU32(Cur);
-      if (Cur)
-        ParmsType = hasVectorInfo()
-                        ? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
-                        : parseParmsType(ParamsTypeValue, ParmNum);
-    }
-  }
+  if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
+    ParamsTypeValue = DE.getU32(Cur);
 
   if (Cur && hasTraceBackTableOffset())
     TraceBackTableOffset = DE.getU32(Cur);
@@ -1060,10 +1006,35 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
   if (Cur && isAllocaUsed())
     AllocaRegister = DE.getU8(Cur);
 
+  unsigned VectorParmsNum = 0;
   if (Cur && hasVectorInfo()) {
     StringRef VectorExtRef = DE.getBytes(Cur, 6);
-    if (Cur)
-      VecExt = TBVectorExt(VectorExtRef);
+    if (Cur) {
+      Expected<TBVectorExt> TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
+      if (!TBVecExtOrErr) {
+        Err = TBVecExtOrErr.takeError();
+        return;
+      }
+      VecExt = TBVecExtOrErr.get();
+      VectorParmsNum = VecExt.getValue().getNumberOfVectorParms();
+    }
+  }
+
+  // As long as there is no fixed-point or floating-point parameter, this
+  // field remains not present even when hasVectorInfo gives true and
+  // indicates the presence of vector parameters.
+  if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
+    Expected<SmallString<32>> ParmsTypeOrError =
+        hasVectorInfo()
+            ? parseParmsTypeWithVecInfo(ParamsTypeValue, FixedParmsNum,
+                                        FloatingParmsNum, VectorParmsNum)
+            : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
+
+    if (!ParmsTypeOrError) {
+      Err = ParmsTypeOrError.takeError();
+      return;
+    }
+    ParmsType = ParmsTypeOrError.get();
   }
 
   if (Cur && hasExtensionTable())
@@ -1071,6 +1042,7 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
 
   if (!Cur)
     Err = Cur.takeError();
+
   Size = Cur.tell();
 }
 

diff  --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 813faf3e3d37e..fa65f54b4eabf 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -61,6 +61,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/TargetRegistry.h"
@@ -1940,7 +1941,7 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
 
   // Check the function uses floating-point processor instructions or not
   for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
-    if (MRI.isPhysRegUsed(Reg)) {
+    if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
       FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
       break;
     }
@@ -1980,7 +1981,8 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
   FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;
 
   static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!");
-  if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
+  if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31,
+                        /* SkipRegMaskTest */ true))
     FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
 
   const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
@@ -2025,6 +2027,20 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
       (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
 
   // Set the 6th byte of mandatory field.
+
+  // Check whether has Vector Instruction,We only treat instructions uses vector
+  // register as vector instructions.
+  bool HasVectorInst = false;
+  for (unsigned Reg = PPC::V0; Reg <= PPC::V31; ++Reg)
+    if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
+      // Has VMX instruction.
+      HasVectorInst = true;
+      break;
+    }
+
+  if (FI->hasVectorParms() || HasVectorInst)
+    SecondHalfOfMandatoryField |= TracebackTable::HasVectorInfoMask;
+
   bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF);
   if (ShouldEmitEHBlock)
     SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;
@@ -2053,9 +2069,9 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
       (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
 
   // Set the 7th byte of mandatory field.
-  uint32_t NumberOfFixedPara = FI->getFixedParamNum();
+  uint32_t NumberOfFixedParms = FI->getFixedParmsNum();
   SecondHalfOfMandatoryField |=
-      (NumberOfFixedPara << TracebackTable::NumberOfFixedParmsShift) &
+      (NumberOfFixedParms << TracebackTable::NumberOfFixedParmsShift) &
       TracebackTable::NumberOfFixedParmsMask;
   GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
                   NumberOfFixedParms);
@@ -2068,9 +2084,9 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
   // Always set parameter on stack.
   SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;
 
-  uint32_t NumberOfFPPara = FI->getFloatingPointParamNum();
+  uint32_t NumberOfFPParms = FI->getFloatingPointParmsNum();
   SecondHalfOfMandatoryField |=
-      (NumberOfFPPara << TracebackTable::NumberOfFloatingPointParmsShift) &
+      (NumberOfFPParms << TracebackTable::NumberOfFloatingPointParmsShift) &
       TracebackTable::NumberOfFloatingPointParmsMask;
 
   GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
@@ -2083,18 +2099,25 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
   // Generate the optional fields of traceback table.
 
   // Parameter type.
-  if (NumberOfFixedPara || NumberOfFPPara) {
-    assert((SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) ==
-               0 &&
-           "VectorInfo has not been implemented.");
-    uint32_t ParaType = FI->getParameterType();
-    CommentOS << "Parameter type = "
-              << XCOFF::parseParmsType(ParaType,
-                                       NumberOfFixedPara + NumberOfFPPara);
-    EmitComment();
-    OutStreamer->emitIntValueInHexWithPadding(ParaType, sizeof(ParaType));
+  if (NumberOfFixedParms || NumberOfFPParms) {
+    uint32_t ParmsTypeValue = FI->getParmsType();
+
+    Expected<SmallString<32>> ParmsType =
+        FI->hasVectorParms()
+            ? XCOFF::parseParmsTypeWithVecInfo(
+                  ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
+                  FI->getVectorParmsNum())
+            : XCOFF::parseParmsType(ParmsTypeValue, NumberOfFixedParms,
+                                    NumberOfFPParms);
+
+    assert(ParmsType && toString(ParmsType.takeError()).c_str());
+    if (ParmsType) {
+      CommentOS << "Parameter type = " << ParmsType.get();
+      EmitComment();
+    }
+    OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
+                                              sizeof(ParmsTypeValue));
   }
-
   // Traceback table offset.
   OutStreamer->AddComment("Function size");
   if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
@@ -2126,6 +2149,69 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
     OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
   }
 
+  if (SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) {
+    uint16_t VRData = 0;
+    // Calculate the number of VRs be saved.
+    // Vector registers 20 through 31 are marked as reserved and cannot be used
+    // in the default ABI.
+    const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
+    if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
+        TM.getAIXExtendedAltivecABI()) {
+      for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)
+        if (MRI.isPhysRegModified(Reg)) {
+          // Number of VRs saved.
+          VRData |=
+              ((PPC::V31 - Reg + 1) << TracebackTable::NumberOfVRSavedShift) &
+              TracebackTable::NumberOfVRSavedMask;
+          // This bit is supposed to set only when the special register
+          // VRSAVE is saved on stack.
+          // However, IBM XL compiler sets the bit when any vector registers
+          // are saved on the stack. We will follow XL's behavior on AIX
+          // so that we don't get surprise behavior change for C code.
+          VRData |= TracebackTable::IsVRSavedOnStackMask;
+          break;
+        }
+    }
+
+    // Set has_varargs.
+    if (FI->getVarArgsFrameIndex())
+      VRData |= TracebackTable::HasVarArgsMask;
+
+    // Vector parameters number.
+    unsigned VectorParmsNum = FI->getVectorParmsNum();
+    VRData |= (VectorParmsNum << TracebackTable::NumberOfVectorParmsShift) &
+              TracebackTable::NumberOfVectorParmsMask;
+
+    if (HasVectorInst)
+      VRData |= TracebackTable::HasVMXInstructionMask;
+
+    GENVALUECOMMENT("NumOfVRsSaved", VRData, NumberOfVRSaved);
+    GENBOOLCOMMENT(", ", VRData, IsVRSavedOnStack);
+    GENBOOLCOMMENT(", ", VRData, HasVarArgs);
+    EmitComment();
+    OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
+
+    GENVALUECOMMENT("NumOfVectorParams", VRData, NumberOfVectorParms);
+    GENBOOLCOMMENT(", ", VRData, HasVMXInstruction);
+    EmitComment();
+    OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
+
+    uint32_t VecParmTypeValue = FI->getVecExtParmsType();
+
+    Expected<SmallString<32>> VecParmsType =
+        XCOFF::parseVectorParmsType(VecParmTypeValue, VectorParmsNum);
+    assert(VecParmsType && toString(VecParmsType.takeError()).c_str());
+    if (VecParmsType) {
+      CommentOS << "Vector Parameter type = " << VecParmsType.get();
+      EmitComment();
+    }
+    OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
+                                              sizeof(VecParmTypeValue));
+    // Padding 2 bytes.
+    CommentOS << "Padding";
+    EmitCommentAndValue(0, 2);
+  }
+
   uint8_t ExtensionTableFlag = 0;
   if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
     if (ShouldEmitEHBlock)
@@ -2156,7 +2242,6 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
     OutStreamer->AddComment("EHInfo Table");
     OutStreamer->emitValue(Exp, DL.getPointerSize());
   }
-
 #undef GENBOOLCOMMENT
 #undef GENVALUECOMMENT
 }

diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 2dc948c081cb3..4730a6d3d769a 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -6954,10 +6954,38 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
     if (VA.isRegLoc()) {
       if (VA.getValVT().isScalarInteger())
         FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
-      else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector())
-        FuncInfo->appendParameterType(VA.getValVT().SimpleTy == MVT::f32
-                                          ? PPCFunctionInfo::ShortFloatPoint
-                                          : PPCFunctionInfo::LongFloatPoint);
+      else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector()) {
+        switch (VA.getValVT().SimpleTy) {
+        default:
+          report_fatal_error("Unhandled value type for argument.");
+        case MVT::f32:
+          FuncInfo->appendParameterType(PPCFunctionInfo::ShortFloatingPoint);
+          break;
+        case MVT::f64:
+          FuncInfo->appendParameterType(PPCFunctionInfo::LongFloatingPoint);
+          break;
+        }
+      } else if (VA.getValVT().isVector()) {
+        switch (VA.getValVT().SimpleTy) {
+        default:
+          report_fatal_error("Unhandled value type for argument.");
+        case MVT::v16i8:
+          FuncInfo->appendParameterType(PPCFunctionInfo::VectorChar);
+          break;
+        case MVT::v8i16:
+          FuncInfo->appendParameterType(PPCFunctionInfo::VectorShort);
+          break;
+        case MVT::v4i32:
+        case MVT::v2i64:
+        case MVT::v1i128:
+          FuncInfo->appendParameterType(PPCFunctionInfo::VectorInt);
+          break;
+        case MVT::v4f32:
+        case MVT::v2f64:
+          FuncInfo->appendParameterType(PPCFunctionInfo::VectorFloat);
+          break;
+        }
+      }
     }
 
     if (Flags.isByVal() && VA.isMemLoc()) {

diff  --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
index c976a9c62d3bf..782d41f93ae53 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
@@ -66,34 +66,122 @@ bool PPCFunctionInfo::isLiveInZExt(Register VReg) const {
 }
 
 void PPCFunctionInfo::appendParameterType(ParamType Type) {
-  uint32_t CopyParamType = ParameterType;
-  int Bits = 0;
 
-  // If it is fixed type, we only need to increase the FixedParamNum, for
-  // the bit encode of fixed type is bit of zero, we do not need to change the
-  // ParamType.
-  if (Type == FixedType) {
-    ++FixedParamNum;
+  ParamtersType.push_back(Type);
+  switch (Type) {
+  case FixedType:
+    ++FixedParmsNum;
+    return;
+  case ShortFloatingPoint:
+  case LongFloatingPoint:
+    ++FloatingParmsNum;
     return;
+  case VectorChar:
+  case VectorShort:
+  case VectorInt:
+  case VectorFloat:
+    ++VectorParmsNum;
+    return;
+  }
+  llvm_unreachable("Error ParamType type.");
+}
+
+uint32_t PPCFunctionInfo::getVecExtParmsType() const {
+
+  uint32_t VectExtParamInfo = 0;
+  unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
+  int Bits = 0;
+
+  if (!hasVectorParms())
+    return 0;
+
+  for (const auto &Elt : ParamtersType) {
+    switch (Elt) {
+    case VectorChar:
+      VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+      VectExtParamInfo |=
+          XCOFF::TracebackTable::ParmTypeIsVectorCharBit >> ShiftBits;
+      Bits += XCOFF::TracebackTable::WidthOfParamType;
+      break;
+    case VectorShort:
+      VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+      VectExtParamInfo |=
+          XCOFF::TracebackTable::ParmTypeIsVectorShortBit >> ShiftBits;
+      Bits += XCOFF::TracebackTable::WidthOfParamType;
+      break;
+    case VectorInt:
+      VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+      VectExtParamInfo |=
+          XCOFF::TracebackTable::ParmTypeIsVectorIntBit >> ShiftBits;
+      Bits += XCOFF::TracebackTable::WidthOfParamType;
+      break;
+    case VectorFloat:
+      VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+      VectExtParamInfo |=
+          XCOFF::TracebackTable::ParmTypeIsVectorFloatBit >> ShiftBits;
+      Bits += XCOFF::TracebackTable::WidthOfParamType;
+      break;
+    default:
+      break;
+    }
+
+    // There are only 32bits in the VectExtParamInfo.
+    if (Bits >= 32)
+      break;
   }
+  return Bits < 32 ? VectExtParamInfo << (32 - Bits) : VectExtParamInfo;
+}
+
+uint32_t PPCFunctionInfo::getParmsType() const {
+  uint32_t ParamsTypeInfo = 0;
+  unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
+
+  int Bits = 0;
+  for (const auto &Elt : ParamtersType) {
 
-  ++FloatingPointParamNum;
+    if (Bits > 31 || (Bits > 30 && (Elt != FixedType || hasVectorParms())))
+      break;
 
-  for (int I = 0;
-       I < static_cast<int>(FloatingPointParamNum + FixedParamNum - 1); ++I) {
-    if (CopyParamType & XCOFF::TracebackTable::ParmTypeIsFloatingBit) {
+    switch (Elt) {
+    case FixedType:
+      if (hasVectorParms()) {
+        //'00'  ==> fixed parameter if HasVectorParms is true.
+        ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+        ParamsTypeInfo |=
+            XCOFF::TracebackTable::ParmTypeIsFixedBits >> ShiftBits;
+        Bits += XCOFF::TracebackTable::WidthOfParamType;
+      } else {
+        //'0'  ==> fixed parameter if HasVectorParms is false.
+        ParamsTypeInfo <<= 1;
+        ++Bits;
+      }
+      break;
+    case ShortFloatingPoint:
       // '10'b => floating point short parameter.
+      ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+      ParamsTypeInfo |=
+          XCOFF::TracebackTable::ParmTypeIsFloatingBits >> ShiftBits;
+      Bits += XCOFF::TracebackTable::WidthOfParamType;
+      break;
+    case LongFloatingPoint:
       // '11'b => floating point long parameter.
-      CopyParamType <<= 2;
-      Bits += 2;
-    } else {
-      // '0'b => fixed parameter.
-      CopyParamType <<= 1;
-      ++Bits;
+      ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+      ParamsTypeInfo |=
+          XCOFF::TracebackTable::ParmTypeIsDoubleBits >> ShiftBits;
+      Bits += XCOFF::TracebackTable::WidthOfParamType;
+      break;
+    case VectorChar:
+    case VectorShort:
+    case VectorInt:
+    case VectorFloat:
+      //	'01' ==> vector parameter
+      ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+      ParamsTypeInfo |=
+          XCOFF::TracebackTable::ParmTypeIsVectorBits >> ShiftBits;
+      Bits += XCOFF::TracebackTable::WidthOfParamType;
+      break;
     }
   }
 
-  assert(Type != FixedType && "FixedType should already be handled.");
-  if (Bits < 31)
-    ParameterType |= Type << (30 - Bits);
+  return Bits < 32 ? ParamsTypeInfo << (32 - Bits) : ParamsTypeInfo;
 }

diff  --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index 6a2de53814d8f..07c503d47e981 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -23,12 +23,14 @@ namespace llvm {
 /// PowerPC target-specific information for each MachineFunction.
 class PPCFunctionInfo : public MachineFunctionInfo {
 public:
-  // The value in the ParamType are used to indicate the bitstrings used in the
-  // encoding format.
   enum ParamType {
-    FixedType = 0x0,
-    ShortFloatPoint = 0x2,
-    LongFloatPoint = 0x3
+    FixedType,
+    ShortFloatingPoint,
+    LongFloatingPoint,
+    VectorChar,
+    VectorShort,
+    VectorInt,
+    VectorFloat
   };
 
 private:
@@ -120,19 +122,18 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   /// register for parameter passing.
   unsigned VarArgsNumFPR = 0;
 
-  /// FixedParamNum - Number of fixed parameter.
-  unsigned FixedParamNum = 0;
+  /// FixedParmsNum - The number of fixed parameters.
+  unsigned FixedParmsNum = 0;
 
-  /// FloatingParamNum - Number of floating point parameter.
-  unsigned FloatingPointParamNum = 0;
+  /// FloatingParmsNum - The number of floating parameters.
+  unsigned FloatingParmsNum = 0;
 
-  /// ParamType - Encode type for every parameter
-  /// in the order of parameters passing in.
-  /// Bitstring starts from the most significant (leftmost) bit.
-  /// '0'b => fixed parameter.
-  /// '10'b => floating point short parameter.
-  /// '11'b => floating point long parameter.
-  uint32_t ParameterType = 0;
+  /// VectorParmsNum - The number of vector parameters.
+  unsigned VectorParmsNum = 0;
+
+  /// ParamtersType - Store all the parameter's type that are saved on
+  /// registers.
+  SmallVector<ParamType, 32> ParamtersType;
 
   /// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
   int CRSpillFrameIndex = 0;
@@ -224,11 +225,15 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
   void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
 
-  unsigned getFixedParamNum() const { return FixedParamNum; }
+  unsigned getFixedParmsNum() const { return FixedParmsNum; }
+  unsigned getFloatingPointParmsNum() const { return FloatingParmsNum; }
+  unsigned getVectorParmsNum() const { return VectorParmsNum; }
+  bool hasVectorParms() const { return VectorParmsNum != 0; }
+
+  uint32_t getParmsType() const;
 
-  unsigned getFloatingPointParamNum() const { return FloatingPointParamNum; }
+  uint32_t getVecExtParmsType() const;
 
-  uint32_t getParameterType() const { return ParameterType; }
   void appendParameterType(ParamType Type);
 
   unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }

diff  --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll
index d14f647eca0f7..12a4e014bb19a 100644
--- a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll
@@ -1,9 +1,9 @@
 ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
-; RUN:     -mattr=-altivec -xcoff-traceback-table=true < %s | \
+; RUN:     -mattr=+altivec -vec-extabi -xcoff-traceback-table=true < %s | \
 ; RUN:   FileCheck --check-prefixes=CHECK-ASM,COMMON %s
 
 ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -function-sections \
-; RUN:     -mcpu=pwr4 -mattr=-altivec < %s | \
+; RUN:     -mcpu=pwr4 -mattr=+altivec -vec-extabi  < %s | \
 ; RUN:   FileCheck --check-prefixes=CHECK-FUNC,COMMON %s
 
 define float @bar() #0 {
@@ -26,6 +26,16 @@ entry:
   ret float %add
 }
 
+define <4 x i32> @foov() #0 {
+entry:
+  %taken = alloca <4 x i32>, align 16
+  %data = alloca <4 x i32>, align 16
+  store <4 x i32> <i32 123, i32 0, i32 0, i32 0>, <4 x i32>* %data, align 16
+  call void asm sideeffect "", "~{v31},~{v30},~{v29},~{v28}"() 
+  %0 = load <4 x i32>, <4 x i32>* %taken, align 16
+  ret <4 x i32> %0
+}
+
 ; COMMON:       .vbyte  4, 0x00000000                   # Traceback table begin
 ; COMMON-NEXT:  .byte   0x00                            # Version = 0
 ; COMMON-NEXT:  .byte   0x09                            # Language = CPlusPlus
@@ -46,3 +56,28 @@ entry:
 ; COMMON-NEXT:  .byte   "bar"                           # Function Name
 ; COMMON-NEXT:  .byte   0x1f                            # AllocaUsed
 ; COMMON-NEXT:                                        # -- End function
+
+; COMMON:     L..foov0:
+; COMMON-NEXT:  .vbyte  4, 0x00000000                   # Traceback table begin
+; COMMON-NEXT:  .byte   0x00                            # Version = 0
+; COMMON-NEXT:  .byte   0x09                            # Language = CPlusPlus
+; COMMON-NEXT:  .byte   0x20                            # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; COMMON-NEXT:                                         # +HasTraceBackTableOffset, -IsInternalProcedure
+; COMMON-NEXT:                                         # -HasControlledStorage, -IsTOCless
+; COMMON-NEXT:                                         # -IsFloatingPointPresent
+; COMMON-NEXT:                                         # -IsFloatingPointOperationLogOrAbortEnabled
+; COMMON-NEXT:  .byte   0x40                            # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
+; COMMON-NEXT:                                         # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
+; COMMON-NEXT:  .byte   0x80                            # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
+; COMMON-NEXT:  .byte   0x80                            # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
+; COMMON-NEXT:  .byte   0x00                            # NumberOfFixedParms = 0
+; COMMON-NEXT:  .byte   0x01                            # NumberOfFPParms = 0, +HasParmsOnStack
+; CHECK-ASM-NEXT:   .vbyte  4, L..foov0-.foov               # Function size
+; CHECK-FUNC-NEXT:  .vbyte  4, L..foov0-.foov[PR]           # Function size
+; COMMON-NEXT:  .vbyte  2, 0x0004                       # Function name len = 4
+; COMMON-NEXT:  .byte   "foov"                          # Function Name 
+; COMMON-NEXT:  .byte   0x12                            # NumOfVRsSaved = 4, +IsVRSavedOnStack, -HasVarArgs
+; COMMON-NEXT:  .byte   0x01                            # NumOfVectorParams = 0, +HasVMXInstruction
+; COMMON-NEXT:  .vbyte  4, 0x00000000                   # Vector Parameter type =
+; COMMON-NEXT:  .vbyte  2, 0x0000                       # Padding 
+; COMMON-NEXT:                                         # -- End function

diff  --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll
new file mode 100644
index 0000000000000..ab1dd8e3b9ade
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll
@@ -0,0 +1,129 @@
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr7 \
+; RUN:     -mattr=+altivec  -vec-extabi -xcoff-traceback-table=true < %s | \
+; RUN:   FileCheck --check-prefixes=CHECK-ASM,COMMON %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -function-sections \
+; RUN:     -mcpu=pwr7 -mattr=+altivec -vec-extabi < %s | \
+; RUN:   FileCheck --check-prefixes=CHECK-FUNC,COMMON %s
+
+;; #include <altivec.h>
+;; vector float f(vector int vi1, int i1, int i2, float f1, vector float vf,double d1, vector char vc1) {
+;;   return vec_abs(vf);
+;; }
+;; vector float fin(int x) {
+;;  vector float vf ={1.0,1.0,1.0,1.0};
+;;  if (x) return vf;
+;;  return vec_abs(vf);
+;; }
+
+define dso_local <4 x float> @f(<4 x i32> %vi1, i32 signext %i1, i32 signext %i2, float %f1, <4 x float> %vf, double %d1, <16 x i8> %vc1) #0 {
+entry:
+  %__a.addr.i = alloca <4 x float>, align 16
+  %vi1.addr = alloca <4 x i32>, align 16
+  %i1.addr = alloca i32, align 4
+  %i2.addr = alloca i32, align 4
+  %f1.addr = alloca float, align 4
+  %vf.addr = alloca <4 x float>, align 16
+  %d1.addr = alloca double, align 8
+  %vc1.addr = alloca <16 x i8>, align 16
+  store <4 x i32> %vi1, <4 x i32>* %vi1.addr, align 16
+  store i32 %i1, i32* %i1.addr, align 4
+  store i32 %i2, i32* %i2.addr, align 4
+  store float %f1, float* %f1.addr, align 4
+  store <4 x float> %vf, <4 x float>* %vf.addr, align 16
+  store double %d1, double* %d1.addr, align 8
+  store <16 x i8> %vc1, <16 x i8>* %vc1.addr, align 16
+  %0 = load <4 x float>, <4 x float>* %vf.addr, align 16
+  store <4 x float> %0, <4 x float>* %__a.addr.i, align 16
+  %1 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
+  %2 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
+  %3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %2) #2
+  ret <4 x float> %3
+}
+
+define <4 x float> @fin(i32 %x) #0 {
+entry:
+  %__a.addr.i = alloca <4 x float>, align 16
+  %__res.i = alloca <4 x i32>, align 16
+  %retval = alloca <4 x float>, align 16
+  %x.addr = alloca i32, align 4
+  %vf = alloca <4 x float>, align 16
+  store i32 %x, i32* %x.addr, align 4
+  store <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, <4 x float>* %vf, align 16
+  %0 = load i32, i32* %x.addr, align 4
+  %tobool = icmp ne i32 %0, 0
+  br i1 %tobool, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  %1 = load <4 x float>, <4 x float>* %vf, align 16
+  store <4 x float> %1, <4 x float>* %retval, align 16
+  br label %return
+
+if.end:                                           ; preds = %entry
+  %2 = load <4 x float>, <4 x float>* %vf, align 16
+  store <4 x float> %2, <4 x float>* %__a.addr.i, align 16
+  %3 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
+  %4 = bitcast <4 x float> %3 to <4 x i32>
+  %and.i = and <4 x i32> %4, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
+  store <4 x i32> %and.i, <4 x i32>* %__res.i, align 16
+  %5 = load <4 x i32>, <4 x i32>* %__res.i, align 16
+  %6 = bitcast <4 x i32> %5 to <4 x float>
+  store <4 x float> %6, <4 x float>* %retval, align 16
+  br label %return
+
+return:                                           ; preds = %if.end, %if.then
+  %7 = load <4 x float>, <4 x float>* %retval, align 16
+  ret <4 x float> %7
+}
+
+declare <4 x float> @llvm.fabs.v4f32(<4 x float>) #1
+
+; COMMON:      L..f0:
+; COMMON-NEXT:  .vbyte  4, 0x00000000                   # Traceback table begin
+; COMMON-NEXT:  .byte   0x00                            # Version = 0
+; COMMON-NEXT:  .byte   0x09                            # Language = CPlusPlus
+; COMMON-NEXT:  .byte   0x22                            # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; COMMON-NEXT:                                         # +HasTraceBackTableOffset, -IsInternalProcedure
+; COMMON-NEXT:                                         # -HasControlledStorage, -IsTOCless
+; COMMON-NEXT:                                         # +IsFloatingPointPresent
+; COMMON-NEXT:                                         # -IsFloatingPointOperationLogOrAbortEnabled
+; COMMON-NEXT:  .byte   0x40                            # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
+; COMMON-NEXT:                                         # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
+; COMMON-NEXT:  .byte   0x80                            # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
+; COMMON-NEXT:  .byte   0x80                            # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
+; COMMON-NEXT:  .byte   0x02                            # NumberOfFixedParms = 2
+; COMMON-NEXT:  .byte   0x05                            # NumberOfFPParms = 2, +HasParmsOnStack
+; COMMON-NEXT:  .vbyte  4, 0x42740000                   # Parameter type = v, i, i, f, v, d, v
+; CHECK-ASM-NEXT:  .vbyte  4, L..f0-.f                     # Function size
+; CHECK-FUNC-NEXT: .vbyte  4, L..f0-.f[PR]                 # Function size
+; COMMON-NEXT:  .vbyte  2, 0x0001                       # Function name len = 1
+; COMMON-NEXT:  .byte   102                             # Function Name
+; COMMON-NEXT:  .byte   0x00                            # NumOfVRsSaved = 0, -IsVRSavedOnStack, -HasVarArgs
+; COMMON-NEXT:  .byte   0x07                            # NumOfVectorParams = 3, +HasVMXInstruction
+; COMMON-NEXT:  .vbyte  4, 0xb0000000                   # Vector Parameter type = vi, vf, vc
+; COMMON-NEXT:  .vbyte  2, 0x0000                       # Padding 
+
+; COMMON:     L..fin0:
+; COMMON-NEXT:  .vbyte  4, 0x00000000                   # Traceback table begin
+; COMMON-NEXT:  .byte   0x00                            # Version = 0
+; COMMON-NEXT:  .byte   0x09                            # Language = CPlusPlus
+; COMMON-NEXT:  .byte   0x22                            # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; COMMON-NEXT:                                         # +HasTraceBackTableOffset, -IsInternalProcedure
+; COMMON-NEXT:                                         # -HasControlledStorage, -IsTOCless
+; COMMON-NEXT:                                         # +IsFloatingPointPresent
+; COMMON-NEXT:                                         # -IsFloatingPointOperationLogOrAbortEnabled
+; COMMON-NEXT:  .byte   0x40                            # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
+; COMMON-NEXT:                                         # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
+; COMMON-NEXT:  .byte   0x80                            # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
+; COMMON-NEXT:  .byte   0x80                            # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
+; COMMON-NEXT:  .byte   0x01                            # NumberOfFixedParms = 1
+; COMMON-NEXT:  .byte   0x01                            # NumberOfFPParms = 0, +HasParmsOnStack
+; COMMON-NEXT:  .vbyte  4, 0x00000000                   # Parameter type = i
+; CHECK-ASM-NEXT:       .vbyte  4, L..fin0-.fin                 # Function size
+; CHECK-FUNC-NEXT:      .vbyte  4, L..fin0-.fin[PR]             # Function size
+; COMMON-NEXT:  .vbyte  2, 0x0003                       # Function name len = 3
+; COMMON-NEXT:  .byte   "fin"                           # Function Name 
+; COMMON-NEXT:  .byte   0x00                            # NumOfVRsSaved = 0, -IsVRSavedOnStack, -HasVarArgs
+; COMMON-NEXT:  .byte   0x01                            # NumOfVectorParams = 0, +HasVMXInstruction
+; COMMON-NEXT:  .vbyte  4, 0x00000000                   # Vector Parameter type =
+; COMMON-NEXT:  .vbyte  2, 0x0000                       # Padding

diff  --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo_hasvarg.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo_hasvarg.ll
new file mode 100644
index 0000000000000..9a8a4f5f80d2e
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo_hasvarg.ll
@@ -0,0 +1,36 @@
+; RUN:  llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr7 \
+; RUN:     -mattr=+altivec  -vec-extabi -xcoff-traceback-table=true 2>&1 < %s | \
+; RUN:   FileCheck --check-prefixes=CHECK-ASM %s 
+
+;; void f(vector float vf, ...) {
+;;}
+
+define void @f(<4 x float> %vf, ...) #0 {
+entry:
+  %vf.addr = alloca <4 x float>, align 16
+  store <4 x float> %vf, <4 x float>* %vf.addr, align 16
+  ret void
+}
+
+;CHECK-ASM:             .vbyte  4, 0x00000000                   # Traceback table begin
+;CHECK-ASM-NEXT:        .byte   0x00                            # Version = 0
+;CHECK-ASM-NEXT:        .byte   0x09                            # Language = CPlusPlus
+;CHECK-ASM-NEXT:        .byte   0x20                            # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+;CHECK-ASM-NEXT:                                         # +HasTraceBackTableOffset, -IsInternalProcedure
+;CHECK-ASM-NEXT:                                         # -HasControlledStorage, -IsTOCless
+;CHECK-ASM-NEXT:                                         # -IsFloatingPointPresent
+;CHECK-ASM-NEXT:                                         # -IsFloatingPointOperationLogOrAbortEnabled
+;CHECK-ASM-NEXT:        .byte   0x40                            # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
+;CHECK-ASM-NEXT:                                         # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
+;CHECK-ASM-NEXT:        .byte   0x80                            # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
+;CHECK-ASM-NEXT:        .byte   0x80                            # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
+;CHECK-ASM-NEXT:        .byte   0x00                            # NumberOfFixedParms = 0
+;CHECK-ASM-NEXT:        .byte   0x01                            # NumberOfFPParms = 0, +HasParmsOnStack
+;CHECK-ASM-NEXT:        .vbyte  4, L..f0-.f                     # Function size
+;CHECK-ASM-NEXT:        .vbyte  2, 0x0001                       # Function name len = 1
+;CHECK-ASM-NEXT:        .byte   102                             # Function Name
+;CHECK-ASM-NEXT:        .byte   0x01                            # NumOfVRsSaved = 0, -IsVRSavedOnStack, +HasVarArgs
+;CHECK-ASM-NEXT:        .byte   0x03                            # NumOfVectorParams = 1, +HasVMXInstruction
+;CHECK-ASM-NEXT:        .vbyte  4, 0xc0000000                   # Vector Parameter type = vf
+;CHECK-ASM-NEXT:        .vbyte  2, 0x0000                       # Padding 
+;CHECK-ASM-NEXT:                                         # -- End function

diff  --git a/llvm/test/CodeGen/PowerPC/aix-exception.ll b/llvm/test/CodeGen/PowerPC/aix-exception.ll
index f36c40fcad69e..9a6b5e711f682 100644
--- a/llvm/test/CodeGen/PowerPC/aix-exception.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-exception.ll
@@ -103,10 +103,10 @@ eh.resume:                                        ; preds = %catch.dispatch
 ; ASM:    .vbyte  4, 0x00000000                   # Traceback table begin
 ; ASM:    .byte   0x00                            # Version = 0
 ; ASM:    .byte   0x09                            # Language = CPlusPlus
-; ASM:    .byte   0x22                            # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; ASM:    .byte   0x20                            # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
 ; ASM:                                    # +HasTraceBackTableOffset, -IsInternalProcedure
 ; ASM:                                    # -HasControlledStorage, -IsTOCless
-; ASM:                                    # +IsFloatingPointPresent
+; ASM:                                    # -IsFloatingPointPresent
 ; ASM:                                    # -IsFloatingPointOperationLogOrAbortEnabled
 ; ASM:    .byte   0x41                            # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
 ; ASM:                                    # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved

diff  --git a/llvm/test/DebugInfo/XCOFF/explicit-section.ll b/llvm/test/DebugInfo/XCOFF/explicit-section.ll
index 321861cee1ff6..86dbb56d53a71 100644
--- a/llvm/test/DebugInfo/XCOFF/explicit-section.ll
+++ b/llvm/test/DebugInfo/XCOFF/explicit-section.ll
@@ -112,10 +112,10 @@ entry:
 ; CHECK-NEXT:          .vbyte  4, 0x00000000                   # Traceback table begin
 ; CHECK-NEXT:          .byte   0x00                            # Version = 0
 ; CHECK-NEXT:          .byte   0x09                            # Language = CPlusPlus
-; CHECK-NEXT:          .byte   0x22                            # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; CHECK-NEXT:          .byte   0x20                            # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
 ; CHECK-NEXT:                                          # +HasTraceBackTableOffset, -IsInternalProcedure
 ; CHECK-NEXT:                                          # -HasControlledStorage, -IsTOCless
-; CHECK-NEXT:                                          # +IsFloatingPointPresent
+; CHECK-NEXT:                                          # -IsFloatingPointPresent
 ; CHECK-NEXT:                                          # -IsFloatingPointOperationLogOrAbortEnabled
 ; CHECK-NEXT:          .byte   0x41                            # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
 ; CHECK-NEXT:                                          # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved

diff  --git a/llvm/unittests/Object/XCOFFObjectFileTest.cpp b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
index 71b902c93e3dd..fc7e48100aa68 100644
--- a/llvm/unittests/Object/XCOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
@@ -141,6 +141,20 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIParmsType) {
   XCOFFTracebackTable TT3 = *TTOrErr3;
   ASSERT_TRUE(TT3.getParmsType());
   EXPECT_EQ(TT3.getParmsType().getValue(), "d, i, f, f");
+
+  V[6] = 0x04;
+  V[7] = 0x1E;
+  V[8] = 0xAC;
+  V[9] = 0xAA;
+  V[10] = 0xAA;
+  V[11] = 0xAA;
+  Size = sizeof(V);
+  Expected<XCOFFTracebackTable> TTOrErr4 = XCOFFTracebackTable::create(V, Size);
+  ASSERT_THAT_EXPECTED(TTOrErr4, Succeeded());
+  XCOFFTracebackTable TT4 = *TTOrErr4;
+  ASSERT_TRUE(TT4.getParmsType());
+  EXPECT_EQ(TT4.getParmsType().getValue(),
+            "f, f, d, i, i, f, f, f, f, f, f, f, f, f, f, f, f, ...");
 }
 
 const uint8_t TBTableData[] = {
@@ -205,7 +219,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
   EXPECT_EQ(VecExt.getNumberOfVectorParms(), 2u);
   EXPECT_TRUE(VecExt.hasVMXInstruction());
 
-  EXPECT_EQ(VecExt.getVectorParmsInfoString(), "vf, vf");
+  EXPECT_EQ(VecExt.getVectorParmsInfo(), "vf, vf");
 
   ASSERT_TRUE(TT.getExtensionTable());
   EXPECT_EQ(TT.getExtensionTable().getValue(),
@@ -216,7 +230,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
 
 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
   const uint8_t TBTableData[] = {
-      0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00,
+      0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc5, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
       0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
       0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
@@ -227,7 +241,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
   XCOFFTracebackTable TT = *TTOrErr;
 
   ASSERT_TRUE(TT.getParmsType());
-  EXPECT_EQ(TT.getParmsType().getValue(), "v, i, f, i, d, i");
+  EXPECT_EQ(TT.getParmsType().getValue(), "v, i, f, i, d, i, v, v");
 
   ASSERT_TRUE(TT.getVectorExt());
   TBVectorExt VecExt = TT.getVectorExt().getValue();
@@ -239,7 +253,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
   EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u);
   EXPECT_TRUE(VecExt.hasVMXInstruction());
 
-  EXPECT_EQ(VecExt.getVectorParmsInfoString(), "vi, vs, vc");
+  EXPECT_EQ(VecExt.getVectorParmsInfo(), "vi, vs, vc");
 
   ASSERT_TRUE(TT.getExtensionTable());
   EXPECT_EQ(TT.getExtensionTable().getValue(),
@@ -496,3 +510,49 @@ TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
       ExpectErr.takeError(),
       FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
 }
+
+TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterType) {
+  const uint8_t TBTableData[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01,
+                                 0x05, 0x58, 0x00, 0x10, 0x00, 0x00, 0x00,
+                                 0x00, 0x40, 0x00, 0x07, 0x61, 0x64, 0x64,
+                                 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
+  uint64_t Size = 28;
+  Expected<XCOFFTracebackTable> TTOrErr =
+      XCOFFTracebackTable::create(TBTableData, Size);
+
+  EXPECT_THAT_ERROR(
+      TTOrErr.takeError(),
+      FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
+                        "in parseParmsType."));
+}
+
+TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterTypeWithVecInfo) {
+  const uint8_t TBTableData[] = {
+      0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x10,
+      0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
+      0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
+      0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
+  uint64_t Size = 44;
+  Expected<XCOFFTracebackTable> TTOrErr =
+      XCOFFTracebackTable::create(TBTableData, Size);
+
+  EXPECT_THAT_ERROR(
+      TTOrErr.takeError(),
+      FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
+                        "in parseParmsTypeWithVecInfo."));
+}
+
+TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtVecParameterType) {
+  const uint8_t TBTableData[] = {
+      0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
+      0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
+      0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00};
+  uint64_t Size = 44;
+  Expected<XCOFFTracebackTable> TTOrErr =
+      XCOFFTracebackTable::create(TBTableData, Size);
+
+  EXPECT_THAT_ERROR(TTOrErr.takeError(),
+                    FailedWithMessage("ParmsType encodes more than ParmsNum "
+                                      "parameters in parseVectorParmsType."));
+}


        


More information about the llvm-commits mailing list