Skip to content

Commit

Permalink
[mono][llvm] Improve LLVM 9 compatibility. (#34182)
Browse files Browse the repository at this point in the history
Improve LLVM 9 compatibility.

Several intrinsics were removed in LLVM 7 and above; replace them with
IR sequences that generate the desired instructions.

Fix some type mismatch problems with the generated IR (in
Sse2.StoreAlignedNonTemporal, Vector128.CreateScalarUnsafe, and
Sse2.MaskMove); these were caught by running the coreclr hardware
intrinsic JIT tests.

Support the two-argument forms of Sse.SqrtScalar, Sse.ReciprocalScalar,
and Sse.ReciprocalSqrtScalar.

llvm::linkCoreCLRGC(), in llvm/CodeGen/GCs.h, was removed and replaced with
llvm::linkAllBuiltinGCs(), in llvm/CodeGen/BuiltinGCs.h.

In mono_llvm_dump_value and mono_llvm_dump_module, flush the c library's
stdout stream before using (and flushing) LLVM's own buffered output
functions.
  • Loading branch information
imhameed authored Mar 30, 2020
1 parent c3f7da2 commit 335ffb0
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 161 deletions.
39 changes: 22 additions & 17 deletions src/mono/mono/mini/llvm-intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,25 @@ INTRINS(SSE_PSRL_Q, x86_sse2_psrl_q)
INTRINS(SSE_PSLL_W, x86_sse2_psll_w)
INTRINS(SSE_PSLL_D, x86_sse2_psll_d)
INTRINS(SSE_PSLL_Q, x86_sse2_psll_q)
#if LLVM_API_VERSION < 700
// These intrinsics were removed in LLVM 7 (bcaab53d479e7005ee69e06321bbb493f9b7f5e6).
INTRINS(SSE_SQRT_PS, x86_sse_sqrt_ps)
INTRINS(SSE_SQRT_SS, x86_sse_sqrt_ss)
INTRINS(SSE_SQRT_PD, x86_sse2_sqrt_pd)
INTRINS(SSE_SQRT_SD, x86_sse2_sqrt_sd)
INTRINS(SSE_PMULUDQ, x86_sse2_pmulu_dq)
#else
INTRINS_OVR(SSE_SQRT_PD, sqrt)
INTRINS_OVR(SSE_SQRT_PS, sqrt)
INTRINS_OVR(SSE_SQRT_SD, sqrt)
INTRINS_OVR(SSE_SQRT_SS, sqrt)
#endif
INTRINS(SSE_RCP_PS, x86_sse_rcp_ps)
INTRINS(SSE_RSQRT_PS, x86_sse_rsqrt_ps)
INTRINS(SSE_SQRT_SS, x86_sse_sqrt_ss)
INTRINS(SSE_RCP_SS, x86_sse_rcp_ss)
INTRINS(SSE_RSQRT_SS, x86_sse_rsqrt_ss)
INTRINS(SSE_SQRT_PD, x86_sse2_sqrt_pd)
INTRINS(SSE_SQRT_SD, x86_sse2_sqrt_sd)
INTRINS(SSE_CVTTPD2DQ, x86_sse2_cvttpd2dq)
INTRINS(SSE_CVTTPS2DQ, x86_sse2_cvttps2dq)
INTRINS(SSE_CVTDQ2PS, x86_sse2_cvtdq2ps)
INTRINS(SSE_CVTPD2DQ, x86_sse2_cvtpd2dq)
INTRINS(SSE_CVTPS2DQ, x86_sse2_cvtps2dq)
INTRINS(SSE_CVTPD2PS, x86_sse2_cvtpd2ps)
Expand All @@ -110,10 +118,6 @@ INTRINS(SSE_CVTSD2SI, x86_sse2_cvtsd2si)
INTRINS(SSE_CVTTSD2SI, x86_sse2_cvttsd2si)
INTRINS(SSE_CVTSD2SI64, x86_sse2_cvtsd2si64)
INTRINS(SSE_CVTTSD2SI64, x86_sse2_cvttsd2si64)
INTRINS(SSE_CVTSI2SS, x86_sse_cvtsi2ss)
INTRINS(SSE_CVTSI2SS64, x86_sse_cvtsi642ss)
INTRINS(SSE_CVTSI2SD, x86_sse2_cvtsi2sd)
INTRINS(SSE_CVTSI2SD64, x86_sse2_cvtsi642sd)
INTRINS(SSE_CVTSD2SS, x86_sse2_cvtsd2ss)
INTRINS(SSE_CMPPD, x86_sse2_cmp_pd)
INTRINS(SSE_CMPPS, x86_sse_cmp_ps)
Expand Down Expand Up @@ -161,19 +165,10 @@ INTRINS(SSE_MINSD, x86_sse2_min_sd)
INTRINS(SSE_HADDPD, x86_sse3_hadd_pd)
INTRINS(SSE_HSUBPD, x86_sse3_hsub_pd)
INTRINS(SSE_ADDSUBPD, x86_sse3_addsub_pd)
INTRINS(SSE_PADDSW, x86_sse2_padds_w)
INTRINS(SSE_PSUBSW, x86_sse2_psubs_w)
INTRINS(SSE_PADDUSW, x86_sse2_paddus_w)
INTRINS(SSE_PSUBUSW, x86_sse2_psubus_w)
INTRINS(SSE_PMULHW, x86_sse2_pmulh_w)
INTRINS(SSE_PMULHU, x86_sse2_pmulhu_w)
INTRINS(SSE_PMULUDQ, x86_sse2_pmulu_dq)
INTRINS(SSE_PMULHUW, x86_sse2_pmulhu_w)
INTRINS(SSE_PMADDWD, x86_sse2_pmadd_wd)
INTRINS(SSE_PADDSB, x86_sse2_padds_b)
INTRINS(SSE_PSUBSB, x86_sse2_psubs_b)
INTRINS(SSE_PADDUSB, x86_sse2_paddus_b)
INTRINS(SSE_PSUBUSB, x86_sse2_psubus_b)
INTRINS(SSE_PSADBW, x86_sse2_psad_bw)
INTRINS(SSE_PAUSE, x86_sse2_pause)
INTRINS(SSE_MASKMOVDQU, x86_sse2_maskmov_dqu)
Expand Down Expand Up @@ -208,11 +203,21 @@ INTRINS_OVR(SSE_SADD_SATI8, sadd_sat)
INTRINS_OVR(SSE_UADD_SATI8, uadd_sat)
INTRINS_OVR(SSE_SADD_SATI16, sadd_sat)
INTRINS_OVR(SSE_UADD_SATI16, uadd_sat)

INTRINS_OVR(SSE_SSUB_SATI8, ssub_sat)
INTRINS_OVR(SSE_USUB_SATI8, usub_sat)
INTRINS_OVR(SSE_SSUB_SATI16, ssub_sat)
INTRINS_OVR(SSE_USUB_SATI16, usub_sat)
#else
INTRINS(SSE_SADD_SATI8, x86_sse2_padds_b)
INTRINS(SSE_UADD_SATI8, x86_sse2_paddus_b)
INTRINS(SSE_SADD_SATI16, x86_sse2_padds_w)
INTRINS(SSE_UADD_SATI16, x86_sse2_paddus_w)

INTRINS(SSE_SSUB_SATI8, x86_sse2_psubs_b)
INTRINS(SSE_USUB_SATI8, x86_sse2_psubus_b)
INTRINS(SSE_SSUB_SATI16, x86_sse2_psubs_w)
INTRINS(SSE_USUB_SATI16, x86_sse2_psubus_w)
#endif
#endif
#if defined(TARGET_WASM) && LLVM_API_VERSION >= 800
Expand Down
19 changes: 18 additions & 1 deletion src/mono/mono/mini/llvm-jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Transforms/Scalar.h"

#if LLVM_API_VERSION >= 800
#include "llvm/CodeGen/BuiltinGCs.h"
#else
#include "llvm/CodeGen/GCs.h"
#endif

#include <cstdlib>

Expand All @@ -50,6 +55,17 @@ mono_llvm_set_unhandled_exception_handler (void)
{
}

// noop function that merely ensures that certain symbols are not eliminated
// from the resulting binary.
static void
link_gc () {
#if LLVM_API_VERSION >= 800
llvm::linkAllBuiltinGCs();
#else
llvm::linkCoreCLRGC(); // Mono uses built-in "coreclr" GCStrategy
#endif
}

template <typename T>
static std::vector<T> singletonSet(T t) {
std::vector<T> Vec;
Expand Down Expand Up @@ -304,7 +320,6 @@ class MonoLLVMJIT {
initializeInstCombine(registry);
initializeTarget(registry);
initializeLoopIdiomRecognizeLegacyPassPass(registry);
linkCoreCLRGC(); // Mono uses built-in "coreclr" GCStrategy

// FIXME: find optimal mono specific order of passes
// see https://llvm.org/docs/Frontend/PerformanceTips.html#pass-ordering
Expand Down Expand Up @@ -445,6 +460,8 @@ mono_llvm_jit_init ()
{
if (jit != nullptr) return;

link_gc ();

mono_native_tls_alloc (&current_cfg_tls_id, NULL);

InitializeNativeTarget ();
Expand Down
6 changes: 4 additions & 2 deletions src/mono/mono/mini/mini-llvm-cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,18 @@ void
mono_llvm_dump_value (LLVMValueRef value)
{
/* Same as LLVMDumpValue (), but print to stdout */
outs () << (*unwrap<Value> (value)) << "\n";
fflush (stdout);
outs () << (*unwrap<Value> (value)) << "\n";
outs ().flush ();
}

void
mono_llvm_dump_module (LLVMModuleRef module)
{
/* Same as LLVMDumpModule (), but print to stdout */
outs () << (*unwrap (module));
fflush (stdout);
outs () << (*unwrap (module));
outs ().flush ();
}

/* Missing overload for building an alloca with an alignment */
Expand Down
Loading

0 comments on commit 335ffb0

Please sign in to comment.