Run CoreCLR runtime tests using Mono with LLVM AOT. (#38547)
authorimhameed <imhameed@microsoft.com>
Tue, 14 Jul 2020 04:05:44 +0000 (21:05 -0700)
committerGitHub <noreply@github.com>
Tue, 14 Jul 2020 04:05:44 +0000 (21:05 -0700)
- coreclr/build-test.sh now has a new subcommand: 'mono_aot', which builds a
new target, named 'MonoAotCompileTests', added to
coreclr/tests/src/runtest.proj. This target compiles the runtime tests using
Mono LLVM AOT in a simple configuration where the host platform is identical to
the target platform. Parallel compilation happens via a hack: actual
compilation happens in mono/msbuild/aot-compile.proj, a single-target msbuild
file, and runtest.proj invokes this single-purpose project and target using
batching to create multiple parallelizable instances of this project. Future
work: use the MonoAOTCompiler custom task currently used to build the iOS
sample program.

- Avoid using the runtimeVariant string when defining
coreClrProductArtifactName in mono/templates/xplat-pipeline-job.yml. There are
no "runtime variants" of CoreCLR configured with this parameter; instead,
depend on a shared non-runtime-variant build of CoreCLR.

- Mark function DISubprograms as local definitions--this is an LLVM 9
compatibility fix.

- Use --tag=CXX when linking libmonosgen-2.0.so via libtool when LLVM is linked
into Mono.

  This makes libtool use the C++ compiler driver when linking Mono--which uses
whatever platform-specific flags are necessary to link against the C++ stdlib.
Previously, libtool would use the C compiler driver, which didn't do this and
would produce shared objects with no explicit dependency on libstdc++.

  This problem is normally masked because of the very lax dynamic linking
semantics on ELF, but Mono on our CI setup is built in a CentOS 7 image (which
does not contain a C++11 libstdc++) that has a GCC 7 compatibility package
installed, along with a clang 9 installation that detects headers from the GCC
7 compatibility package. This compatibility package includes a libstdc++ linker
script that links C++11 libstdc++ components statically into the target while
dynamically linking against components present in pre-C++11 libstdc++. The end
result of all of this is that Mono built with this configuration will
dynamically depend on C++11 libstdc++ symbols that should have been statically
linked into the library, and will outright fail to run on machines without a
newer version of libstdc++ available.

- Add tests that fail after LLVM AOT compilation to issues.targets.

eng/pipelines/common/templates/runtimes/run-test-job.yml
eng/pipelines/mono/templates/xplat-pipeline-job.yml
eng/pipelines/runtime.yml
src/coreclr/build-test.sh
src/coreclr/tests/issues.targets
src/coreclr/tests/src/runtest.proj
src/mono/configure.ac
src/mono/mono/mini/Makefile.am.in
src/mono/mono/mini/mini-llvm-cpp.cpp
src/mono/msbuild/aot-compile.proj [new file with mode: 0644]

index 4a89ea975bdbf955e76b4c147ba5daceab2e5191..39616a833b0e4c743b2228feffb6a5148bd83237 100644 (file)
@@ -268,6 +268,10 @@ jobs:
                 /p:TargetArchitecture=$(archType)
         displayName: "Patch dotnet with mono"
 
+    - ${{ if and(eq(parameters.runtimeFlavor, 'mono'), eq(parameters.runtimeVariant, 'llvmaot')) }}:
+      - script: $(coreClrRepoRootDir)build-test$(scriptExt) mono_aot $(buildConfig)
+        displayName: "LLVM AOT compile CoreCLR tests"
+
     # Send tests to Helix
     - template: /eng/pipelines/common/templates/runtimes/send-to-helix-step.yml
       parameters:
index 364616643e86f8abcd28666e606696c0ecd91240..89917a58e0b8a3ccb93cafd0ee312546fcc897a8 100644 (file)
@@ -48,7 +48,7 @@ jobs:
 
     variables:
     - name: coreClrProductArtifactName
-      value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_${{ parameters.liveRuntimeBuildConfig }}'
+      value: 'CoreCLRProduct__$(osGroup)$(osSubgroup)_$(archType)_${{ parameters.liveRuntimeBuildConfig }}'
 
     - name: coreClrProductRootFolderPath
       value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(liveRuntimeBuildConfigUpper)'
index 32d7dc0e686fdacf6d41875900c4eff3bf1ca1e0..10f5a74afc33fc7d5defa0443d0a41bf01c358b7 100644 (file)
@@ -159,7 +159,7 @@ jobs:
 #
 # Build CoreCLR checked using GCC toolchain
 # Only when CoreCLR is changed
-# 
+#
 - template: /eng/pipelines/common/platform-matrix.yml
   parameters:
     jobTemplate: /eng/pipelines/coreclr/templates/build-job.yml
@@ -250,7 +250,7 @@ jobs:
         or(
           eq(dependencies.checkout.outputs['SetPathVars_coreclr.containsChange'], true),
           eq(variables['isFullMatrix'], true))
-  
+
 # Build the whole product using Mono runtime
 # Only when libraries, mono or installer are changed
 #
@@ -479,6 +479,25 @@ jobs:
           eq(dependencies.checkout.outputs['SetPathVars_mono.containsChange'], true),
           eq(variables['isFullMatrix'], true))
 
+#
+# Build Mono release with LLVM AOT
+# Only when mono, or the runtime tests changed
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+  parameters:
+    jobTemplate: /eng/pipelines/mono/templates/build-job.yml
+    runtimeFlavor: mono
+    buildConfig: release
+    platforms:
+    - Linux_x64
+    jobParameters:
+      runtimeVariant: llvmaot
+      condition: >-
+        or(
+          eq(dependencies.checkout.outputs['SetPathVars_runtimetests.containsChange'], true),
+          eq(dependencies.checkout.outputs['SetPathVars_mono.containsChange'], true),
+          eq(variables['isFullMatrix'], true))
+
 #
 # Build libraries using live CoreLib
 # These set of libraries are built always no matter what changed
@@ -613,7 +632,7 @@ jobs:
       isOfficialBuild: false
       liveRuntimeBuildConfig: release
       testScope: innerloop
-      condition: >- 
+      condition: >-
         or(
           eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true),
           eq(dependencies.checkout.outputs['SetPathVars_coreclr.containsChange'], true),
@@ -745,6 +764,29 @@ jobs:
           eq(dependencies.checkout.outputs['SetPathVars_mono.containsChange'], true),
           eq(dependencies.checkout.outputs['SetPathVars_runtimetests.containsChange'], true),
           eq(variables['isFullMatrix'], true))
+#
+# Mono CoreCLR runtime Test executions using live libraries and LLVM AOT
+# Only when Mono is changed
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+  parameters:
+    jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
+    buildConfig: release
+    runtimeFlavor: mono
+    platforms:
+    - Linux_x64
+    helixQueueGroup: pr
+    helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+    jobParameters:
+      testGroup: innerloop
+      liveLibrariesBuildConfig: ${{ variables.debugOnPrReleaseOnRolling }}
+      liveRuntimeBuildConfig: release
+      runtimeVariant: llvmaot
+      condition: >-
+        or(
+          eq(dependencies.checkout.outputs['SetPathVars_mono.containsChange'], true),
+          eq(dependencies.checkout.outputs['SetPathVars_runtimetests.containsChange'], true),
+          eq(variables['isFullMatrix'], true))
 
 #
 # Libraries Release Test Execution against a release mono runtime.
index 2de59c68c06ca2830120ff710f43e16cc4f6a594..f1a26c565e3b025c3deeae729609ade211df63b0 100755 (executable)
@@ -47,6 +47,18 @@ build_test_wrappers()
     fi
 }
 
+build_mono_aot()
+{
+    __RuntimeFlavor="mono"
+    __MonoBinDir="$__RootBinDir/bin/mono/$__TargetOS.$__BuildArch.$__BuildType"
+    __Exclude="${__ProjectDir}/tests/issues.targets"
+    __TestBinDir="$__TestWorkingDir"
+    CORE_ROOT="$__TestBinDir"/Tests/Core_Root
+    export __Exclude
+    export CORE_ROOT
+    build_MSBuild_projects "Tests_MonoAot" "$__ProjectDir/tests/src/runtest.proj" "Mono AOT compile tests" "/t:MonoAotCompileTests" "/p:RuntimeFlavor=$__RuntimeFlavor" "/p:MonoLlvmPath=$__MonoBinDir"
+}
+
 generate_layout()
 {
     echo "${__MsgPrefix}Creating test overlay..."
@@ -608,6 +620,12 @@ handle_arguments_local() {
         excludemonofailures|-excludemonofailures)
             __Mono=1
             ;;
+
+        mono_aot|-mono_aot)
+            __Mono=1
+            __MonoAot=1
+            ;;
+
         *)
             __UnprocessedBuildArgs+=("$1")
             ;;
@@ -661,6 +679,8 @@ __UseNinja=0
 __VerboseBuild=0
 __CMakeArgs=""
 __priority1=
+__Mono=0
+__MonoAot=0
 CORE_ROOT=
 
 source "$__ProjectRoot"/_build-commons.sh
@@ -703,10 +723,12 @@ if [[ -z "$HOME" ]]; then
     echo "HOME not defined; setting it to $HOME"
 fi
 
-if [[ (-z "$__GenerateLayoutOnly") && (-z "$__BuildTestWrappersOnly") ]]; then
+if [[ (-z "$__GenerateLayoutOnly") && (-z "$__BuildTestWrappersOnly") && ("$__MonoAot" -eq 0) ]]; then
     build_Tests
 elif [[ ! -z "$__BuildTestWrappersOnly" ]]; then
     build_test_wrappers
+elif [[ "$__MonoAot" -eq 1 ]]; then
+    build_mono_aot
 else
     generate_layout
 fi
index e42c969e4a1d445d58fa9afd1c264ba7db26a09e..eb1f6be60e89f4a60693f30b79d1ce34bfd6d8f6 100644 (file)
 
     <!-- Known failures for mono runtime on *all* architectures/operating systems -->
     <ItemGroup Condition="'$(RuntimeFlavor)' == 'mono'" >
+        <ExcludeList Include="$(XunitTestBinBase)/Interop/StringMarshalling/AnsiBSTR/AnsiBStrTest/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Interop/StringMarshalling/BSTR/BSTRTest/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/Regression/GitHub_17073/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/Sse3/LoadDquVector128_r/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/Sse3/LoadDquVector128_ro/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/General/VectorArray_r/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/General/VectorArray_ro/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/General/VectorRet_r/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/General/VectorRet_ro/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/General/VectorUnused_r/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/General/VectorUnused_ro/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/General/Vector128/Vector128_ro/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/General/Vector128/Vector128_r/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/MethodImpl/CovariantReturns/Structs/IncompatibleOverride/**">
+            <Issue>Crashes during LLVM AOT compilation.</Issue>
+        </ExcludeList>
+
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/opt/InstructionCombining/DivToMul/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/SIMD/VectorConvert_ro_Target_64Bit/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/SIMD/VectorConvert_r_Target_64Bit/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/StructABI/StructABI/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/GitHub_15949/GitHub_15949/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/GitHub_15291/GitHub_15291/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/CLR-x86-JIT/V1-M09.5-PDC/b16928/b16928/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/opt/osr/osr015/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/opt/rngchk/ArrayBound_o/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/AssemblyLoadContext30Extensions/AssemblyLoadContext30Extensions/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/MethodImpl/CovariantReturns/UnitTest/CompatibleWithTest/**">
+            <Issue>Doesn't pass after LLVM AOT compilation.</Issue>
+        </ExcludeList>
+
         <ExcludeList Include="$(XunitTestBinBase)/GC/Features/Finalizer/finalizeother/finalizeexcep/**">
             <Issue>PlatformDetection.IsPreciseGcSupported false on mono</Issue>
         </ExcludeList>
index adc7433ebd98735d45b3591de37133f2f569decb..f4d3e4b88571543bbe727bfebf223380bc74f2ad 100644 (file)
@@ -348,6 +348,37 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\","").
     </ItemGroup>
   </Target>
 
+  <Target Name="MonoAotCompileTests" DependsOnTargets="GetListOfTestCmds;FindCmdDirectories">
+    <ItemGroup>
+      <AllTestScripts Include="%(TestDirectories.Identity)\**\*.sh" />
+      <TestExclusions Include="@(ExcludeList->Metadata('FullPath'))" Condition="$(HaveExcludes)" />
+      <TestScripts Include="@(AllTestScripts)" Exclude="@(TestExclusions)" />
+      <TestDllPaths Include="$([System.IO.Path]::ChangeExtension('%(TestScripts.Identity)', 'dll'))" />
+      <TestDlls Include="%(TestDllPaths.Identity)" Condition="Exists(%(TestDllPaths.Identity))" />
+    </ItemGroup>
+    <PropertyGroup>
+      <CorerunExecutable Condition="'$(RunningOnUnix)' == 'true'">$(CORE_ROOT)\corerun</CorerunExecutable>
+      <CorerunExecutable Condition="'$(RunningOnUnix)' != 'true'">$(CORE_ROOT)\corerun.exe</CorerunExecutable>
+    </PropertyGroup>
+    <ItemGroup>
+      <AotEnvVar Include="MONO_ENV_OPTIONS=--aot=llvm,llvm-path='$(MonoLlvmPath)'" />
+    </ItemGroup>
+    <PropertyGroup>
+      <AotEnvVars>@(AotEnvVar)</AotEnvVars>
+    </PropertyGroup>
+    <ItemGroup>
+      <AotProject Include="../../../mono/msbuild/aot-compile.proj">
+        <Properties>_CorerunExecutable=$(CorerunExecutable);_TestDll=%(TestDlls.Identity);AotEnvVars=@(AotEnvVar)</Properties>
+      </AotProject>
+    </ItemGroup>
+    <MSBuild
+      Projects="@(AotProject)"
+      Targets="AotCompile"
+      Condition="@(TestDlls->Count()) &gt; 0"
+      BuildInParallel="true"
+      />
+  </Target>
+
   <Target Name="CreateAllWrappers" DependsOnTargets="GetListOfTestCmds;FindCmdDirectories">
     <MSBuild Projects="$(MSBuildProjectFile)" Targets="CreateXunitWrapper;BuildXunitWrapper" Properties="_CMDDIR=%(TestDirectories.Identity);TestSrcDir=$(XunitTestBinBase)" />
   </Target>
@@ -374,6 +405,11 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\","").
     <MSBuild Projects="$(MSBuildThisFileDirectory)Common\test_dependencies\test_dependencies.csproj"
              Condition=" '$(BuildWrappers)'=='true' " />
 
+    <MSBuild Projects="$(MSBuildProjectFile)"
+             Targets="MonoAotCompileTests"
+             Properties=""
+             Condition=" '$(MonoAotCompile)'=='true' " />
+
     <!-- Default for building -->
     <MSBuild Projects="$(MSBuildProjectFile)"
              Targets="CreateAllWrappers"
index 38f76cca856496aa55d32b4186563ee54d2d50ed..9e3b75b2ba26cf7cdc719dc3964838a97e284160 100644 (file)
@@ -6768,8 +6768,10 @@ AC_SUBST(MONO_NATIVE_PLATFORM_TYPE_UNIFIED)
 #
 if test "x$enable_llvm_runtime" = "xyes"; then
        AC_SUBST(MONO_CXXLD, [$CXX])
+       AC_SUBST(MONO_LIBTOOL_TAG, '--tag=CXX')
 else
        AC_SUBST(MONO_CXXLD, [$CC])
+       AC_SUBST(MONO_LIBTOOL_TAG, '')
 fi
 
 ### Set -Werror options
index 867b13b3754c9b32c34858332f34753b2cbb41d7..38e1c4e69519b8e917e3b91a31c66035589dc974 100755 (executable)
@@ -768,6 +768,7 @@ libmonosgen_2_0_la_CFLAGS = $(mono_sgen_CFLAGS) @CXX_ADD_CFLAGS@
 
 libmonosgen_2_0_la_LIBADD = libmini.la $(interp_libs_with_mini) $(dbg_libs_with_mini) $(sgen_libs) $(LIBMONO_DTRACE_OBJECT) $(LLVMMONOF)
 libmonosgen_2_0_la_LDFLAGS = $(libmonoldflags) $(monobin_platform_ldflags) $(CCLDFLAGS)
+libmonosgen_2_0_la_LIBTOOLFLAGS = $(MONO_LIBTOOL_TAG)
 
 noinst_LIBRARIES += libmaintest.a
 
index e9ef8782222943137f9167b1bf967bab880d63a1..dd9138ef6c2888c8eebcb36524035e1d54ac3b12 100644 (file)
@@ -520,7 +520,9 @@ mono_llvm_di_create_function (void *di_builder, void *cu, LLVMValueRef func, con
        di_file = builder->createFile (file, dir);
        type = builder->createSubroutineType (builder->getOrCreateTypeArray (ArrayRef<Metadata*> ()));
 #if LLVM_API_VERSION >= 900
-       di_func = builder->createFunction (di_file, name, mangled_name, di_file, line, type, 0);
+       di_func = builder->createFunction (
+               di_file, name, mangled_name, di_file, line, type, 0,
+               DINode::FlagZero, DISubprogram::SPFlagDefinition | DISubprogram::SPFlagLocalToUnit);
 #else
        di_func = builder->createFunction (di_file, name, mangled_name, di_file, line, type, true, true, 0);
 #endif
diff --git a/src/mono/msbuild/aot-compile.proj b/src/mono/msbuild/aot-compile.proj
new file mode 100644 (file)
index 0000000..2bceabf
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+    <Target Name="AotCompile">
+        <Exec Command="$(_CorerunExecutable) $(_TestDll)" EnvironmentVariables="$(AotEnvVars)" />
+    </Target>
+</Project>