From a5033ce20784859f2dcf3502ad020088443cbbd5 Mon Sep 17 00:00:00 2001 From: lateralusX Date: Mon, 4 Jan 2021 16:24:17 +0100 Subject: [PATCH] Fix Mono Windows x64 crash blocking CI Windows x64 Release job. After upgrade to later msvc version on CI boots, see https://github.com/dotnet/runtime/issues/45524 for details, Window x64 Release builds started to crash on libraries tests. After investigation it turns out that new msvc compiler handles an expression different compared to how it was handled in previous version. After upgrade of msvc, the expression: int _amd64_width_temp = ((guint64)(imm) == (guint64)(int)(guint64)(imm)); implemented in amd64_mov_reg_imm and then called from tramp-amd64.c@500 was transformed into an always true expression by compiler: amd64_mov_reg_imm (code, AMD64_R11, (guint8*)mono_get_rethrow_preserve_exception_addr ()); lea rcx,[rethrow_preserve_exception_func (07FFB9E33A590h)] mov word ptr [rbx+0Dh],0BB41h mov byte ptr [rbx+0Fh],cl mov rax,rcx shr eax,8 mov byte ptr [rbx+10h],al mov rax,rcx shr eax,10h shr ecx,18h mov byte ptr [rbx+11h],al lea rax,[rbx+13h] mov byte ptr [rbx+12h],cl as seen above, the condition and handling of a 64-bit imm has been dropped by compiler. This cause issues when the imm is a 64-bit value since it will always gets truncated into 32-bit imm and in this case it was a pointer to a function within coreclr.dll (mono_get_rethrow_preserve_exception_addr) loaded located at higher address (using more than 32-bit). This is most likely a regression issue in compiler for this specific construction. I tried simpler construction (using same type conversion) on both old and new compiler version and then it makes the right optimization. Fix is to switch to a macro already available in amd64-codegen (amd64_is_imm32) detecting if an imm needs a 32-bit or 64-bit sized value. This will be correctly optimized by new msvc compiler and even if this is a work around for a what seems to be a optimization bug in the compiler, it is still cleaner and better describes the intent than current code. Fix also re-enable Windows x64 Release CI test lane. --- eng/pipelines/runtime.yml | 2 +- src/mono/mono/arch/amd64/amd64-codegen.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 6712fa33bd5ae..91f052fbf3459 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -806,7 +806,7 @@ jobs: runtimeFlavor: mono buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} platforms: - # - windows_x64 + - windows_x64 - OSX_x64 - Linux_arm64 - Linux_x64 diff --git a/src/mono/mono/arch/amd64/amd64-codegen.h b/src/mono/mono/arch/amd64/amd64-codegen.h index 952b88da6a9f0..f0ae81aa23d0f 100644 --- a/src/mono/mono/arch/amd64/amd64-codegen.h +++ b/src/mono/mono/arch/amd64/amd64-codegen.h @@ -417,9 +417,8 @@ typedef union { #define amd64_mov_reg_imm(inst,reg,imm) \ do { \ - int _amd64_width_temp = ((guint64)(imm) == (guint64)(int)(guint64)(imm)); \ amd64_codegen_pre(inst); \ - amd64_mov_reg_imm_size ((inst), (reg), (imm), (_amd64_width_temp ? 4 : 8)); \ + amd64_mov_reg_imm_size ((inst), (reg), (imm), (amd64_is_imm32 (((gint64)imm)) ? 4 : 8)); \ amd64_codegen_post(inst); \ } while (0)