[clang] 8a1c999 - Implement _ExtInt ABI for all ABIs in Clang, enable type for ABIs

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Wed May 6 06:52:36 PDT 2020


Author: Erich Keane
Date: 2020-05-06T06:52:18-07:00
New Revision: 8a1c999c9b0817d4de778a62965b4af86416e4b7

URL: https://github.com/llvm/llvm-project/commit/8a1c999c9b0817d4de778a62965b4af86416e4b7
DIFF: https://github.com/llvm/llvm-project/commit/8a1c999c9b0817d4de778a62965b4af86416e4b7.diff

LOG: Implement _ExtInt ABI for all ABIs in Clang, enable type for ABIs

This is the result of an audit of all of the ABIs in clang to implement
and enable the type for those targets.

Additionally, this finds an issue with integer-promotion passing for a
few platforms when using _ExtInt of < int, so this also corrects that
resulting in signext/zeroext being on a params of those types in some
platforms.

Differential Revisions: https://reviews.llvm.org/D79118

Added: 
    

Modified: 
    clang/lib/Basic/Targets/AArch64.h
    clang/lib/Basic/Targets/AMDGPU.h
    clang/lib/Basic/Targets/ARC.h
    clang/lib/Basic/Targets/ARM.h
    clang/lib/Basic/Targets/Hexagon.h
    clang/lib/Basic/Targets/Lanai.h
    clang/lib/Basic/Targets/Mips.h
    clang/lib/Basic/Targets/NVPTX.h
    clang/lib/Basic/Targets/PNaCl.h
    clang/lib/Basic/Targets/PPC.h
    clang/lib/Basic/Targets/RISCV.h
    clang/lib/Basic/Targets/SPIR.h
    clang/lib/Basic/Targets/Sparc.h
    clang/lib/Basic/Targets/SystemZ.h
    clang/lib/Basic/Targets/WebAssembly.h
    clang/lib/Basic/Targets/XCore.h
    clang/lib/CodeGen/ABIInfo.h
    clang/lib/CodeGen/TargetInfo.cpp
    clang/test/CodeGen/ext-int-cc.c
    clang/test/CodeGen/ext-int-sanitizer.cpp
    clang/test/CodeGenCXX/ext-int.cpp

Removed: 
    clang/test/Sema/ext-int-not-supported.c


################################################################################
diff  --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index 39763b5b5609..6af44d1c19be 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -120,6 +120,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
   int getEHDataRegisterNumber(unsigned RegNo) const override;
 
   bool hasInt128Type() const override;
+
+  bool hasExtIntType() const override { return true; }
 };
 
 class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo {

diff  --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index 548cadcab9ab..d0e88e223e95 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -354,6 +354,8 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
   }
 
   void setAuxTarget(const TargetInfo *Aux) override;
+
+  bool hasExtIntType() const override { return true; }
 };
 
 } // namespace targets

diff  --git a/clang/lib/Basic/Targets/ARC.h b/clang/lib/Basic/Targets/ARC.h
index c43a39984edb..b314c42be1e9 100644
--- a/clang/lib/Basic/Targets/ARC.h
+++ b/clang/lib/Basic/Targets/ARC.h
@@ -65,6 +65,8 @@ class LLVM_LIBRARY_VISIBILITY ARCTargetInfo : public TargetInfo {
                              TargetInfo::ConstraintInfo &Info) const override {
     return false;
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 
 } // namespace targets

diff  --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h
index 48d9db2ba166..d2f4e6901f63 100644
--- a/clang/lib/Basic/Targets/ARM.h
+++ b/clang/lib/Basic/Targets/ARM.h
@@ -182,6 +182,8 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
   int getEHDataRegisterNumber(unsigned RegNo) const override;
 
   bool hasSjLjLowering() const override;
+
+  bool hasExtIntType() const override { return true; }
 };
 
 class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {

diff  --git a/clang/lib/Basic/Targets/Hexagon.h b/clang/lib/Basic/Targets/Hexagon.h
index 7e173df81683..d6c7da5f1e40 100644
--- a/clang/lib/Basic/Targets/Hexagon.h
+++ b/clang/lib/Basic/Targets/Hexagon.h
@@ -138,6 +138,8 @@ class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo {
     // We can write more stricter checks later.
     return CPU.find('t') != std::string::npos;
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang

diff  --git a/clang/lib/Basic/Targets/Lanai.h b/clang/lib/Basic/Targets/Lanai.h
index e119606384c7..9af5427b81c4 100644
--- a/clang/lib/Basic/Targets/Lanai.h
+++ b/clang/lib/Basic/Targets/Lanai.h
@@ -86,6 +86,8 @@ class LLVM_LIBRARY_VISIBILITY LanaiTargetInfo : public TargetInfo {
   }
 
   const char *getClobbers() const override { return ""; }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang

diff  --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h
index 224ec0783edf..b475c03889a1 100644
--- a/clang/lib/Basic/Targets/Mips.h
+++ b/clang/lib/Basic/Targets/Mips.h
@@ -406,6 +406,7 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
   unsigned getUnwindWordWidth() const override;
 
   bool validateTarget(DiagnosticsEngine &Diags) const override;
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang

diff  --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index 63780789c474..f57a0f18efa3 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -160,6 +160,8 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
       return HostTarget->checkCallingConvention(CC);
     return CCCR_Warning;
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang

diff  --git a/clang/lib/Basic/Targets/PNaCl.h b/clang/lib/Basic/Targets/PNaCl.h
index ab4abf9fc567..d5bfc369583f 100644
--- a/clang/lib/Basic/Targets/PNaCl.h
+++ b/clang/lib/Basic/Targets/PNaCl.h
@@ -68,6 +68,8 @@ class LLVM_LIBRARY_VISIBILITY PNaClTargetInfo : public TargetInfo {
   }
 
   const char *getClobbers() const override { return ""; }
+
+  bool hasExtIntType() const override { return true; }
 };
 
 // We attempt to use PNaCl (le32) frontend and Mips32EL backend.

diff  --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index 270aa7ff9181..6261a49c4fde 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -332,6 +332,8 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
                : "u9__ieee128";
   }
   const char *getFloat128Mangling() const override { return "u9__ieee128"; }
+
+  bool hasExtIntType() const override { return true; }
 };
 
 class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {

diff  --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 05da13230bf8..73652b409e9c 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -76,6 +76,8 @@ class RISCVTargetInfo : public TargetInfo {
 
   bool handleTargetFeatures(std::vector<std::string> &Features,
                             DiagnosticsEngine &Diags) override;
+
+  bool hasExtIntType() const override { return true; }
 };
 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
 public:

diff  --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 279d1866a428..f625d4980e29 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -100,6 +100,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
     // for SPIR since it is a generic target.
     getSupportedOpenCLOpts().supportAll();
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
 public:

diff  --git a/clang/lib/Basic/Targets/Sparc.h b/clang/lib/Basic/Targets/Sparc.h
index 1f799565e99b..d24cf15d7cd6 100644
--- a/clang/lib/Basic/Targets/Sparc.h
+++ b/clang/lib/Basic/Targets/Sparc.h
@@ -176,6 +176,7 @@ class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
                         MacroBuilder &Builder) const override;
 
   bool hasSjLjLowering() const override { return true; }
+  bool hasExtIntType() const override { return true; }
 };
 
 // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
@@ -227,6 +228,8 @@ class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {
       return false;
     return getCPUGeneration(CPU) == CG_V9;
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang

diff  --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index 9f7ce62d2ce6..1c8822e2bc2d 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -150,6 +150,8 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
   }
 
   const char *getLongDoubleMangling() const override { return "g"; }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang

diff  --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h
index dd5584960304..030d79ea2ecc 100644
--- a/clang/lib/Basic/Targets/WebAssembly.h
+++ b/clang/lib/Basic/Targets/WebAssembly.h
@@ -130,6 +130,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
       return CCCR_Warning;
     }
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
     : public WebAssemblyTargetInfo {

diff  --git a/clang/lib/Basic/Targets/XCore.h b/clang/lib/Basic/Targets/XCore.h
index c94f93a99bca..c33766751aa1 100644
--- a/clang/lib/Basic/Targets/XCore.h
+++ b/clang/lib/Basic/Targets/XCore.h
@@ -75,6 +75,8 @@ class LLVM_LIBRARY_VISIBILITY XCoreTargetInfo : public TargetInfo {
   }
 
   bool allowsLargerPreferedTypeAlignment() const override { return false; }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang

diff  --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h
index 0c3a076da0b5..4e9d44421875 100644
--- a/clang/lib/CodeGen/ABIInfo.h
+++ b/clang/lib/CodeGen/ABIInfo.h
@@ -102,6 +102,10 @@ namespace swiftcall {
     bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
                                 uint64_t &Members) const;
 
+    // Implement the Type::IsPromotableIntegerType for ABI specific needs. The
+    // only 
diff erence is that this considers _ExtInt as well.
+    bool isPromotableIntegerTypeForABI(QualType Ty) const;
+
     /// A convenience method to return an indirect ABIArgInfo with an
     /// expected alignment equal to the ABI alignment of the given type.
     CodeGen::ABIArgInfo

diff  --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 237ef7c9ff95..1e164d3fe2b0 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -97,6 +97,17 @@ Address ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
   return Address::invalid();
 }
 
+bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
+  if (Ty->isPromotableIntegerType())
+    return true;
+
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy))
+      return true;
+
+  return false;
+}
+
 ABIInfo::~ABIInfo() {}
 
 /// Does the given lowering require more than the given number of
@@ -701,8 +712,16 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
     Ty = EnumTy->getDecl()->getIntegerType();
 
-  return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                        : ABIArgInfo::getDirect());
+  ASTContext &Context = getContext();
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() >
+        Context.getTypeSize(Context.getTargetInfo().hasInt128Type()
+                                ? Context.Int128Ty
+                                : Context.LongLongTy))
+      return getNaturalAlignIndirect(Ty);
+
+  return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+                                            : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
@@ -716,8 +735,15 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
     RetTy = EnumTy->getDecl()->getIntegerType();
 
-  return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
-                                           : ABIArgInfo::getDirect());
+  if (const auto *EIT = RetTy->getAs<ExtIntType>())
+    if (EIT->getNumBits() >
+        getContext().getTypeSize(getContext().getTargetInfo().hasInt128Type()
+                                     ? getContext().Int128Ty
+                                     : getContext().LongLongTy))
+      return getNaturalAlignIndirect(RetTy);
+
+  return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                               : ABIArgInfo::getDirect());
 }
 
 //===----------------------------------------------------------------------===//
@@ -933,10 +959,15 @@ ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const {
   } else if (Ty->isFloatingType()) {
     // Floating-point types don't go inreg.
     return ABIArgInfo::getDirect();
+  } else if (const auto *EIT = Ty->getAs<ExtIntType>()) {
+    // Treat extended integers as integers if <=64, otherwise pass indirectly.
+    if (EIT->getNumBits() > 64)
+      return getNaturalAlignIndirect(Ty);
+    return ABIArgInfo::getDirect();
   }
 
-  return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                        : ABIArgInfo::getDirect());
+  return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+                                            : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
@@ -947,12 +978,19 @@ ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
   if (isAggregateTypeForABI(RetTy))
     return getNaturalAlignIndirect(RetTy);
 
+  // Treat extended integers as integers if <=64, otherwise pass indirectly.
+  if (const auto *EIT = RetTy->getAs<ExtIntType>()) {
+    if (EIT->getNumBits() > 64)
+      return getNaturalAlignIndirect(RetTy);
+    return ABIArgInfo::getDirect();
+  }
+
   // 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 (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                               : ABIArgInfo::getDirect());
 }
 
 /// IsX86_MMXType - Return true if this is an MMX type.
@@ -1498,8 +1536,12 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
     RetTy = EnumTy->getDecl()->getIntegerType();
 
-  return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
-                                           : ABIArgInfo::getDirect());
+  if (const auto *EIT = RetTy->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 64)
+      return getIndirectReturnResult(RetTy, State);
+
+  return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                               : ABIArgInfo::getDirect());
 }
 
 static bool isSSEVectorType(ASTContext &Context, QualType Ty) {
@@ -1816,7 +1858,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
 
   bool InReg = shouldPrimitiveUseInReg(Ty, State);
 
-  if (Ty->isPromotableIntegerType()) {
+  if (isPromotableIntegerTypeForABI(Ty)) {
     if (InReg)
       return ABIArgInfo::getExtendInReg(Ty);
     return ABIArgInfo::getExtend(Ty);
@@ -2977,9 +3019,11 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const {
     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
       Ty = EnumTy->getDecl()->getIntegerType();
 
-    if (!Ty->isExtIntType())
-      return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                            : ABIArgInfo::getDirect());
+    if (Ty->isExtIntType())
+      return getNaturalAlignIndirect(Ty);
+
+    return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+                                              : ABIArgInfo::getDirect());
   }
 
   return getNaturalAlignIndirect(Ty);
@@ -3017,8 +3061,8 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
       Ty = EnumTy->getDecl()->getIntegerType();
 
-    return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                          : ABIArgInfo::getDirect());
+    return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+                                              : ABIArgInfo::getDirect());
   }
 
   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
@@ -3400,7 +3444,7 @@ classifyReturnType(QualType RetTy) const {
         RetTy = EnumTy->getDecl()->getIntegerType();
 
       if (RetTy->isIntegralOrEnumerationType() &&
-          RetTy->isPromotableIntegerType())
+          isPromotableIntegerTypeForABI(RetTy))
         return ABIArgInfo::getExtend(RetTy);
     }
     break;
@@ -3545,7 +3589,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(
         Ty = EnumTy->getDecl()->getIntegerType();
 
       if (Ty->isIntegralOrEnumerationType() &&
-          Ty->isPromotableIntegerType())
+          isPromotableIntegerTypeForABI(Ty))
         return ABIArgInfo::getExtend(Ty);
     }
 
@@ -4662,7 +4706,7 @@ PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const {
     Ty = EnumTy->getDecl()->getIntegerType();
 
   // Promotable integer types are required to be promoted by the ABI.
-  if (Ty->isPromotableIntegerType())
+  if (isPromotableIntegerTypeForABI(Ty))
     return true;
 
   // In addition to the usual promotable integer types, we also need to
@@ -4676,6 +4720,10 @@ PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const {
       break;
     }
 
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() < 64)
+      return true;
+
   return false;
 }
 
@@ -4893,6 +4941,10 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {
     }
   }
 
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 128)
+      return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+
   if (isAggregateTypeForABI(Ty)) {
     if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
       return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
@@ -4965,6 +5017,10 @@ PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
     }
   }
 
+  if (const auto *EIT = RetTy->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 128)
+      return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
+
   if (isAggregateTypeForABI(RetTy)) {
     // ELFv2 homogeneous aggregates are returned as array types.
     const Type *Base = nullptr;
@@ -5301,7 +5357,11 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const {
     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
       Ty = EnumTy->getDecl()->getIntegerType();
 
-    return (Ty->isPromotableIntegerType() && isDarwinPCS()
+    if (const auto *EIT = Ty->getAs<ExtIntType>())
+      if (EIT->getNumBits() > 128)
+        return getNaturalAlignIndirect(Ty);
+
+    return (isPromotableIntegerTypeForABI(Ty) && isDarwinPCS()
                 ? ABIArgInfo::getExtend(Ty)
                 : ABIArgInfo::getDirect());
   }
@@ -5378,7 +5438,11 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
     if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
       RetTy = EnumTy->getDecl()->getIntegerType();
 
-    return (RetTy->isPromotableIntegerType() && isDarwinPCS()
+    if (const auto *EIT = RetTy->getAs<ExtIntType>())
+      if (EIT->getNumBits() > 128)
+        return getNaturalAlignIndirect(RetTy);
+
+    return (isPromotableIntegerTypeForABI(RetTy) && isDarwinPCS()
                 ? ABIArgInfo::getExtend(RetTy)
                 : ABIArgInfo::getDirect());
   }
@@ -6068,8 +6132,12 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,
       Ty = EnumTy->getDecl()->getIntegerType();
     }
 
-    return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                          : ABIArgInfo::getDirect());
+    if (const auto *EIT = Ty->getAs<ExtIntType>())
+      if (EIT->getNumBits() > 64)
+        return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+
+    return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+                                              : ABIArgInfo::getDirect());
   }
 
   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
@@ -6274,8 +6342,12 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic,
     if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
       RetTy = EnumTy->getDecl()->getIntegerType();
 
-    return RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
-                                            : ABIArgInfo::getDirect();
+    if (const auto *EIT = RetTy->getAs<ExtIntType>())
+      if (EIT->getNumBits() > 64)
+        return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
+
+    return isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                                : ABIArgInfo::getDirect();
   }
 
   // Are we following APCS?
@@ -6528,6 +6600,8 @@ class NVPTXABIInfo : public ABIInfo {
   void computeInfo(CGFunctionInfo &FI) const override;
   Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                     QualType Ty) const override;
+  bool isUnsupportedType(QualType T) const;
+  ABIArgInfo coerceToIntArrayWithLimit(QualType Ty, unsigned MaxSize) const;
 };
 
 class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -6591,18 +6665,22 @@ class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo {
 };
 
 /// Checks if the type is unsupported directly by the current target.
-static bool isUnsupportedType(ASTContext &Context, QualType T) {
+bool NVPTXABIInfo::isUnsupportedType(QualType T) const {
+  ASTContext &Context = getContext();
   if (!Context.getTargetInfo().hasFloat16Type() && T->isFloat16Type())
     return true;
   if (!Context.getTargetInfo().hasFloat128Type() &&
       (T->isFloat128Type() ||
        (T->isRealFloatingType() && Context.getTypeSize(T) == 128)))
     return true;
+  if (const auto *EIT = T->getAs<ExtIntType>())
+    return EIT->getNumBits() >
+           (Context.getTargetInfo().hasInt128Type() ? 128 : 64);
   if (!Context.getTargetInfo().hasInt128Type() && T->isIntegerType() &&
       Context.getTypeSize(T) > 64)
     return true;
   if (const auto *AT = T->getAsArrayTypeUnsafe())
-    return isUnsupportedType(Context, AT->getElementType());
+    return isUnsupportedType(AT->getElementType());
   const auto *RT = T->getAs<RecordType>();
   if (!RT)
     return false;
@@ -6611,24 +6689,23 @@ static bool isUnsupportedType(ASTContext &Context, QualType T) {
   // If this is a C++ record, check the bases first.
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
     for (const CXXBaseSpecifier &I : CXXRD->bases())
-      if (isUnsupportedType(Context, I.getType()))
+      if (isUnsupportedType(I.getType()))
         return true;
 
   for (const FieldDecl *I : RD->fields())
-    if (isUnsupportedType(Context, I->getType()))
+    if (isUnsupportedType(I->getType()))
       return true;
   return false;
 }
 
 /// Coerce the given type into an array with maximum allowed size of elements.
-static ABIArgInfo coerceToIntArrayWithLimit(QualType Ty, ASTContext &Context,
-                                            llvm::LLVMContext &LLVMContext,
-                                            unsigned MaxSize) {
+ABIArgInfo NVPTXABIInfo::coerceToIntArrayWithLimit(QualType Ty,
+                                                   unsigned MaxSize) const {
   // Alignment and Size are measured in bits.
-  const uint64_t Size = Context.getTypeSize(Ty);
-  const uint64_t Alignment = Context.getTypeAlign(Ty);
+  const uint64_t Size = getContext().getTypeSize(Ty);
+  const uint64_t Alignment = getContext().getTypeAlign(Ty);
   const unsigned Div = std::min<unsigned>(MaxSize, Alignment);
-  llvm::Type *IntType = llvm::Type::getIntNTy(LLVMContext, Div);
+  llvm::Type *IntType = llvm::Type::getIntNTy(getVMContext(), Div);
   const uint64_t NumElements = (Size + Div - 1) / Div;
   return ABIArgInfo::getDirect(llvm::ArrayType::get(IntType, NumElements));
 }
@@ -6638,9 +6715,8 @@ ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {
     return ABIArgInfo::getIgnore();
 
   if (getContext().getLangOpts().OpenMP &&
-      getContext().getLangOpts().OpenMPIsDevice &&
-      isUnsupportedType(getContext(), RetTy))
-    return coerceToIntArrayWithLimit(RetTy, getContext(), getVMContext(), 64);
+      getContext().getLangOpts().OpenMPIsDevice && isUnsupportedType(RetTy))
+    return coerceToIntArrayWithLimit(RetTy, 64);
 
   // note: this is 
diff erent from default ABI
   if (!RetTy->isScalarType())
@@ -6650,8 +6726,8 @@ ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {
   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
     RetTy = EnumTy->getDecl()->getIntegerType();
 
-  return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
-                                           : ABIArgInfo::getDirect());
+  return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                               : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const {
@@ -6674,8 +6750,15 @@ ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const {
     return getNaturalAlignIndirect(Ty, /* byval */ true);
   }
 
-  return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                        : ABIArgInfo::getDirect());
+  if (const auto *EIT = Ty->getAs<ExtIntType>()) {
+    if ((EIT->getNumBits() > 128) ||
+        (!getContext().getTargetInfo().hasInt128Type() &&
+         EIT->getNumBits() > 64))
+      return getNaturalAlignIndirect(Ty, /* byval */ true);
+  }
+
+  return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+                                            : ABIArgInfo::getDirect());
 }
 
 void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
@@ -6794,7 +6877,7 @@ class SystemZABIInfo : public SwiftABIInfo {
   SystemZABIInfo(CodeGenTypes &CGT, bool HV, bool SF)
     : SwiftABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
 
-  bool isPromotableIntegerType(QualType Ty) const;
+  bool isPromotableIntegerTypeForABI(QualType Ty) const;
   bool isCompoundType(QualType Ty) const;
   bool isVectorArgumentType(QualType Ty) const;
   bool isFPArgumentType(QualType Ty) const;
@@ -6831,15 +6914,19 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
 
 }
 
-bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const {
+bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
   // Treat an enum type as its underlying type.
   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
     Ty = EnumTy->getDecl()->getIntegerType();
 
   // Promotable integer types are required to be promoted by the ABI.
-  if (Ty->isPromotableIntegerType())
+  if (ABIInfo::isPromotableIntegerTypeForABI(Ty))
     return true;
 
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() < 64)
+      return true;
+
   // 32-bit values must also be promoted.
   if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
     switch (BT->getKind()) {
@@ -7086,8 +7173,8 @@ ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
     return ABIArgInfo::getDirect();
   if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
     return getNaturalAlignIndirect(RetTy);
-  return (isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy)
-                                         : ABIArgInfo::getDirect());
+  return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                               : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
@@ -7096,7 +7183,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
     return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
 
   // Integers and enums are extended to full register width.
-  if (isPromotableIntegerType(Ty))
+  if (isPromotableIntegerTypeForABI(Ty))
     return ABIArgInfo::getExtend(Ty);
 
   // Handle vector types and vector-like structure types.  Note that
@@ -7391,6 +7478,13 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
     Ty = EnumTy->getDecl()->getIntegerType();
 
+  // Make sure we pass indirectly things that are too large.
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 128 ||
+        (EIT->getNumBits() > 64 &&
+         !getContext().getTargetInfo().hasInt128Type()))
+      return getNaturalAlignIndirect(Ty);
+
   // All integral types are promoted to the GPR width.
   if (Ty->isIntegralOrEnumerationType())
     return extendType(Ty);
@@ -7475,7 +7569,14 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {
   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
     RetTy = EnumTy->getDecl()->getIntegerType();
 
-  if (RetTy->isPromotableIntegerType())
+  // Make sure we pass indirectly things that are too large.
+  if (const auto *EIT = RetTy->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 128 ||
+        (EIT->getNumBits() > 64 &&
+         !getContext().getTargetInfo().hasInt128Type()))
+      return getNaturalAlignIndirect(RetTy);
+
+  if (isPromotableIntegerTypeForABI(RetTy))
     return ABIArgInfo::getExtend(RetTy);
 
   if ((RetTy->isUnsignedIntegerOrEnumerationType() ||
@@ -7769,8 +7870,11 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty,
     if (Size <= 64)
       HexagonAdjustRegsLeft(Size, RegsLeft);
 
-    return Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                         : ABIArgInfo::getDirect();
+    if (Size > 64 && Ty->isExtIntType())
+      return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+
+    return isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+                                             : ABIArgInfo::getDirect();
   }
 
   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
@@ -7822,8 +7926,11 @@ ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const {
     if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
       RetTy = EnumTy->getDecl()->getIntegerType();
 
-    return RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
-                                            : ABIArgInfo::getDirect();
+    if (Size > 64 && RetTy->isExtIntType())
+      return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
+
+    return isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                                : ABIArgInfo::getDirect();
   }
 
   if (isEmptyRecord(getContext(), RetTy, true))
@@ -8186,7 +8293,13 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty,
     Ty = EnumTy->getDecl()->getIntegerType();
 
   bool InReg = shouldUseInReg(Ty, State);
-  if (Ty->isPromotableIntegerType()) {
+
+  // Don't pass >64 bit integers in registers.
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 64)
+      return getIndirectResult(Ty, /*ByVal=*/true, State);
+
+  if (isPromotableIntegerTypeForABI(Ty)) {
     if (InReg)
       return ABIArgInfo::getDirectInReg();
     return ABIArgInfo::getExtend(Ty);
@@ -8896,6 +9009,10 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const {
   if (Size < 64 && Ty->isIntegerType())
     return ABIArgInfo::getExtend(Ty);
 
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() < 64)
+      return ABIArgInfo::getExtend(Ty);
+
   // Other non-aggregates go in registers.
   if (!isAggregateTypeForABI(Ty))
     return ABIArgInfo::getDirect();
@@ -9145,11 +9262,15 @@ ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty,
         ABIArgInfo::getDirect(Result, 0, nullptr, false);
   }
 
-  return Ty->isPromotableIntegerType() ?
-      (FreeRegs >= SizeInRegs ? ABIArgInfo::getExtendInReg(Ty) :
-                                ABIArgInfo::getExtend(Ty)) :
-      (FreeRegs >= SizeInRegs ? ABIArgInfo::getDirectInReg() :
-                                ABIArgInfo::getDirect());
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 64)
+      return getIndirectByValue(Ty);
+
+  return isPromotableIntegerTypeForABI(Ty)
+             ? (FreeRegs >= SizeInRegs ? ABIArgInfo::getExtendInReg(Ty)
+                                       : ABIArgInfo::getExtend(Ty))
+             : (FreeRegs >= SizeInRegs ? ABIArgInfo::getDirectInReg()
+                                       : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo ARCABIInfo::classifyReturnType(QualType RetTy) const {
@@ -10180,6 +10301,15 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
       return extendType(Ty);
     }
 
+    if (const auto *EIT = Ty->getAs<ExtIntType>()) {
+      if (EIT->getNumBits() < XLen && !MustUseStack)
+        return extendType(Ty);
+      if (EIT->getNumBits() > 128 ||
+          (!getContext().getTargetInfo().hasInt128Type() &&
+           EIT->getNumBits() > 64))
+        return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
+    }
+
     return ABIArgInfo::getDirect();
   }
 

diff  --git a/clang/test/CodeGen/ext-int-cc.c b/clang/test/CodeGen/ext-int-cc.c
index 41410be65497..02e2f3aef274 100644
--- a/clang/test/CodeGen/ext-int-cc.c
+++ b/clang/test/CodeGen/ext-int-cc.c
@@ -2,6 +2,32 @@
 // RUN: %clang_cc1 -triple x86_64-windows-pc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=WIN64
 // RUN: %clang_cc1 -triple i386-gnu-linux -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=LIN32
 // RUN: %clang_cc1 -triple i386-windows-pc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=WIN32
+// RUN: %clang_cc1 -triple le32-nacl -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=NACL
+// RUN: %clang_cc1 -triple nvptx64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=NVPTX64
+// RUN: %clang_cc1 -triple nvptx -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=NVPTX
+// RUN: %clang_cc1 -triple sparcv9 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SPARCV9
+// RUN: %clang_cc1 -triple sparc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SPARC
+// RUN: %clang_cc1 -triple mips64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=MIPS64
+// RUN: %clang_cc1 -triple mips -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=MIPS
+// RUN: %clang_cc1 -triple spir64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SPIR64
+// RUN: %clang_cc1 -triple spir -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SPIR
+// RUN: %clang_cc1 -triple hexagon -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=HEX
+// RUN: %clang_cc1 -triple lanai -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=LANAI
+// RUN: %clang_cc1 -triple r600 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=R600
+// RUN: %clang_cc1 -triple arc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=ARC
+// RUN: %clang_cc1 -triple xcore -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=XCORE
+// RUN: %clang_cc1 -triple riscv64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=RISCV64
+// RUN: %clang_cc1 -triple riscv32 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=RISCV32
+// RUN: %clang_cc1 -triple wasm64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=WASM
+// RUN: %clang_cc1 -triple wasm32 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=WASM
+// RUN: %clang_cc1 -triple systemz -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=SYSTEMZ
+// RUN: %clang_cc1 -triple ppc64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=PPC64
+// RUN: %clang_cc1 -triple ppc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=PPC32
+// RUN: %clang_cc1 -triple aarch64 -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64
+// RUN: %clang_cc1 -triple aarch64 -target-abi darwinpcs -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64DARWIN
+// RUN: %clang_cc1 -triple arm64_32-apple-ios -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64
+// RUN: %clang_cc1 -triple arm64_32-apple-ios -target-abi darwinpcs -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64DARWIN
+// RUN: %clang_cc1 -triple arm -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=ARM
 
 // Make sure 128 and 64 bit versions are passed like integers, and that >128
 // is passed indirectly.
@@ -10,33 +36,239 @@ void ParamPassing(_ExtInt(129) a, _ExtInt(128) b, _ExtInt(64) c) {}
 // WIN64: define dso_local void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
 // LIN32: define void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
 // WIN32: define dso_local void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
+// NACL: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// NVPTX64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// NVPTX: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// SPARCV9: define void @ParamPassing(i129* %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// SPARC: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// MIPS64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 signext  %{{.+}}, i64 signext %{{.+}})
+// MIPS: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 signext %{{.+}})
+// SPIR64: define spir_func void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// SPIR: define spir_func void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// HEX: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// LANAI: define void @ParamPassing(i129* byval(i129) align 4 %{{.+}}, i128* byval(i128) align 4 %{{.+}}, i64 %{{.+}})
+// R600: define void @ParamPassing(i129 addrspace(5)* byval(i129) align 8 %{{.+}}, i128 addrspace(5)* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// ARC: define void @ParamPassing(i129* byval(i129) align 4 %{{.+}}, i128* byval(i128) align 4 %{{.+}}, i64 inreg %{{.+}})
+// XCORE: define void @ParamPassing(i129* byval(i129) align 4 %{{.+}}, i128* byval(i128) align 4 %{{.+}}, i64 %{{.+}})
+// RISCV64: define void @ParamPassing(i129* %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// RISCV32: define void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
+// WASM: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// SYSTEMZ: define void @ParamPassing(i129* %{{.+}}, i128* %{{.+}}, i64 %{{.+}})
+// PPC64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// PPC32: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+// AARCH64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// AARCH64DARWIN: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// ARM: define arm_aapcscc void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
+
 void ParamPassing2(_ExtInt(129) a, _ExtInt(127) b, _ExtInt(63) c) {}
 // LIN64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i64 %{{.+}})
 // WIN64: define dso_local void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 %{{.+}})
 // LIN32: define void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 %{{.+}})
 // WIN32: define dso_local void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 %{{.+}})
+// NACL: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// NVPTX64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// NVPTX: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// SPARCV9: define void @ParamPassing2(i129* %{{.+}}, i127 %{{.+}}, i63 signext %{{.+}})
+// SPARC: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// MIPS64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 signext  %{{.+}}, i63 signext %{{.+}})
+// MIPS: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 signext %{{.+}})
+// SPIR64: define spir_func void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// SPIR: define spir_func void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// HEX: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// LANAI: define void @ParamPassing2(i129* byval(i129) align 4 %{{.+}}, i127* byval(i127) align 4 %{{.+}}, i63 %{{.+}})
+// R600: define void @ParamPassing2(i129 addrspace(5)* byval(i129) align 8 %{{.+}}, i127 addrspace(5)* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// ARC: define void @ParamPassing2(i129* byval(i129) align 4 %{{.+}}, i127* byval(i127) align 4 %{{.+}}, i63 inreg %{{.+}})
+// XCORE: define void @ParamPassing2(i129* byval(i129) align 4 %{{.+}}, i127* byval(i127) align 4 %{{.+}}, i63 %{{.+}})
+// RISCV64: define void @ParamPassing2(i129* %{{.+}}, i127 %{{.+}}, i63 signext %{{.+}})
+// RISCV32: define void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 %{{.+}})
+// WASM: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// SYSTEMZ: define void @ParamPassing2(i129* %{{.+}}, i127* %{{.+}}, i63 signext %{{.+}})
+// PPC64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 signext %{{.+}})
+// PPC32: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+// AARCH64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// AARCH64DARWIN: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
+// ARM: define arm_aapcscc void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
+
+// Make sure we follow the signext rules for promotable integer types.
+void ParamPassing3(_ExtInt(15) a, _ExtInt(31) b) {}
+// LIN64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// WIN64: define dso_local void @ParamPassing3(i15 %{{.+}}, i31 %{{.+}})
+// LIN32: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// WIN32: define dso_local void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// NACL: define void @ParamPassing3(i15 %{{.+}}, i31 %{{.+}})
+// NVPTX64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// NVPTX: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SPARCV9: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SPARC: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// MIPS64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// MIPS: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SPIR64: define spir_func void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SPIR: define spir_func void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// HEX: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// LANAI: define void @ParamPassing3(i15 inreg %{{.+}}, i31 inreg %{{.+}})
+// R600: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// ARC: define void @ParamPassing3(i15 inreg signext %{{.+}}, i31 inreg signext %{{.+}})
+// XCORE: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// RISCV64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// RISCV32: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// WASM: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// SYSTEMZ: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// PPC64: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// PPC32: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// AARCH64: define void @ParamPassing3(i15 %{{.+}}, i31 %{{.+}})
+// AARCH64DARWIN: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+// ARM: define arm_aapcscc void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
+
 _ExtInt(63) ReturnPassing(){}
 // LIN64: define i64 @ReturnPassing(
 // WIN64: define dso_local i63 @ReturnPassing(
 // LIN32: define i63 @ReturnPassing(
 // WIN32: define dso_local i63 @ReturnPassing(
+// NACL: define i63 @ReturnPassing(
+// NVPTX64: define i63 @ReturnPassing(
+// NVPTX: define i63 @ReturnPassing(
+// SPARCV9: define signext i63 @ReturnPassing(
+// SPARC: define i63 @ReturnPassing(
+// MIPS64: define i63 @ReturnPassing(
+// MIPS: define i63 @ReturnPassing(
+// SPIR64: define spir_func i63 @ReturnPassing(
+// SPIR: define spir_func i63 @ReturnPassing(
+// HEX: define i63 @ReturnPassing(
+// LANAI: define i63 @ReturnPassing(
+// R600: define i63 @ReturnPassing(
+// ARC: define i63 @ReturnPassing(
+// XCORE: define i63 @ReturnPassing(
+// RISCV64: define signext i63 @ReturnPassing(
+// RISCV32: define i63 @ReturnPassing(
+// WASM: define i63 @ReturnPassing(
+// SYSTEMZ: define signext i63 @ReturnPassing(
+// PPC64: define signext i63 @ReturnPassing(
+// PPC32: define i63 @ReturnPassing(
+// AARCH64: define i63 @ReturnPassing(
+// AARCH64DARWIN: define i63 @ReturnPassing(
+// ARM: define arm_aapcscc i63 @ReturnPassing(
+
 _ExtInt(64) ReturnPassing2(){}
 // LIN64: define i64 @ReturnPassing2(
 // WIN64: define dso_local i64 @ReturnPassing2(
 // LIN32: define i64 @ReturnPassing2(
 // WIN32: define dso_local i64 @ReturnPassing2(
+// NACL: define i64 @ReturnPassing2(
+// NVPTX64: define i64 @ReturnPassing2(
+// NVPTX: define i64 @ReturnPassing2(
+// SPARCV9: define i64 @ReturnPassing2(
+// SPARC: define i64 @ReturnPassing2(
+// MIPS64: define i64 @ReturnPassing2(
+// MIPS: define i64 @ReturnPassing2(
+// SPIR64: define spir_func i64 @ReturnPassing2(
+// SPIR: define spir_func i64 @ReturnPassing2(
+// HEX: define i64 @ReturnPassing2(
+// LANAI: define i64 @ReturnPassing2(
+// R600: define i64 @ReturnPassing2(
+// ARC: define i64 @ReturnPassing2(
+// XCORE: define i64 @ReturnPassing2(
+// RISCV64: define i64 @ReturnPassing2(
+// RISCV32: define i64 @ReturnPassing2(
+// WASM: define i64 @ReturnPassing2(
+// SYSTEMZ: define i64 @ReturnPassing2(
+// PPC64: define i64 @ReturnPassing2(
+// PPC32: define i64 @ReturnPassing2(
+// AARCH64: define i64 @ReturnPassing2(
+// AARCH64DARWIN: define i64 @ReturnPassing2(
+// ARM: define arm_aapcscc i64 @ReturnPassing2(
+
 _ExtInt(127) ReturnPassing3(){}
 // LIN64: define { i64, i64 } @ReturnPassing3(
 // WIN64: define dso_local void @ReturnPassing3(i127* noalias sret
-// LIN32: define i127 @ReturnPassing3(
-// WIN32: define dso_local i127 @ReturnPassing3(
+// LIN32: define void @ReturnPassing3(i127* noalias sret
+// WIN32: define dso_local void @ReturnPassing3(i127* noalias sret
+// NACL: define void @ReturnPassing3(i127* noalias sret
+// NVPTX/64 makes the intentional choice to put all return values direct, even
+// large structures, so we do the same here.
+// NVPTX64: define i127 @ReturnPassing3(
+// NVPTX: define i127 @ReturnPassing3(
+// SPARCV9: define i127 @ReturnPassing3(
+// SPARC: define void @ReturnPassing3(i127* noalias sret
+// MIPS64: define i127 @ReturnPassing3(
+// MIPS: define void @ReturnPassing3(i127* noalias sret
+// SPIR64: define spir_func i127 @ReturnPassing3(
+// SPIR: define spir_func void @ReturnPassing3(i127* noalias sret
+// HEX: define void @ReturnPassing3(i127* noalias sret
+// LANAI: define void @ReturnPassing3(i127* noalias sret
+// R600: define void @ReturnPassing3(i127 addrspace(5)* noalias sret
+// ARC: define void @ReturnPassing3(i127* noalias sret
+// XCORE: define void @ReturnPassing3(i127* noalias sret
+// RISCV64: define i127 @ReturnPassing3(
+// RISCV32: define void @ReturnPassing3(i127* noalias sret
+// WASM: define i127 @ReturnPassing3(
+// SYSTEMZ: define void @ReturnPassing3(i127* noalias sret
+// PPC64: define i127 @ReturnPassing3(
+// PPC32: define void @ReturnPassing3(i127* noalias sret
+// AARCH64: define i127 @ReturnPassing3(
+// AARCH64DARWIN: define i127 @ReturnPassing3(
+// ARM: define arm_aapcscc void @ReturnPassing3(i127* noalias sret
+
 _ExtInt(128) ReturnPassing4(){}
 // LIN64: define { i64, i64 } @ReturnPassing4(
 // WIN64: define dso_local void @ReturnPassing4(i128* noalias sret
-// LIN32: define i128 @ReturnPassing4(
-// WIN32: define dso_local i128 @ReturnPassing4(
+// LIN32: define void @ReturnPassing4(i128* noalias sret
+// WIN32: define dso_local void @ReturnPassing4(i128* noalias sret
+// NACL: define void @ReturnPassing4(i128* noalias sret
+// NVPTX64: define i128 @ReturnPassing4(
+// NVPTX: define i128 @ReturnPassing4(
+// SPARCV9: define i128 @ReturnPassing4(
+// SPARC: define void @ReturnPassing4(i128* noalias sret
+// MIPS64: define i128 @ReturnPassing4(
+// MIPS: define void @ReturnPassing4(i128* noalias sret
+// SPIR64: define spir_func i128 @ReturnPassing4(
+// SPIR: define spir_func void @ReturnPassing4(i128* noalias sret
+// HEX: define void @ReturnPassing4(i128* noalias sret
+// LANAI: define void @ReturnPassing4(i128* noalias sret
+// R600: define void @ReturnPassing4(i128 addrspace(5)* noalias sret
+// ARC: define void @ReturnPassing4(i128* noalias sret
+// XCORE: define void @ReturnPassing4(i128* noalias sret
+// RISCV64: define i128 @ReturnPassing4(
+// RISCV32: define void @ReturnPassing4(i128* noalias sret
+// WASM: define i128 @ReturnPassing4(
+// SYSTEMZ: define void @ReturnPassing4(i128* noalias sret
+// PPC64: define i128 @ReturnPassing4(
+// PPC32: define void @ReturnPassing4(i128* noalias sret
+// AARCH64: define i128 @ReturnPassing4(
+// AARCH64DARWIN: define i128 @ReturnPassing4(
+// ARM: define arm_aapcscc void @ReturnPassing4(i128* noalias sret
+
 _ExtInt(129) ReturnPassing5(){}
 // LIN64: define void @ReturnPassing5(i129* noalias sret
 // WIN64: define dso_local void @ReturnPassing5(i129* noalias sret
-// LIN32: define i129 @ReturnPassing5(
-// WIN32: define dso_local i129 @ReturnPassing5(
+// LIN32: define void @ReturnPassing5(i129* noalias sret
+// WIN32: define dso_local void @ReturnPassing5(i129* noalias sret
+// NACL: define void @ReturnPassing5(i129* noalias sret
+// NVPTX64: define i129 @ReturnPassing5(
+// NVPTX: define i129 @ReturnPassing5(
+// SPARCV9: define i129 @ReturnPassing5(
+// SPARC: define void @ReturnPassing5(i129* noalias sret
+// MIPS64: define void @ReturnPassing5(i129* noalias sret
+// MIPS: define void @ReturnPassing5(i129* noalias sret
+// SPIR64: define spir_func void @ReturnPassing5(i129* noalias sret
+// SPIR: define spir_func void @ReturnPassing5(i129* noalias sret
+// HEX: define void @ReturnPassing5(i129* noalias sret
+// LANAI: define void @ReturnPassing5(i129* noalias sret
+// R600: define void @ReturnPassing5(i129 addrspace(5)* noalias sret
+// ARC: define void @ReturnPassing5(i129* inreg noalias sret
+// XCORE: define void @ReturnPassing5(i129* noalias sret
+// RISCV64: define void @ReturnPassing5(i129* noalias sret
+// RISCV32: define void @ReturnPassing5(i129* noalias sret
+// WASM: define void @ReturnPassing5(i129* noalias sret
+// SYSTEMZ: define void @ReturnPassing5(i129* noalias sret
+// PPC64: define void @ReturnPassing5(i129* noalias sret
+// PPC32: define void @ReturnPassing5(i129* noalias sret
+// AARCH64: define void @ReturnPassing5(i129* noalias sret
+// AARCH64DARWIN: define void @ReturnPassing5(i129* noalias sret
+// ARM: define arm_aapcscc void @ReturnPassing5(i129* noalias sret
+
+// SparcV9 is odd in that it has a return-size limit of 256, not 128 or 64
+// like other platforms, so test to make sure this behavior will still work.
+_ExtInt(256) ReturnPassing6() {}
+// SPARCV9: define i256 @ReturnPassing6(
+_ExtInt(257) ReturnPassing7() {}
+// SPARCV9: define void @ReturnPassing7(i257* noalias sret

diff  --git a/clang/test/CodeGen/ext-int-sanitizer.cpp b/clang/test/CodeGen/ext-int-sanitizer.cpp
index eaaab1b56c34..144ad3a4c91f 100644
--- a/clang/test/CodeGen/ext-int-sanitizer.cpp
+++ b/clang/test/CodeGen/ext-int-sanitizer.cpp
@@ -145,8 +145,7 @@ void DivByZero(_ExtInt(11) E, int i) {
 
   // Also triggers signed integer overflow.
   E / E;
-  // CHECK: %[[E1LOAD:.+]] = load i11
-  // CHECK: store i11 %[[E1LOAD]], i11* %[[EADDR:.+]]
+  // CHECK: %[[EADDR:.+]] = alloca i11
   // CHECK: %[[E:.+]] = load i11, i11* %[[EADDR]]
   // CHECK: %[[E2:.+]] = load i11, i11* %[[EADDR]]
   // CHECK: %[[NEZERO:.+]] = icmp ne i11 %[[E2]], 0
@@ -163,8 +162,7 @@ void DivByZero(_ExtInt(11) E, int i) {
 // CHECK: define void @_Z6ShiftsU7_ExtIntILi9EEi
 void Shifts(_ExtInt(9) E) {
   E >> E;
-  // CHECK: %[[E1LOAD:.+]] = load i9, i9*
-  // CHECK: store i9 %[[E1LOAD]], i9* %[[EADDR:.+]]
+  // CHECK: %[[EADDR:.+]] = alloca i9
   // CHECK: %[[LHSE:.+]] = load i9, i9* %[[EADDR]]
   // CHECK: %[[RHSE:.+]] = load i9, i9* %[[EADDR]]
   // CHECK: %[[CMP:.+]] = icmp ule i9 %[[RHSE]], 8
@@ -227,8 +225,7 @@ void UnsignedIntegerOverflow(unsigned u,
                              unsigned _ExtInt(23) SmallE,
                              unsigned _ExtInt(35) BigE) {
   u = SmallE + SmallE;
-  // CHECK: %[[LOADBIGGESTE2:.+]] = load i23
-  // CHECK: store i23 %[[LOADBIGGESTE2]], i23* %[[BIGGESTEADDR:.+]]
+  // CHECK: %[[BIGGESTEADDR:.+]] = alloca i23
   // CHECK: %[[LOADE1:.+]] = load i23, i23* %[[BIGGESTEADDR]]
   // CHECK: %[[LOADE2:.+]] = load i23, i23* %[[BIGGESTEADDR]]
   // CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADE1]], i23 %[[LOADE2]])

diff  --git a/clang/test/CodeGenCXX/ext-int.cpp b/clang/test/CodeGenCXX/ext-int.cpp
index 3e72d3ab66c1..131b9cd4388c 100644
--- a/clang/test/CodeGenCXX/ext-int.cpp
+++ b/clang/test/CodeGenCXX/ext-int.cpp
@@ -98,7 +98,7 @@ enum AsEnumUnderlyingType : _ExtInt(9) {
 };
 
 void UnderlyingTypeUsage(AsEnumUnderlyingType Param) {
-  // LIN: define void @_Z19UnderlyingTypeUsage20AsEnumUnderlyingType(i16 %
+  // LIN: define void @_Z19UnderlyingTypeUsage20AsEnumUnderlyingType(i9 signext %
   // WIN: define dso_local void @"?UnderlyingTypeUsage@@YAXW4AsEnumUnderlyingType@@@Z"(i9 %
   AsEnumUnderlyingType Var;
   // CHECK: alloca i9, align 2

diff  --git a/clang/test/Sema/ext-int-not-supported.c b/clang/test/Sema/ext-int-not-supported.c
deleted file mode 100644
index 23610b9941e4..000000000000
--- a/clang/test/Sema/ext-int-not-supported.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify %s
-
-void foo() {
-  _ExtInt(33) a; // expected-error{{_ExtInt is not supported on this target}}
-}


        


More information about the cfe-commits mailing list