Skip to content

Commit acdb869

Browse files
Nathan RicciNathan Ricci
Nathan Ricci
and
Nathan Ricci
authored
Refactored INTRINS_OVR to include type infomration, and use it to generate add_intrinsic (#47731)
Co-authored-by: Nathan Ricci <[email protected]>
1 parent 669fda7 commit acdb869

File tree

4 files changed

+99
-228
lines changed

4 files changed

+99
-228
lines changed

src/mono/mono/mini/llvm-intrinsics.h

Lines changed: 83 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,63 +2,67 @@
22
/*
33
* List of LLVM intrinsics
44
*
5-
* INTRINS(id, llvm_id)
5+
* INTRINS(id, llvm_id, llvm_argument_type)
66
* To define a simple intrinsic
7-
* INTRINS_OVR(id, llvm_id)
8-
* To define an overloaded intrinsic
7+
* INTRINS_OVR(id, llvm_id, llvm_argument_type)
8+
* To define an overloaded intrinsic with a single argument
9+
* INTRINS_OVR_2_ARG(id, llvm_id, llvm_argument_type1, llvm_argument_type2)
10+
* To define an overloaded intrinsic with two arguments
11+
* INTRINS_OVR_3_ARG(id, llvm_id, llvm_argument_type1, llvm_argument_type2, llvm_argument_type3)
12+
* To define an overloaded intrinsic with three arguments
913
*/
1014

11-
INTRINS_OVR(MEMSET, memset)
12-
INTRINS_OVR(MEMCPY, memcpy)
13-
INTRINS_OVR(MEMMOVE, memmove)
14-
INTRINS_OVR(SADD_OVF_I32, sadd_with_overflow)
15-
INTRINS_OVR(UADD_OVF_I32, uadd_with_overflow)
16-
INTRINS_OVR(SSUB_OVF_I32, ssub_with_overflow)
17-
INTRINS_OVR(USUB_OVF_I32, usub_with_overflow)
18-
INTRINS_OVR(SMUL_OVF_I32, smul_with_overflow)
19-
INTRINS_OVR(UMUL_OVF_I32, umul_with_overflow)
20-
INTRINS_OVR(SADD_OVF_I64, sadd_with_overflow)
21-
INTRINS_OVR(UADD_OVF_I64, uadd_with_overflow)
22-
INTRINS_OVR(SSUB_OVF_I64, ssub_with_overflow)
23-
INTRINS_OVR(USUB_OVF_I64, usub_with_overflow)
24-
INTRINS_OVR(SMUL_OVF_I64, smul_with_overflow)
25-
INTRINS_OVR(UMUL_OVF_I64, umul_with_overflow)
26-
INTRINS_OVR(SIN, sin)
27-
INTRINS_OVR(COS, cos)
28-
INTRINS_OVR(SQRT, sqrt)
29-
INTRINS_OVR(FLOOR, floor)
30-
INTRINS_OVR(FLOORF, floor)
31-
INTRINS_OVR(CEIL, ceil)
32-
INTRINS_OVR(CEILF, ceil)
33-
INTRINS_OVR(FMA, fma)
34-
INTRINS_OVR(FMAF, fma)
15+
INTRINS_OVR_2_ARG(MEMSET, memset, LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type ())
16+
INTRINS_OVR_3_ARG(MEMCPY, memcpy, LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type () )
17+
INTRINS_OVR_3_ARG(MEMMOVE, memmove, LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt64Type ())
18+
INTRINS_OVR(SADD_OVF_I32, sadd_with_overflow, LLVMInt32Type ())
19+
INTRINS_OVR(UADD_OVF_I32, uadd_with_overflow, LLVMInt32Type ())
20+
INTRINS_OVR(SSUB_OVF_I32, ssub_with_overflow, LLVMInt32Type ())
21+
INTRINS_OVR(USUB_OVF_I32, usub_with_overflow, LLVMInt32Type ())
22+
INTRINS_OVR(SMUL_OVF_I32, smul_with_overflow, LLVMInt32Type ())
23+
INTRINS_OVR(UMUL_OVF_I32, umul_with_overflow, LLVMInt32Type ())
24+
INTRINS_OVR(SADD_OVF_I64, sadd_with_overflow, LLVMInt64Type ())
25+
INTRINS_OVR(UADD_OVF_I64, uadd_with_overflow, LLVMInt64Type ())
26+
INTRINS_OVR(SSUB_OVF_I64, ssub_with_overflow, LLVMInt64Type ())
27+
INTRINS_OVR(USUB_OVF_I64, usub_with_overflow, LLVMInt64Type ())
28+
INTRINS_OVR(SMUL_OVF_I64, smul_with_overflow, LLVMInt64Type ())
29+
INTRINS_OVR(UMUL_OVF_I64, umul_with_overflow, LLVMInt64Type ())
30+
INTRINS_OVR(SIN, sin, LLVMDoubleType ())
31+
INTRINS_OVR(COS, cos, LLVMDoubleType ())
32+
INTRINS_OVR(SQRT, sqrt, LLVMDoubleType ())
33+
INTRINS_OVR(FLOOR, floor, LLVMDoubleType ())
34+
INTRINS_OVR(FLOORF, floor, LLVMFloatType ())
35+
INTRINS_OVR(CEIL, ceil, LLVMDoubleType ())
36+
INTRINS_OVR(CEILF, ceil, LLVMFloatType ())
37+
INTRINS_OVR(FMA, fma, LLVMDoubleType ())
38+
INTRINS_OVR(FMAF, fma, LLVMFloatType ())
3539
/* This isn't an intrinsic, instead llvm seems to special case it by name */
36-
INTRINS_OVR(FABS, fabs)
37-
INTRINS_OVR(ABSF, fabs)
38-
INTRINS_OVR(SINF, sin)
39-
INTRINS_OVR(COSF, cos)
40-
INTRINS_OVR(SQRTF, sqrt)
41-
INTRINS_OVR(POWF, pow)
42-
INTRINS_OVR(POW, pow)
43-
INTRINS_OVR(EXP, exp)
44-
INTRINS_OVR(EXPF, exp)
45-
INTRINS_OVR(LOG, log)
46-
INTRINS_OVR(LOG2, log2)
47-
INTRINS_OVR(LOG2F, log2)
48-
INTRINS_OVR(LOG10, log10)
49-
INTRINS_OVR(LOG10F, log10)
50-
INTRINS_OVR(TRUNC, trunc)
51-
INTRINS_OVR(TRUNCF, trunc)
52-
INTRINS_OVR(COPYSIGN, copysign)
53-
INTRINS_OVR(COPYSIGNF, copysign)
54-
INTRINS_OVR(EXPECT_I8, expect)
55-
INTRINS_OVR(EXPECT_I1, expect)
56-
INTRINS_OVR(CTPOP_I32, ctpop)
57-
INTRINS_OVR(CTPOP_I64, ctpop)
58-
INTRINS_OVR(CTLZ_I32, ctlz)
59-
INTRINS_OVR(CTLZ_I64, ctlz)
60-
INTRINS_OVR(CTTZ_I32, cttz)
61-
INTRINS_OVR(CTTZ_I64, cttz)
40+
INTRINS_OVR(FABS, fabs, LLVMDoubleType ())
41+
INTRINS_OVR(ABSF, fabs,LLVMFloatType ())
42+
INTRINS_OVR(SINF, sin, LLVMFloatType ())
43+
INTRINS_OVR(COSF, cos, LLVMFloatType ())
44+
INTRINS_OVR(SQRTF, sqrt, LLVMFloatType ())
45+
INTRINS_OVR(POWF, pow, LLVMFloatType ())
46+
INTRINS_OVR(POW, pow, LLVMDoubleType ())
47+
INTRINS_OVR(EXP, exp, LLVMDoubleType ())
48+
INTRINS_OVR(EXPF, exp, LLVMFloatType ())
49+
INTRINS_OVR(LOG, log, LLVMDoubleType ())
50+
INTRINS_OVR(LOG2, log2, LLVMDoubleType ())
51+
INTRINS_OVR(LOG2F, log2, LLVMFloatType ())
52+
INTRINS_OVR(LOG10, log10, LLVMDoubleType ())
53+
INTRINS_OVR(LOG10F, log10, LLVMFloatType ())
54+
INTRINS_OVR(TRUNC, trunc, LLVMDoubleType ())
55+
INTRINS_OVR(TRUNCF, trunc, LLVMFloatType ())
56+
INTRINS_OVR(COPYSIGN, copysign, LLVMDoubleType ())
57+
INTRINS_OVR(COPYSIGNF, copysign, LLVMFloatType ())
58+
INTRINS_OVR(EXPECT_I8, expect, LLVMInt8Type ())
59+
INTRINS_OVR(EXPECT_I1, expect, LLVMInt1Type ())
60+
INTRINS_OVR(CTPOP_I32, ctpop, LLVMInt32Type ())
61+
INTRINS_OVR(CTPOP_I64, ctpop, LLVMInt64Type ())
62+
INTRINS_OVR(CTLZ_I32, ctlz, LLVMInt32Type ())
63+
INTRINS_OVR(CTLZ_I64, ctlz, LLVMInt64Type ())
64+
INTRINS_OVR(CTTZ_I32, cttz, LLVMInt32Type ())
65+
INTRINS_OVR(CTTZ_I64, cttz, LLVMInt64Type ())
6266
INTRINS(PREFETCH, prefetch)
6367
INTRINS(BZHI_I32, x86_bmi_bzhi_32)
6468
INTRINS(BZHI_I64, x86_bmi_bzhi_64)
@@ -96,10 +100,10 @@ INTRINS(SSE_SQRT_PD, x86_sse2_sqrt_pd)
96100
INTRINS(SSE_SQRT_SD, x86_sse2_sqrt_sd)
97101
INTRINS(SSE_PMULUDQ, x86_sse2_pmulu_dq)
98102
#else
99-
INTRINS_OVR(SSE_SQRT_PD, sqrt)
100-
INTRINS_OVR(SSE_SQRT_PS, sqrt)
101-
INTRINS_OVR(SSE_SQRT_SD, sqrt)
102-
INTRINS_OVR(SSE_SQRT_SS, sqrt)
103+
INTRINS_OVR(SSE_SQRT_PD, sqrt, sse_r8_t)
104+
INTRINS_OVR(SSE_SQRT_PS, sqrt, sse_r4_t)
105+
INTRINS_OVR(SSE_SQRT_SD, sqrt, LLVMDoubleType ())
106+
INTRINS_OVR(SSE_SQRT_SS, sqrt, LLVMFloatType ())
103107
#endif
104108
INTRINS(SSE_RCP_PS, x86_sse_rcp_ps)
105109
INTRINS(SSE_RSQRT_PS, x86_sse_rsqrt_ps)
@@ -221,15 +225,15 @@ INTRINS(AESNI_AESENCLAST, x86_aesni_aesenclast)
221225
INTRINS(AESNI_AESIMC, x86_aesni_aesimc)
222226
#if LLVM_API_VERSION >= 800
223227
// these intrinsics were renamed in LLVM 8
224-
INTRINS_OVR(SSE_SADD_SATI8, sadd_sat)
225-
INTRINS_OVR(SSE_UADD_SATI8, uadd_sat)
226-
INTRINS_OVR(SSE_SADD_SATI16, sadd_sat)
227-
INTRINS_OVR(SSE_UADD_SATI16, uadd_sat)
228+
INTRINS_OVR(SSE_SADD_SATI8, sadd_sat, sse_i1_t)
229+
INTRINS_OVR(SSE_UADD_SATI8, uadd_sat, sse_i1_t)
230+
INTRINS_OVR(SSE_SADD_SATI16, sadd_sat, sse_i1_t)
231+
INTRINS_OVR(SSE_UADD_SATI16, uadd_sat, sse_i1_t)
228232

229-
INTRINS_OVR(SSE_SSUB_SATI8, ssub_sat)
230-
INTRINS_OVR(SSE_USUB_SATI8, usub_sat)
231-
INTRINS_OVR(SSE_SSUB_SATI16, ssub_sat)
232-
INTRINS_OVR(SSE_USUB_SATI16, usub_sat)
233+
INTRINS_OVR(SSE_SSUB_SATI8, ssub_sat, sse_i2_t)
234+
INTRINS_OVR(SSE_USUB_SATI8, usub_sat, sse_i2_t)
235+
INTRINS_OVR(SSE_SSUB_SATI16, ssub_sat, sse_i2_t)
236+
INTRINS_OVR(SSE_USUB_SATI16, usub_sat, sse_i2_t)
233237
#else
234238
INTRINS(SSE_SADD_SATI8, x86_sse2_padds_b)
235239
INTRINS(SSE_UADD_SATI8, x86_sse2_paddus_b)
@@ -243,14 +247,14 @@ INTRINS(SSE_USUB_SATI16, x86_sse2_psubus_w)
243247
#endif
244248
#endif
245249
#if defined(TARGET_WASM) && LLVM_API_VERSION >= 800
246-
INTRINS_OVR(WASM_ANYTRUE_V16, wasm_anytrue)
247-
INTRINS_OVR(WASM_ANYTRUE_V8, wasm_anytrue)
248-
INTRINS_OVR(WASM_ANYTRUE_V4, wasm_anytrue)
249-
INTRINS_OVR(WASM_ANYTRUE_V2, wasm_anytrue)
250+
INTRINS_OVR(WASM_ANYTRUE_V16, wasm_anytrue, sse_i1_t)
251+
INTRINS_OVR(WASM_ANYTRUE_V8, wasm_anytrue, sse_i2_t)
252+
INTRINS_OVR(WASM_ANYTRUE_V4, wasm_anytrue, sse_i4_t)
253+
INTRINS_OVR(WASM_ANYTRUE_V2, wasm_anytrue, sse_i8_t)
250254
#endif
251255
#if defined(TARGET_ARM64)
252-
INTRINS_OVR(BITREVERSE_I32, bitreverse)
253-
INTRINS_OVR(BITREVERSE_I64, bitreverse)
256+
INTRINS_OVR(BITREVERSE_I32, bitreverse, LLVMInt32Type ())
257+
INTRINS_OVR(BITREVERSE_I64, bitreverse, LLVMInt64Type ())
254258
INTRINS(AARCH64_CRC32B, aarch64_crc32b)
255259
INTRINS(AARCH64_CRC32H, aarch64_crc32h)
256260
INTRINS(AARCH64_CRC32W, aarch64_crc32w)
@@ -273,14 +277,16 @@ INTRINS(AARCH64_SHA256SU0, aarch64_crypto_sha256su0)
273277
INTRINS(AARCH64_SHA256SU1, aarch64_crypto_sha256su1)
274278
INTRINS(AARCH64_SHA256H, aarch64_crypto_sha256h)
275279
INTRINS(AARCH64_SHA256H2, aarch64_crypto_sha256h2)
276-
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_FLOAT, fabs)
277-
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_DOUBLE, fabs)
278-
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT8, aarch64_neon_abs)
279-
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT16, aarch64_neon_abs)
280-
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT32, aarch64_neon_abs)
281-
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT64, aarch64_neon_abs)
280+
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_FLOAT, fabs, sse_r4_t)
281+
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_DOUBLE, fabs, sse_r8_t)
282+
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT8, aarch64_neon_abs, sse_i1_t)
283+
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT16, aarch64_neon_abs, sse_i2_t)
284+
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT32, aarch64_neon_abs, sse_i4_t)
285+
INTRINS_OVR(AARCH64_ADV_SIMD_ABS_INT64, aarch64_neon_abs, sse_i8_t)
282286
#endif
283287

284288
#undef INTRINS
285289
#undef INTRINS_OVR
290+
#undef INTRINS_OVR_2_ARG
291+
#undef INTRINS_OVR_3_ARG
286292

src/mono/mono/mini/mini-llvm-cpp.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,9 @@ get_intrins_id (IntrinsicId id)
633633
Intrinsic::ID intrins_id = Intrinsic::ID::not_intrinsic;
634634
switch (id) {
635635
#define INTRINS(id, llvm_id) case INTRINS_ ## id: intrins_id = Intrinsic::ID::llvm_id; break;
636-
#define INTRINS_OVR(id, llvm_id) case INTRINS_ ## id: intrins_id = Intrinsic::ID::llvm_id; break;
636+
#define INTRINS_OVR(id, llvm_id, ty) case INTRINS_ ## id: intrins_id = Intrinsic::ID::llvm_id; break;
637+
#define INTRINS_OVR_2_ARG(id, llvm_id, ty1, ty2) case INTRINS_ ## id: intrins_id = Intrinsic::ID::llvm_id; break;
638+
#define INTRINS_OVR_3_ARG(id, llvm_id, ty1, ty2, ty3) case INTRINS_ ## id: intrins_id = Intrinsic::ID::llvm_id; break;
637639
#include "llvm-intrinsics.h"
638640
default:
639641
break;
@@ -646,7 +648,9 @@ is_overloaded_intrins (IntrinsicId id)
646648
{
647649
switch (id) {
648650
#define INTRINS(id, llvm_id)
649-
#define INTRINS_OVR(id, llvm_id) case INTRINS_ ## id: return true;
651+
#define INTRINS_OVR(id, llvm_id, ty) case INTRINS_ ## id: return true;
652+
#define INTRINS_OVR_2_ARG(id, llvm_id, ty1, ty2) case INTRINS_ ## id: return true;
653+
#define INTRINS_OVR_3_ARG(id, llvm_id, ty1, ty2, ty3) case INTRINS_ ## id: return true;
650654
#include "llvm-intrinsics.h"
651655
default:
652656
break;

src/mono/mono/mini/mini-llvm-cpp.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@ G_BEGIN_DECLS
2424

2525
typedef enum {
2626
#define INTRINS(id, llvm_id) INTRINS_ ## id,
27-
#define INTRINS_OVR(id, llvm_id) INTRINS_ ## id,
27+
#define INTRINS_OVR(id, llvm_id, ty) INTRINS_ ## id,
28+
#define INTRINS_OVR_2_ARG(id, llvm_id, ty1, ty2) INTRINS_ ## id,
29+
#define INTRINS_OVR_3_ARG(id, llvm_id, ty1, ty2, ty3) INTRINS_ ## id,
2830
#include "llvm-intrinsics.h"
2931
INTRINS_NUM
3032
} IntrinsicId;
3133

34+
3235
/*
3336
* Keep in sync with the enum in utils/mono-memory-model.h.
3437
*/

0 commit comments

Comments
 (0)