[PATCH] D39210: Add default calling convention support for regcall.

2017-11-02 Thread Erich Keane via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL317268: Add default calling convention support for regcall. 
(authored by erichkeane).

Changed prior to commit:
  https://reviews.llvm.org/D39210?vs=120284&id=121372#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D39210

Files:
  cfe/trunk/include/clang/Basic/LangOptions.h
  cfe/trunk/include/clang/Driver/CC1Options.td
  cfe/trunk/include/clang/Driver/CLCompatOptions.td
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/Driver/ToolChains/Clang.cpp
  cfe/trunk/lib/Frontend/CompilerInvocation.cpp
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/test/CodeGenCXX/default_calling_conv.cpp
  cfe/trunk/test/Driver/cl-cc-flags.c

Index: cfe/trunk/include/clang/Driver/CC1Options.td
===
--- cfe/trunk/include/clang/Driver/CC1Options.td
+++ cfe/trunk/include/clang/Driver/CC1Options.td
@@ -704,7 +704,7 @@
 def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
   HelpText<"Allow function arguments and returns of type half">;
 def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">,
-  HelpText<"Set default MS calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall">;
+  HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">;
 def finclude_default_header : Flag<["-"], "finclude-default-header">,
   HelpText<"Include the default header file for OpenCL">;
 def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">,
Index: cfe/trunk/include/clang/Driver/CLCompatOptions.td
===
--- cfe/trunk/include/clang/Driver/CLCompatOptions.td
+++ cfe/trunk/include/clang/Driver/CLCompatOptions.td
@@ -302,6 +302,8 @@
   HelpText<"Set __stdcall as a default calling convention">;
 def _SLASH_Gv : CLFlag<"Gv">,
   HelpText<"Set __vectorcall as a default calling convention">;
+def _SLASH_Gregcall : CLFlag<"Gregcall">,
+  HelpText<"Set __regcall as a default calling convention">;
 
 // Ignored:
 
Index: cfe/trunk/include/clang/Basic/LangOptions.h
===
--- cfe/trunk/include/clang/Basic/LangOptions.h
+++ cfe/trunk/include/clang/Basic/LangOptions.h
@@ -77,7 +77,8 @@
 DCC_CDecl,
 DCC_FastCall,
 DCC_StdCall,
-DCC_VectorCall
+DCC_VectorCall,
+DCC_RegCall
   };
 
   enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
Index: cfe/trunk/test/Driver/cl-cc-flags.c
===
--- cfe/trunk/test/Driver/cl-cc-flags.c
+++ cfe/trunk/test/Driver/cl-cc-flags.c
@@ -13,6 +13,9 @@
 // RUN: %clang_cl --target=i686-windows-msvc /Gv -### -- %s 2>&1 | FileCheck --check-prefix=VECTORCALL %s
 // VECTORCALL: -fdefault-calling-conv=vectorcall
 
+// RUN: %clang_cl --target=i686-windows-msvc /Gregcall -### -- %s 2>&1 | FileCheck --check-prefix=REGCALL %s
+// REGCALL: -fdefault-calling-conv=regcall
+
 // Last one should win:
 
 // RUN: %clang_cl --target=i686-windows-msvc /Gd /Gv -### -- %s 2>&1 | FileCheck --check-prefix=LASTWINS_VECTOR %s
Index: cfe/trunk/test/CodeGenCXX/default_calling_conv.cpp
===
--- cfe/trunk/test/CodeGenCXX/default_calling_conv.cpp
+++ cfe/trunk/test/CodeGenCXX/default_calling_conv.cpp
@@ -3,18 +3,21 @@
 // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
 // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
 // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL
 
 // CDECL: define void @_Z5test1v
 // FASTCALL: define x86_fastcallcc void @_Z5test1v
 // STDCALL: define x86_stdcallcc void @_Z5test1v
 // VECTORCALL: define x86_vectorcallcc void @_Z5test1v
+// REGCALL: define x86_regcallcc void @_Z17__regcall3__test1v
 void test1() {}
 
-// fastcall, stdcall, and vectorcall all do not support variadic functions.
+// fastcall, stdcall, vectorcall and regcall do not support variadic functions.
 // CDECL: define void @_Z12testVariadicz
 // FASTCALL: define void @_Z12testVariadicz
 // STDCALL: define void @_Z12testVariadicz
 // VECTORCALL: define void @_Z12testVariadicz
+// REGCALL: define void @_Z12testVariadicz
 void testVariadic(...){}
 
 // ALL: define void @_Z5test2v
@@ -29,6 +32,9 @@
 // ALL: define  x86_vectorcallcc void @_Z5test5v
 void __attribute__((vectorcall)) test5() {}
 
+// ALL: define x86_regcallcc void @_Z17__regcall3__test6v
+void __attribute__((regcall)) test6() {}
+

[PATCH] D39210: Add default calling convention support for regcall.

2017-11-02 Thread Elizabeth Andrews via Phabricator via cfe-commits
eandrews added a comment.

No problem! Thanks!


https://reviews.llvm.org/D39210



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39210: Add default calling convention support for regcall.

2017-11-02 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

Looks good! Sorry for the delay.


https://reviews.llvm.org/D39210



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39210: Add default calling convention support for regcall.

2017-11-02 Thread Elizabeth Andrews via Phabricator via cfe-commits
eandrews added a comment.

*ping*


https://reviews.llvm.org/D39210



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39210: Add default calling convention support for regcall.

2017-10-25 Thread Elizabeth Andrews via Phabricator via cfe-commits
eandrews added inline comments.



Comment at: lib/Sema/SemaType.cpp:3269-3273
+  bool IsMain = false;
+  if (D.getIdentifier() && D.getIdentifier()->isStr("main") &&
+  S.CurContext->getRedeclContext()->isTranslationUnit() &&
+  !S.getLangOpts().Freestanding)
+IsMain = true;

erichkeane wrote:
> rnk wrote:
> > erichkeane wrote:
> > > rnk wrote:
> > > > I highly doubt this is correct. I have a feeling there are all kinds of 
> > > > ways you can get this to fire on things that aren't a function 
> > > > declaration. It's also inefficient to check the identifier string every 
> > > > time we make a function type. Please find somewhere else to add this. 
> > > > I'd suggest adjusting the function type in CheckMain, or some time 
> > > > before then, whereever we make main implicitly extern "C".
> > > I believe the logic here was pulled from FunctionDecl's "isMain" 
> > > function: 
> > > https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html#aa2b31caf653741632b16cce1ae2061cc
> > > 
> > > As this is so early in the process (at Declarator), I didn't see a good 
> > > place to recommend extracting this, besides pulling it into the 
> > > Declarator.  
> > > 
> > > CheckMain is also run at the Decl stage, isn't it?  Is your suggestion be 
> > > to simply let this go through with the wrong calling-convention here, 
> > > then revert it it in "CheckMain"?
> > Yep. You can look at how we use FunctionTypeUnwrapper and 
> > ASTContext::adjustFunctionType in various places to fix up function types 
> > that were built with the wrong calling convention without losing type 
> > source info.
> Perfect, thanks for the examples!  I am sure @eandrews can use those to track 
> down the right place to fix this up.
Thanks for the review! I've updated the patch. Please take a look.


https://reviews.llvm.org/D39210



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39210: Add default calling convention support for regcall.

2017-10-25 Thread Elizabeth Andrews via Phabricator via cfe-commits
eandrews updated this revision to Diff 120284.
eandrews added a comment.

Updated patch to set default calling convention for main() in CheckMain()


https://reviews.llvm.org/D39210

Files:
  include/clang/Basic/LangOptions.h
  include/clang/Driver/CC1Options.td
  include/clang/Driver/CLCompatOptions.td
  lib/AST/ASTContext.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Sema/SemaDecl.cpp
  test/CodeGenCXX/default_calling_conv.cpp
  test/Driver/cl-cc-flags.c

Index: test/Driver/cl-cc-flags.c
===
--- test/Driver/cl-cc-flags.c
+++ test/Driver/cl-cc-flags.c
@@ -13,6 +13,9 @@
 // RUN: %clang_cl --target=i686-windows-msvc /Gv -### -- %s 2>&1 | FileCheck --check-prefix=VECTORCALL %s
 // VECTORCALL: -fdefault-calling-conv=vectorcall
 
+// RUN: %clang_cl --target=i686-windows-msvc /Gregcall -### -- %s 2>&1 | FileCheck --check-prefix=REGCALL %s
+// REGCALL: -fdefault-calling-conv=regcall
+
 // Last one should win:
 
 // RUN: %clang_cl --target=i686-windows-msvc /Gd /Gv -### -- %s 2>&1 | FileCheck --check-prefix=LASTWINS_VECTOR %s
Index: test/CodeGenCXX/default_calling_conv.cpp
===
--- test/CodeGenCXX/default_calling_conv.cpp
+++ test/CodeGenCXX/default_calling_conv.cpp
@@ -3,18 +3,21 @@
 // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
 // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
 // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL
 
 // CDECL: define void @_Z5test1v
 // FASTCALL: define x86_fastcallcc void @_Z5test1v
 // STDCALL: define x86_stdcallcc void @_Z5test1v
 // VECTORCALL: define x86_vectorcallcc void @_Z5test1v
+// REGCALL: define x86_regcallcc void @_Z17__regcall3__test1v
 void test1() {}
 
-// fastcall, stdcall, and vectorcall all do not support variadic functions.
+// fastcall, stdcall, vectorcall and regcall do not support variadic functions.
 // CDECL: define void @_Z12testVariadicz
 // FASTCALL: define void @_Z12testVariadicz
 // STDCALL: define void @_Z12testVariadicz
 // VECTORCALL: define void @_Z12testVariadicz
+// REGCALL: define void @_Z12testVariadicz
 void testVariadic(...){}
 
 // ALL: define void @_Z5test2v
@@ -29,6 +32,9 @@
 // ALL: define  x86_vectorcallcc void @_Z5test5v
 void __attribute__((vectorcall)) test5() {}
 
+// ALL: define x86_regcallcc void @_Z17__regcall3__test6v
+void __attribute__((regcall)) test6() {}
+
 // ALL: define linkonce_odr void @_ZN1A11test_memberEv
 class A {
 public:
@@ -39,3 +45,8 @@
   A a;
   a.test_member();
 }
+
+// ALL: define i32 @main
+int main() {
+  return 1;
+}
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -9673,6 +9673,13 @@
   assert(T->isFunctionType() && "function decl is not of function type");
   const FunctionType* FT = T->castAs();
 
+  // Set default calling convention for main()
+  if (FT->getCallConv() != CC_C) {
+FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(CC_C));
+FD->setType(QualType(FT, 0));
+T = Context.getCanonicalType(FD->getType());
+  }
+
   if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
 // In C with GNU extensions we allow main() to have non-integer return
 // type, but we should warn about the extension, and we disable the
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2308,12 +2308,12 @@
   // Check for MS default calling conventions being specified.
   if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
 LangOptions::DefaultCallingConvention DefaultCC =
-llvm::StringSwitch(
-A->getValue())
+llvm::StringSwitch(A->getValue())
 .Case("cdecl", LangOptions::DCC_CDecl)
 .Case("fastcall", LangOptions::DCC_FastCall)
 .Case("stdcall", LangOptions::DCC_StdCall)
 .Case("vectorcall", LangOptions::DCC_VectorCall)
+.Case("regcall", LangOptions::DCC_RegCall)
 .Default(LangOptions::DCC_None);
 if (DefaultCC == LangOptions::DCC_None)
   Diags.Report(diag::err_drv_invalid_value)
@@ -2324,7 +2324,8 @@
 bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
   DefaultCC == LangOptions::DCC_StdCall) &&
  Arch != llvm::Triple::x86;
-emitError |= DefaultCC =

[PATCH] D39210: Add default calling convention support for regcall.

2017-10-23 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: lib/Sema/SemaType.cpp:3269-3273
+  bool IsMain = false;
+  if (D.getIdentifier() && D.getIdentifier()->isStr("main") &&
+  S.CurContext->getRedeclContext()->isTranslationUnit() &&
+  !S.getLangOpts().Freestanding)
+IsMain = true;

rnk wrote:
> erichkeane wrote:
> > rnk wrote:
> > > I highly doubt this is correct. I have a feeling there are all kinds of 
> > > ways you can get this to fire on things that aren't a function 
> > > declaration. It's also inefficient to check the identifier string every 
> > > time we make a function type. Please find somewhere else to add this. I'd 
> > > suggest adjusting the function type in CheckMain, or some time before 
> > > then, whereever we make main implicitly extern "C".
> > I believe the logic here was pulled from FunctionDecl's "isMain" function: 
> > https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html#aa2b31caf653741632b16cce1ae2061cc
> > 
> > As this is so early in the process (at Declarator), I didn't see a good 
> > place to recommend extracting this, besides pulling it into the Declarator. 
> >  
> > 
> > CheckMain is also run at the Decl stage, isn't it?  Is your suggestion be 
> > to simply let this go through with the wrong calling-convention here, then 
> > revert it it in "CheckMain"?
> Yep. You can look at how we use FunctionTypeUnwrapper and 
> ASTContext::adjustFunctionType in various places to fix up function types 
> that were built with the wrong calling convention without losing type source 
> info.
Perfect, thanks for the examples!  I am sure @eandrews can use those to track 
down the right place to fix this up.


https://reviews.llvm.org/D39210



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39210: Add default calling convention support for regcall.

2017-10-23 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: lib/Sema/SemaType.cpp:3269-3273
+  bool IsMain = false;
+  if (D.getIdentifier() && D.getIdentifier()->isStr("main") &&
+  S.CurContext->getRedeclContext()->isTranslationUnit() &&
+  !S.getLangOpts().Freestanding)
+IsMain = true;

erichkeane wrote:
> rnk wrote:
> > I highly doubt this is correct. I have a feeling there are all kinds of 
> > ways you can get this to fire on things that aren't a function declaration. 
> > It's also inefficient to check the identifier string every time we make a 
> > function type. Please find somewhere else to add this. I'd suggest 
> > adjusting the function type in CheckMain, or some time before then, 
> > whereever we make main implicitly extern "C".
> I believe the logic here was pulled from FunctionDecl's "isMain" function: 
> https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html#aa2b31caf653741632b16cce1ae2061cc
> 
> As this is so early in the process (at Declarator), I didn't see a good place 
> to recommend extracting this, besides pulling it into the Declarator.  
> 
> CheckMain is also run at the Decl stage, isn't it?  Is your suggestion be to 
> simply let this go through with the wrong calling-convention here, then 
> revert it it in "CheckMain"?
Yep. You can look at how we use FunctionTypeUnwrapper and 
ASTContext::adjustFunctionType in various places to fix up function types that 
were built with the wrong calling convention without losing type source info.


https://reviews.llvm.org/D39210



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39210: Add default calling convention support for regcall.

2017-10-23 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: lib/Sema/SemaType.cpp:3269-3273
+  bool IsMain = false;
+  if (D.getIdentifier() && D.getIdentifier()->isStr("main") &&
+  S.CurContext->getRedeclContext()->isTranslationUnit() &&
+  !S.getLangOpts().Freestanding)
+IsMain = true;

rnk wrote:
> I highly doubt this is correct. I have a feeling there are all kinds of ways 
> you can get this to fire on things that aren't a function declaration. It's 
> also inefficient to check the identifier string every time we make a function 
> type. Please find somewhere else to add this. I'd suggest adjusting the 
> function type in CheckMain, or some time before then, whereever we make main 
> implicitly extern "C".
I believe the logic here was pulled from FunctionDecl's "isMain" function: 
https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html#aa2b31caf653741632b16cce1ae2061cc

As this is so early in the process (at Declarator), I didn't see a good place 
to recommend extracting this, besides pulling it into the Declarator.  

CheckMain is also run at the Decl stage, isn't it?  Is your suggestion be to 
simply let this go through with the wrong calling-convention here, then revert 
it it in "CheckMain"?


https://reviews.llvm.org/D39210



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39210: Add default calling convention support for regcall.

2017-10-23 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: lib/Sema/SemaType.cpp:3269-3273
+  bool IsMain = false;
+  if (D.getIdentifier() && D.getIdentifier()->isStr("main") &&
+  S.CurContext->getRedeclContext()->isTranslationUnit() &&
+  !S.getLangOpts().Freestanding)
+IsMain = true;

I highly doubt this is correct. I have a feeling there are all kinds of ways 
you can get this to fire on things that aren't a function declaration. It's 
also inefficient to check the identifier string every time we make a function 
type. Please find somewhere else to add this. I'd suggest adjusting the 
function type in CheckMain, or some time before then, whereever we make main 
implicitly extern "C".


https://reviews.llvm.org/D39210



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39210: Add default calling convention support for regcall.

2017-10-23 Thread Elizabeth Andrews via Phabricator via cfe-commits
eandrews created this revision.

Added support for regcall as default calling convention.  Also added code to 
exclude main when applying default calling conventions.


https://reviews.llvm.org/D39210

Files:
  include/clang/AST/ASTContext.h
  include/clang/Basic/LangOptions.h
  include/clang/Driver/CC1Options.td
  include/clang/Driver/CLCompatOptions.td
  lib/AST/ASTContext.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Sema/SemaType.cpp
  test/CodeGenCXX/default_calling_conv.cpp
  test/Driver/cl-cc-flags.c

Index: test/Driver/cl-cc-flags.c
===
--- test/Driver/cl-cc-flags.c
+++ test/Driver/cl-cc-flags.c
@@ -13,6 +13,9 @@
 // RUN: %clang_cl --target=i686-windows-msvc /Gv -### -- %s 2>&1 | FileCheck --check-prefix=VECTORCALL %s
 // VECTORCALL: -fdefault-calling-conv=vectorcall
 
+// RUN: %clang_cl --target=i686-windows-msvc /Gregcall -### -- %s 2>&1 | FileCheck --check-prefix=REGCALL %s
+// REGCALL: -fdefault-calling-conv=regcall
+
 // Last one should win:
 
 // RUN: %clang_cl --target=i686-windows-msvc /Gd /Gv -### -- %s 2>&1 | FileCheck --check-prefix=LASTWINS_VECTOR %s
Index: test/CodeGenCXX/default_calling_conv.cpp
===
--- test/CodeGenCXX/default_calling_conv.cpp
+++ test/CodeGenCXX/default_calling_conv.cpp
@@ -3,11 +3,13 @@
 // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
 // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
 // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL
 
 // CDECL: define void @_Z5test1v
 // FASTCALL: define x86_fastcallcc void @_Z5test1v
 // STDCALL: define x86_stdcallcc void @_Z5test1v
 // VECTORCALL: define x86_vectorcallcc void @_Z5test1v
+// REGCALL: define x86_regcallcc void @_Z17__regcall3__test1v
 void test1() {}
 
 // ALL: define void @_Z5test2v
@@ -22,6 +24,9 @@
 // ALL: define  x86_vectorcallcc void @_Z5test5v
 void __attribute__((vectorcall)) test5() {}
 
+// ALL: define x86_regcallcc void @_Z17__regcall3__test6v
+void __attribute__((regcall)) test6() {}
+
 // ALL: define linkonce_odr void @_ZN1A11test_memberEv
 class A {
 public:
@@ -32,3 +37,8 @@
   A a;
   a.test_member();
 }
+
+// ALL: define i32 @main
+int main() {
+  return 1;
+}
Index: lib/Sema/SemaType.cpp
===
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -3266,8 +3266,14 @@
 }
   }
 
-  CallingConv CC = S.Context.getDefaultCallingConvention(FTI.isVariadic,
- IsCXXInstanceMethod);
+  bool IsMain = false;
+  if (D.getIdentifier() && D.getIdentifier()->isStr("main") &&
+  S.CurContext->getRedeclContext()->isTranslationUnit() &&
+  !S.getLangOpts().Freestanding)
+IsMain = true;
+
+  CallingConv CC = S.Context.getDefaultCallingConvention(
+  FTI.isVariadic, IsCXXInstanceMethod, IsMain);
 
   // Attribute AT_OpenCLKernel affects the calling convention for SPIR
   // and AMDGPU targets, hence it cannot be treated as a calling
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2299,12 +2299,12 @@
   // Check for MS default calling conventions being specified.
   if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
 LangOptions::DefaultCallingConvention DefaultCC =
-llvm::StringSwitch(
-A->getValue())
+llvm::StringSwitch(A->getValue())
 .Case("cdecl", LangOptions::DCC_CDecl)
 .Case("fastcall", LangOptions::DCC_FastCall)
 .Case("stdcall", LangOptions::DCC_StdCall)
 .Case("vectorcall", LangOptions::DCC_VectorCall)
+.Case("regcall", LangOptions::DCC_RegCall)
 .Default(LangOptions::DCC_None);
 if (DefaultCC == LangOptions::DCC_None)
   Diags.Report(diag::err_drv_invalid_value)
@@ -2315,7 +2315,8 @@
 bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
   DefaultCC == LangOptions::DCC_StdCall) &&
  Arch != llvm::Triple::x86;
-emitError |= DefaultCC == LangOptions::DCC_VectorCall &&
+emitError |= (DefaultCC == LangOptions::DCC_VectorCall ||
+  DefaultCC == LangOptions::DCC_RegCall) &&
  !(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64);
 if (emitError)
   Diags.Report(diag::err_drv_argument_not_allow