Skip to content

Commit

Permalink
[2019-08] [arm/arm64] fix fconv/rconv issues with LLVM (#16532)
Browse files Browse the repository at this point in the history
* [ci] add make -C mono/mini llvmaotcheck to FullAOT LLVM lanes

* [arm64] use opcode emulation for fconv/rconv

LLVM eagerly optimizes constants such as NaN in a way that does not align with .NET behaviour. In the future we can change it so that we only do opcode emulation when LLVM is used.

Fixes #16411

* [arm] account only 4 bytes on stack for single precision arguments

Fixes `test_0_arm64_small_stack_args` in gshared.cs when
* `test_0_arm64_small_stack_args` is compiled with LLVM
* `Foo3.Floats` is compiled with Mini

* [arm] use opcode emulation for fconv/rconv

* [llvmaotcheck] require sse3 being available for regression tests

* [amd64] use opcode emulation for fconv/rconv

* fix cast and signature for mono_rconv_u4
  • Loading branch information
monojenkins authored and akoeplinger committed Aug 28, 2019
1 parent 75f2ac1 commit 076bab4
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 9 deletions.
7 changes: 6 additions & 1 deletion mono/mini/Makefile.am.in
Original file line number Diff line number Diff line change
Expand Up @@ -881,11 +881,16 @@ gctest: mono gc-test.exe
MONO_DEBUG_OPTIONS=clear-nursery-at-gc $(MINI_RUNTIME) --regression gc-test.exe

LLVM_AOT_RUNTIME_OPTS=$(if $(LLVM),--llvm,)
if AMD64
LLVM_AOT_COMPILER_OPTS=$(if $(LLVM),"=llvmllc=-mcpu=generic -mattr=+sse3",)
else
LLVM_AOT_COMPILER_OPTS=
endif
GSHAREDVT_RUNTIME_OPTS=$(if $(GSHAREDVT),-O=gsharedvt,)

aotcheck: mono $(regtests)
rm -rf *.exe.so *.exe.dylib *.exe.dylib.dSYM
$(MINI_RUNTIME) $(LLVM_AOT_RUNTIME_OPTS) --aot $(regtests) || exit 1
$(MINI_RUNTIME) $(LLVM_AOT_RUNTIME_OPTS) --aot$(LLVM_AOT_COMPILER_OPTS) $(regtests) || exit 1
for i in $(regtests); do $(RUNTIME_AOTCHECK) --regression $$i || exit 1; done
rm -rf *.exe.so *.exe.dylib *.exe.dylib.dSYM

Expand Down
4 changes: 2 additions & 2 deletions mono/mini/jit-icalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -925,12 +925,12 @@ mono_fconv_u4_2 (double v)
return mono_fconv_u4 (v);
}

gint32
guint32
mono_rconv_u4 (float v)
{
if (mono_isinf (v) || mono_isnan (v))
return 0;
return (gint32)v;
return (guint32) v;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion mono/mini/jit-icalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ G_EXTERN_C gint64 mono_fconv_i8 (double v);
G_EXTERN_C guint32 mono_fconv_u4 (double v);
G_EXTERN_C guint32 mono_fconv_u4_2 (double v);

G_EXTERN_C gint32 mono_rconv_u4 (float v);
G_EXTERN_C guint32 mono_rconv_u4 (float v);

G_EXTERN_C gint64 mono_fconv_ovf_i8 (double v);

Expand Down
4 changes: 1 addition & 3 deletions mono/mini/mini-amd64.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,8 @@ typedef struct {

#define MONO_ARCH_EMULATE_CONV_R8_UN 1
#define MONO_ARCH_EMULATE_FCONV_TO_U8 1
// The Windows x64 FullAOT+LLVM fails to pass the basic-float tests without this.
#ifdef TARGET_WIN32
// x64 FullAOT+LLVM fails to pass the basic-float tests without this.
#define MONO_ARCH_EMULATE_FCONV_TO_U4 1
#endif
#define MONO_ARCH_EMULATE_FREM 1
#define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
#define MONO_ARCH_HAVE_INVALIDATE_METHOD 1
Expand Down
2 changes: 1 addition & 1 deletion mono/mini/mini-arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,7 @@ add_float (guint *fpr, guint *stack_size, ArgInfo *ainfo, gboolean is_double, gi
ainfo->reg = ARMREG_SP;
ainfo->storage = RegTypeBase;

*stack_size += 8;
*stack_size += is_double ? 8 : 4;
}
}

Expand Down
1 change: 1 addition & 0 deletions mono/mini/mini-arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ typedef struct MonoCompileArch {
int thunks_size;
} MonoCompileArch;

#define MONO_ARCH_EMULATE_FCONV_TO_U4 1
#define MONO_ARCH_EMULATE_FCONV_TO_I8 1
#define MONO_ARCH_EMULATE_FCONV_TO_U8 1
#define MONO_ARCH_EMULATE_LCONV_TO_R8 1
Expand Down
3 changes: 2 additions & 1 deletion mono/mini/mini-arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,14 @@ typedef struct {
int thunks_size;
} MonoCompileArch;

#define MONO_ARCH_EMULATE_FCONV_TO_U4 1
#define MONO_ARCH_EMULATE_FCONV_TO_U8 1
#ifdef MONO_ARCH_ILP32
/* For the watch (starting with series 4), a new ABI is introduced: arm64_32.
* We can still use the older AOT compiler to produce bitcode, because it's
* "offset compatible". However, since it is targeting arm7k, it makes certain
* assumptions that we need to align here. */
#define MONO_ARCH_EMULATE_FCONV_TO_I8 1
#define MONO_ARCH_EMULATE_FCONV_TO_U8 1
#define MONO_ARCH_EMULATE_LCONV_TO_R8 1
#define MONO_ARCH_EMULATE_LCONV_TO_R4 1
#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
Expand Down
5 changes: 5 additions & 0 deletions scripts/ci/run-test-testing_aot_full.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ then
${TESTCMD} --label=mini --timeout=25m make -j ${CI_CPU_COUNT} -w -C mono/mini -k llvmonlycheck
else
${TESTCMD} --label=mini --timeout=25m make -j ${CI_CPU_COUNT} -w -C mono/mini -k fullaotcheck
if [[ ${CI_TAGS} == *'_llvm'* ]]; then
${TESTCMD} --label=mini-aotcheck --timeout=25m make -j ${CI_CPU_COUNT} -w -C mono/mini -k llvmaotcheck
# FIXME: https://github.com/mono/mono/issues/15999
# ${TESTCMD} --label=mini-aotcheck --timeout=25m make -j ${CI_CPU_COUNT} -w -C mono/mini -k llvmfullaotcheck
fi
fi

${TESTCMD} --label=runtime --timeout=160m make -w -C mono/tests -k test-wrench V=1
Expand Down

0 comments on commit 076bab4

Please sign in to comment.