Add a target environment for CoreCLR.

Although targeting CoreCLR is similar to targeting MSVC, there are
certain important differences that the backend must be aware of
(e.g. differences in stack probes, EH, and library calls).

Differential Revision: http://reviews.llvm.org/D11012

llvm-svn: 245115
diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h
index e6239bc..3606ae7 100644
--- a/llvm/include/llvm/ADT/Triple.h
+++ b/llvm/include/llvm/ADT/Triple.h
@@ -171,7 +171,8 @@
     Itanium,
     Cygnus,
     AMDOpenCL,
-    LastEnvironmentType = AMDOpenCL
+    CoreCLR,
+    LastEnvironmentType = CoreCLR
   };
   enum ObjectFormatType {
     UnknownObjectFormat,
@@ -438,6 +439,10 @@
     return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC;
   }
 
+  bool isWindowsCoreCLREnvironment() const {
+    return getOS() == Triple::Win32 && getEnvironment() == Triple::CoreCLR;
+  }
+
   bool isWindowsItaniumEnvironment() const {
     return getOS() == Triple::Win32 && getEnvironment() == Triple::Itanium;
   }
diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
index f1b009e..a946e19 100644
--- a/llvm/lib/Support/Triple.cpp
+++ b/llvm/lib/Support/Triple.cpp
@@ -197,6 +197,7 @@
   case Itanium: return "itanium";
   case Cygnus: return "cygnus";
   case AMDOpenCL: return "amdopencl";
+  case CoreCLR: return "coreclr";
   }
 
   llvm_unreachable("Invalid EnvironmentType!");
@@ -432,6 +433,7 @@
     .StartsWith("itanium", Triple::Itanium)
     .StartsWith("cygnus", Triple::Cygnus)
     .StartsWith("amdopencl", Triple::AMDOpenCL)
+    .StartsWith("coreclr", Triple::CoreCLR)
     .Default(Triple::UnknownEnvironment);
 }
 
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index 83b4091..7a453fe 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -122,7 +122,8 @@
   } else if (TheTriple.isOSBinFormatELF()) {
     // Force the use of an ELF container.
     MAI = new X86ELFMCAsmInfo(TheTriple);
-  } else if (TheTriple.isWindowsMSVCEnvironment()) {
+  } else if (TheTriple.isWindowsMSVCEnvironment() ||
+             TheTriple.isWindowsCoreCLREnvironment()) {
     MAI = new X86MCAsmInfoMicrosoft(TheTriple);
   } else if (TheTriple.isOSCygMing() ||
              TheTriple.isWindowsItaniumEnvironment()) {
diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h
index f026d42..14e0088 100644
--- a/llvm/lib/Target/X86/X86Subtarget.h
+++ b/llvm/lib/Target/X86/X86Subtarget.h
@@ -406,6 +406,10 @@
     return TargetTriple.isKnownWindowsMSVCEnvironment();
   }
 
+  bool isTargetWindowsCoreCLR() const {
+    return TargetTriple.isWindowsCoreCLREnvironment();
+  }
+
   bool isTargetWindowsCygwin() const {
     return TargetTriple.isWindowsCygwinEnvironment();
   }
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index fb9cb4b..a9b6b74 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -45,7 +45,7 @@
     return make_unique<X86LinuxNaClTargetObjectFile>();
   if (TT.isOSBinFormatELF())
     return make_unique<X86ELFTargetObjectFile>();
-  if (TT.isKnownWindowsMSVCEnvironment())
+  if (TT.isKnownWindowsMSVCEnvironment() || TT.isWindowsCoreCLREnvironment())
     return make_unique<X86WindowsTargetObjectFile>();
   if (TT.isOSBinFormatCOFF())
     return make_unique<TargetLoweringObjectFileCOFF>();
diff --git a/llvm/test/CodeGen/WinEH/seh-catch-all.ll b/llvm/test/CodeGen/WinEH/seh-catch-all.ll
index 5ac2295..1255496f 100644
--- a/llvm/test/CodeGen/WinEH/seh-catch-all.ll
+++ b/llvm/test/CodeGen/WinEH/seh-catch-all.ll
@@ -1,7 +1,7 @@
-; RUN: opt -S -winehprepare < %s | FileCheck %s
+; RUN: opt -S -winehprepare -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
+; RUN: opt -S -winehprepare -mtriple=x86_64-pc-windows-coreclr < %s | FileCheck %s
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc"
 
 @str.__except = internal unnamed_addr constant [9 x i8] c"__except\00", align 1
 
diff --git a/llvm/test/CodeGen/WinEH/seh-inlined-finally.ll b/llvm/test/CodeGen/WinEH/seh-inlined-finally.ll
index 157adf0..07fe600 100644
--- a/llvm/test/CodeGen/WinEH/seh-inlined-finally.ll
+++ b/llvm/test/CodeGen/WinEH/seh-inlined-finally.ll
@@ -1,10 +1,10 @@
-; RUN: opt -S -winehprepare < %s | FileCheck %s
+; RUN: opt -S -winehprepare -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
+; RUN: opt -S -winehprepare -mtriple=x86_64-pc-windows-coreclr < %s | FileCheck %s
 
 ; Check that things work when the mid-level optimizer inlines the finally
 ; block.
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc"
 
 %struct._RTL_CRITICAL_SECTION = type { %struct._RTL_CRITICAL_SECTION_DEBUG*, i32, i32, i8*, i8*, i64 }
 %struct._RTL_CRITICAL_SECTION_DEBUG = type { i16, i16, %struct._RTL_CRITICAL_SECTION*, %struct._LIST_ENTRY, i32, i32, i32, i16, i16 }
diff --git a/llvm/test/CodeGen/WinEH/seh-outlined-finally.ll b/llvm/test/CodeGen/WinEH/seh-outlined-finally.ll
index 529f85b..b46b4e9 100644
--- a/llvm/test/CodeGen/WinEH/seh-outlined-finally.ll
+++ b/llvm/test/CodeGen/WinEH/seh-outlined-finally.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -S -winehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
+; RUN: opt -S -winehprepare -mtriple=x86_64-windows-coreclr < %s | FileCheck %s
 
 ; Test case based on this code:
 ;
@@ -26,7 +27,6 @@
 ; is nothing like a std::terminate call in this situation.
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc"
 
 @str_outer_finally = linkonce_odr unnamed_addr constant [18 x i8] c"outer finally %d\0A\00", align 1
 @str_inner_finally = linkonce_odr unnamed_addr constant [18 x i8] c"inner finally %d\0A\00", align 1
diff --git a/llvm/test/CodeGen/WinEH/seh-prepared-basic.ll b/llvm/test/CodeGen/WinEH/seh-prepared-basic.ll
index b6a3030..d4ff04c 100644
--- a/llvm/test/CodeGen/WinEH/seh-prepared-basic.ll
+++ b/llvm/test/CodeGen/WinEH/seh-prepared-basic.ll
@@ -1,4 +1,5 @@
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-pc-windows-coreclr < %s | FileCheck %s
 
 ; Test case based on this code:
 ; extern "C" unsigned long _exception_code();
@@ -12,7 +13,6 @@
 ; }
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc"
 
 ; Function Attrs: uwtable
 define void @do_except() #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
diff --git a/llvm/test/CodeGen/WinEH/seh-resume-phi.ll b/llvm/test/CodeGen/WinEH/seh-resume-phi.ll
index d2bd641..4ce5519 100644
--- a/llvm/test/CodeGen/WinEH/seh-resume-phi.ll
+++ b/llvm/test/CodeGen/WinEH/seh-resume-phi.ll
@@ -1,7 +1,7 @@
-; RUN: opt -S -winehprepare < %s | FileCheck %s
+; RUN: opt -S -winehprepare -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
+; RUN: opt -S -winehprepare -mtriple=x86_64-pc-windows-coreclr < %s | FileCheck %s
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc"
 
 declare void @might_crash(i8* %ehptr)
 declare i32 @filt()
diff --git a/llvm/test/CodeGen/WinEH/seh-simple.ll b/llvm/test/CodeGen/WinEH/seh-simple.ll
index 0601864..9974548 100644
--- a/llvm/test/CodeGen/WinEH/seh-simple.ll
+++ b/llvm/test/CodeGen/WinEH/seh-simple.ll
@@ -1,5 +1,7 @@
 ; RUN: opt -S -winehprepare -mtriple=x86_64-windows-msvc < %s \
 ; RUN: 		| FileCheck %s --check-prefix=CHECK --check-prefix=X64
+; RUN: opt -S -winehprepare -mtriple=x86_64-windows-coreclr < %s \
+; RUN: 		| FileCheck %s --check-prefix=CHECK --check-prefix=X64
 
 ; This test should also pass in 32-bit using _except_handler3.
 ; RUN: sed -e 's/__C_specific_handler/_except_handler3/' %s \
diff --git a/llvm/test/CodeGen/X86/stack-probe-size.ll b/llvm/test/CodeGen/X86/stack-probe-size.ll
index 21482c3..43c62c1 100644
--- a/llvm/test/CodeGen/X86/stack-probe-size.ll
+++ b/llvm/test/CodeGen/X86/stack-probe-size.ll
@@ -6,10 +6,10 @@
 ; stack probe size equals the page size (4096 bytes for all x86 targets), and
 ; this is unlikely to change in the future.
 ;
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck %s
+; RUN: llc -mtriple=i686-windows-coreclr < %s | FileCheck %s
 
 target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
-target triple = "i686-pc-windows-msvc"
 
 define i32 @test1() "stack-probe-size"="0" {
   %buffer = alloca [4095 x i8]