erichkeane updated this revision to Diff 261523.
erichkeane retitled this revision from "[WIP] _ExtInt calling convention Audit" 
to "Implement _ExtInt ABI for all ABIs in Clang, enable type for ABIs".
erichkeane edited the summary of this revision.
erichkeane added a subscriber: cfe-commits.
erichkeane added a comment.
Herald added subscribers: kerbowa, luismarques, apazos, sameer.abuasal, pzheng, 
lenary, Jim, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, 
atanasyan, edward-jones, zzheng, MaskRay, niosHD, sabuasal, johnrusso, rbar, 
asb, kbarton, jgravelle-google, sbc100, nhaehnle, jvesely, nemanjai, sdardis, 
jyknight, jholewinski.

@rjmccall

Alright, i finished the audit and finished all of the ABIs, as well as wrote 
tests for each.  I added a test for situations that I'd not previously covered 
as well.

Can you please review when you can/suggest others to do so?

Thanks!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79118/new/

https://reviews.llvm.org/D79118

Files:
  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

Index: clang/test/CodeGenCXX/ext-int.cpp
===================================================================
--- clang/test/CodeGenCXX/ext-int.cpp
+++ clang/test/CodeGenCXX/ext-int.cpp
@@ -98,7 +98,7 @@
 };
 
 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
Index: clang/test/CodeGen/ext-int-sanitizer.cpp
===================================================================
--- clang/test/CodeGen/ext-int-sanitizer.cpp
+++ clang/test/CodeGen/ext-int-sanitizer.cpp
@@ -145,8 +145,7 @@
 
   // 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 @@
 // 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 @@
                              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]])
Index: clang/test/CodeGen/ext-int-cc.c
===================================================================
--- clang/test/CodeGen/ext-int-cc.c
+++ 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,232 @@
 // 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* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
+// RISCV32: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8  %{{.+}}, 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* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 signext %{{.+}})
+// RISCV32: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, 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(
+// 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(
+// 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(
+// 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
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -97,6 +97,16 @@
   return Address::invalid();
 }
 
+bool ABIInfo::isPromotableIntegerType(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 +711,14 @@
   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
     Ty = EnumTy->getDecl()->getIntegerType();
 
-  return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                        : ABIArgInfo::getDirect());
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 128 ||
+        (EIT->getNumBits() > 64 &&
+         !getContext().getTargetInfo().hasInt128Type()))
+      return getNaturalAlignIndirect(Ty);
+
+  return (isPromotableIntegerType(Ty) ? ABIArgInfo::getExtend(Ty)
+                                      : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
@@ -716,8 +732,14 @@
   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() > 128 ||
+        (EIT->getNumBits() > 64 &&
+         !getContext().getTargetInfo().hasInt128Type()))
+      return getNaturalAlignIndirect(RetTy);
+
+  return (isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                         : ABIArgInfo::getDirect());
 }
 
 //===----------------------------------------------------------------------===//
@@ -933,10 +955,15 @@
   } 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 (isPromotableIntegerType(Ty) ? ABIArgInfo::getExtend(Ty)
+                                      : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
@@ -947,12 +974,19 @@
   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 (isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                         : ABIArgInfo::getDirect());
 }
 
 /// IsX86_MMXType - Return true if this is an MMX type.
@@ -1498,8 +1532,8 @@
   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
     RetTy = EnumTy->getDecl()->getIntegerType();
 
-  return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
-                                           : ABIArgInfo::getDirect());
+  return (isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                         : ABIArgInfo::getDirect());
 }
 
 static bool isSSEVectorType(ASTContext &Context, QualType Ty) {
@@ -1816,7 +1850,7 @@
 
   bool InReg = shouldPrimitiveUseInReg(Ty, State);
 
-  if (Ty->isPromotableIntegerType()) {
+  if (isPromotableIntegerType(Ty)) {
     if (InReg)
       return ABIArgInfo::getExtendInReg(Ty);
     return ABIArgInfo::getExtend(Ty);
@@ -2977,9 +3011,11 @@
     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 (isPromotableIntegerType(Ty) ? ABIArgInfo::getExtend(Ty)
+                                        : ABIArgInfo::getDirect());
   }
 
   return getNaturalAlignIndirect(Ty);
@@ -3017,8 +3053,8 @@
     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
       Ty = EnumTy->getDecl()->getIntegerType();
 
-    return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
-                                          : ABIArgInfo::getDirect());
+    return (isPromotableIntegerType(Ty) ? ABIArgInfo::getExtend(Ty)
+                                        : ABIArgInfo::getDirect());
   }
 
   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
@@ -3400,7 +3436,7 @@
         RetTy = EnumTy->getDecl()->getIntegerType();
 
       if (RetTy->isIntegralOrEnumerationType() &&
-          RetTy->isPromotableIntegerType())
+          isPromotableIntegerType(RetTy))
         return ABIArgInfo::getExtend(RetTy);
     }
     break;
@@ -3545,7 +3581,7 @@
         Ty = EnumTy->getDecl()->getIntegerType();
 
       if (Ty->isIntegralOrEnumerationType() &&
-          Ty->isPromotableIntegerType())
+          isPromotableIntegerType(Ty))
         return ABIArgInfo::getExtend(Ty);
     }
 
@@ -4662,7 +4698,7 @@
     Ty = EnumTy->getDecl()->getIntegerType();
 
   // Promotable integer types are required to be promoted by the ABI.
-  if (Ty->isPromotableIntegerType())
+  if (isPromotableIntegerType(Ty))
     return true;
 
   // In addition to the usual promotable integer types, we also need to
@@ -4676,6 +4712,10 @@
       break;
     }
 
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() < 64)
+      return true;
+
   return false;
 }
 
@@ -4893,6 +4933,10 @@
     }
   }
 
+  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 +5009,10 @@
     }
   }
 
+  if (const auto *EIT = RetTy->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 128)
+      return getNaturalAlignIndirect(RetTy, /*ByVal=*/true);
+
   if (isAggregateTypeForABI(RetTy)) {
     // ELFv2 homogeneous aggregates are returned as array types.
     const Type *Base = nullptr;
@@ -5301,7 +5349,11 @@
     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 (isPromotableIntegerType(Ty) && isDarwinPCS()
                 ? ABIArgInfo::getExtend(Ty)
                 : ABIArgInfo::getDirect());
   }
@@ -5378,7 +5430,11 @@
     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 (isPromotableIntegerType(RetTy) && isDarwinPCS()
                 ? ABIArgInfo::getExtend(RetTy)
                 : ABIArgInfo::getDirect());
   }
@@ -6068,7 +6124,11 @@
       Ty = EnumTy->getDecl()->getIntegerType();
     }
 
-    return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend(Ty)
+    if (const auto *EIT = Ty->getAs<ExtIntType>())
+      if (EIT->getNumBits() > 64)
+        return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+
+    return (isPromotableIntegerType(Ty) ? ABIArgInfo::getExtend(Ty)
                                           : ABIArgInfo::getDirect());
   }
 
@@ -6274,8 +6334,12 @@
     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=*/true);
+
+    return isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                          : ABIArgInfo::getDirect();
   }
 
   // Are we following APCS?
@@ -6598,6 +6662,9 @@
       (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;
@@ -6650,8 +6717,8 @@
   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
     RetTy = EnumTy->getDecl()->getIntegerType();
 
-  return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy)
-                                           : ABIArgInfo::getDirect());
+  return (isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                         : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const {
@@ -6674,8 +6741,15 @@
     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 (isPromotableIntegerType(Ty) ? ABIArgInfo::getExtend(Ty)
+                                      : ABIArgInfo::getDirect());
 }
 
 void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
@@ -6794,7 +6868,7 @@
   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 +6905,19 @@
 
 }
 
-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 (isPromotableIntegerType(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 +7164,8 @@
     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 +7174,7 @@
     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 +7469,13 @@
   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 +7560,14 @@
   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 (isPromotableIntegerType(RetTy))
     return ABIArgInfo::getExtend(RetTy);
 
   if ((RetTy->isUnsignedIntegerOrEnumerationType() ||
@@ -7769,8 +7861,11 @@
     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 isPromotableIntegerType(Ty) ? ABIArgInfo::getExtend(Ty)
+                                       : ABIArgInfo::getDirect();
   }
 
   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
@@ -7822,8 +7917,11 @@
     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=*/true);
+
+    return isPromotableIntegerType(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                          : ABIArgInfo::getDirect();
   }
 
   if (isEmptyRecord(getContext(), RetTy, true))
@@ -8186,7 +8284,13 @@
     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 (isPromotableIntegerType(Ty)) {
     if (InReg)
       return ABIArgInfo::getDirectInReg();
     return ABIArgInfo::getExtend(Ty);
@@ -8881,7 +8985,7 @@
   if (Ty->isVoidType())
     return ABIArgInfo::getIgnore();
 
-  uint64_t Size = getContext().getTypeSize(Ty);
+  uint64_t Size = getContext().getIntWidth(Ty);
 
   // Anything too big to fit in registers is passed with an explicit indirect
   // pointer / sret pointer.
@@ -9145,7 +9249,11 @@
         ABIArgInfo::getDirect(Result, 0, nullptr, false);
   }
 
-  return Ty->isPromotableIntegerType() ?
+  if (const auto *EIT = Ty->getAs<ExtIntType>())
+    if (EIT->getNumBits() > 64)
+      return getIndirectByValue(Ty);
+
+  return isPromotableIntegerType(Ty) ?
       (FreeRegs >= SizeInRegs ? ABIArgInfo::getExtendInReg(Ty) :
                                 ABIArgInfo::getExtend(Ty)) :
       (FreeRegs >= SizeInRegs ? ABIArgInfo::getDirectInReg() :
@@ -10180,6 +10288,15 @@
       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=*/true);
+    }
+
     return ABIArgInfo::getDirect();
   }
 
Index: clang/lib/CodeGen/ABIInfo.h
===================================================================
--- clang/lib/CodeGen/ABIInfo.h
+++ clang/lib/CodeGen/ABIInfo.h
@@ -102,6 +102,10 @@
     bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
                                 uint64_t &Members) const;
 
+    // Implement the Type::IsPromotableIntegerType for ABI specific needs. The
+    // only difference is that this considers _ExtInt as well.
+    bool isPromotableIntegerType(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
Index: clang/lib/Basic/Targets/XCore.h
===================================================================
--- clang/lib/Basic/Targets/XCore.h
+++ clang/lib/Basic/Targets/XCore.h
@@ -75,6 +75,8 @@
   }
 
   bool allowsLargerPreferedTypeAlignment() const override { return false; }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang
Index: clang/lib/Basic/Targets/WebAssembly.h
===================================================================
--- clang/lib/Basic/Targets/WebAssembly.h
+++ clang/lib/Basic/Targets/WebAssembly.h
@@ -130,6 +130,8 @@
       return CCCR_Warning;
     }
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
     : public WebAssemblyTargetInfo {
Index: clang/lib/Basic/Targets/SystemZ.h
===================================================================
--- clang/lib/Basic/Targets/SystemZ.h
+++ clang/lib/Basic/Targets/SystemZ.h
@@ -150,6 +150,8 @@
   }
 
   const char *getLongDoubleMangling() const override { return "g"; }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang
Index: clang/lib/Basic/Targets/Sparc.h
===================================================================
--- clang/lib/Basic/Targets/Sparc.h
+++ clang/lib/Basic/Targets/Sparc.h
@@ -176,6 +176,7 @@
                         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 @@
       return false;
     return getCPUGeneration(CPU) == CG_V9;
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang
Index: clang/lib/Basic/Targets/SPIR.h
===================================================================
--- clang/lib/Basic/Targets/SPIR.h
+++ clang/lib/Basic/Targets/SPIR.h
@@ -100,6 +100,8 @@
     // for SPIR since it is a generic target.
     getSupportedOpenCLOpts().supportAll();
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
 public:
Index: clang/lib/Basic/Targets/RISCV.h
===================================================================
--- clang/lib/Basic/Targets/RISCV.h
+++ clang/lib/Basic/Targets/RISCV.h
@@ -76,6 +76,8 @@
 
   bool handleTargetFeatures(std::vector<std::string> &Features,
                             DiagnosticsEngine &Diags) override;
+
+  bool hasExtIntType() const override { return true; }
 };
 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
 public:
Index: clang/lib/Basic/Targets/PPC.h
===================================================================
--- clang/lib/Basic/Targets/PPC.h
+++ clang/lib/Basic/Targets/PPC.h
@@ -332,6 +332,8 @@
                : "u9__ieee128";
   }
   const char *getFloat128Mangling() const override { return "u9__ieee128"; }
+
+  bool hasExtIntType() const override { return true; }
 };
 
 class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {
Index: clang/lib/Basic/Targets/PNaCl.h
===================================================================
--- clang/lib/Basic/Targets/PNaCl.h
+++ clang/lib/Basic/Targets/PNaCl.h
@@ -68,6 +68,8 @@
   }
 
   const char *getClobbers() const override { return ""; }
+
+  bool hasExtIntType() const override { return true; }
 };
 
 // We attempt to use PNaCl (le32) frontend and Mips32EL backend.
Index: clang/lib/Basic/Targets/NVPTX.h
===================================================================
--- clang/lib/Basic/Targets/NVPTX.h
+++ clang/lib/Basic/Targets/NVPTX.h
@@ -160,6 +160,10 @@
       return HostTarget->checkCallingConvention(CC);
     return CCCR_Warning;
   }
+
+  bool hasExtIntType() const override {
+    return true;
+  }
 };
 } // namespace targets
 } // namespace clang
Index: clang/lib/Basic/Targets/Mips.h
===================================================================
--- clang/lib/Basic/Targets/Mips.h
+++ clang/lib/Basic/Targets/Mips.h
@@ -406,6 +406,7 @@
   unsigned getUnwindWordWidth() const override;
 
   bool validateTarget(DiagnosticsEngine &Diags) const override;
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang
Index: clang/lib/Basic/Targets/Lanai.h
===================================================================
--- clang/lib/Basic/Targets/Lanai.h
+++ clang/lib/Basic/Targets/Lanai.h
@@ -86,6 +86,8 @@
   }
 
   const char *getClobbers() const override { return ""; }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang
Index: clang/lib/Basic/Targets/Hexagon.h
===================================================================
--- clang/lib/Basic/Targets/Hexagon.h
+++ clang/lib/Basic/Targets/Hexagon.h
@@ -138,6 +138,8 @@
     // We can write more stricter checks later.
     return CPU.find('t') != std::string::npos;
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 } // namespace targets
 } // namespace clang
Index: clang/lib/Basic/Targets/ARM.h
===================================================================
--- clang/lib/Basic/Targets/ARM.h
+++ clang/lib/Basic/Targets/ARM.h
@@ -182,6 +182,8 @@
   int getEHDataRegisterNumber(unsigned RegNo) const override;
 
   bool hasSjLjLowering() const override;
+
+  bool hasExtIntType() const override { return true; }
 };
 
 class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
Index: clang/lib/Basic/Targets/ARC.h
===================================================================
--- clang/lib/Basic/Targets/ARC.h
+++ clang/lib/Basic/Targets/ARC.h
@@ -65,6 +65,8 @@
                              TargetInfo::ConstraintInfo &Info) const override {
     return false;
   }
+
+  bool hasExtIntType() const override { return true; }
 };
 
 } // namespace targets
Index: clang/lib/Basic/Targets/AMDGPU.h
===================================================================
--- clang/lib/Basic/Targets/AMDGPU.h
+++ clang/lib/Basic/Targets/AMDGPU.h
@@ -354,6 +354,8 @@
   }
 
   void setAuxTarget(const TargetInfo *Aux) override;
+
+  bool hasExtIntType() const override { return true; }
 };
 
 } // namespace targets
Index: clang/lib/Basic/Targets/AArch64.h
===================================================================
--- clang/lib/Basic/Targets/AArch64.h
+++ clang/lib/Basic/Targets/AArch64.h
@@ -120,6 +120,8 @@
   int getEHDataRegisterNumber(unsigned RegNo) const override;
 
   bool hasInt128Type() const override;
+
+  bool hasExtIntType() const override { return true; }
 };
 
 class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to