Skip to content

Commit e938e44

Browse files
authored
Add support for LLVM 14.x (#68719)
* [mono][jit] Remove AdvSimd.ReverseElementBits () intrinsics, there is no corresponding managed method. * [mono][llvm] Add support for LLVM 14.x. * Remove unused AARCH64_ADV_SIMD_RBIT intrinsic. * Add back ReverseElementBits intrinsic.
1 parent 0e84780 commit e938e44

File tree

5 files changed

+72
-24
lines changed

5 files changed

+72
-24
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ INTRINS(PEXT_I32, x86_bmi_pext_32, X86)
9999
INTRINS(PEXT_I64, x86_bmi_pext_64, X86)
100100
INTRINS(PDEP_I32, x86_bmi_pdep_32, X86)
101101
INTRINS(PDEP_I64, x86_bmi_pdep_64, X86)
102+
103+
#if LLVM_API_VERSION >= 1400
104+
INTRINS_OVR_TAG(ROUNDEVEN, roundeven, Generic, Scalar | V64 | V128 | R4 | R8)
105+
#endif
106+
102107
#if defined(TARGET_AMD64) || defined(TARGET_X86)
103108
INTRINS(SSE_PMOVMSKB, x86_sse2_pmovmskb_128, X86)
104109
INTRINS(SSE_MOVMSK_PS, x86_sse_movmsk_ps, X86)
@@ -256,6 +261,7 @@ INTRINS_OVR(WASM_ANYTRUE_V2, wasm_anytrue, Wasm, sse_i8_t)
256261
#if defined(TARGET_ARM64)
257262
INTRINS_OVR(BITREVERSE_I32, bitreverse, Generic, LLVMInt32Type ())
258263
INTRINS_OVR(BITREVERSE_I64, bitreverse, Generic, LLVMInt64Type ())
264+
INTRINS_OVR_TAG(BITREVERSE, bitreverse, Generic, V64 | V128 | I1 | I2 | I4 | I8)
259265
INTRINS(AARCH64_CRC32B, aarch64_crc32b, Arm64)
260266
INTRINS(AARCH64_CRC32H, aarch64_crc32h, Arm64)
261267
INTRINS(AARCH64_CRC32W, aarch64_crc32w, Arm64)
@@ -394,10 +400,14 @@ INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRSQRTE, aarch64_neon_frsqrte, Arm64, Scalar |
394400
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRSQRTS, aarch64_neon_frsqrts, Arm64, Scalar | V64 | V128 | R4 | R8)
395401
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRECPS, aarch64_neon_frecps, Arm64, Scalar | V64 | V128 | R4 | R8)
396402

403+
#if LLVM_API_VERSION < 1400
397404
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_RBIT, aarch64_neon_rbit, Arm64, V64 | V128 | I1)
405+
#endif
398406

399407
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTA, round, Generic, Scalar | V64 | V128 | R4 | R8)
408+
#if LLVM_API_VERSION < 1400
400409
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTN, aarch64_neon_frintn, Arm64, Scalar | V64 | V128 | R4 | R8)
410+
#endif
401411
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTM, floor, Generic, Scalar | V64 | V128 | R4 | R8)
402412
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTP, ceil, Generic, Scalar | V64 | V128 | R4 | R8)
403413
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTZ, trunc, Generic, Scalar | V64 | V128 | R4 | R8)

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

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,10 @@ mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty, LLVMValueRef Arr
105105
}
106106

107107
LLVMValueRef
108-
mono_llvm_build_atomic_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
108+
mono_llvm_build_atomic_load (LLVMBuilderRef builder, LLVMTypeRef Type, LLVMValueRef PointerVal,
109109
const char *Name, gboolean is_volatile, int alignment, BarrierKind barrier)
110110
{
111-
LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
111+
LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(Type), unwrap(PointerVal), is_volatile, Name);
112112

113113
ins->setAlignment (to_align (alignment));
114114
switch (barrier) {
@@ -129,12 +129,12 @@ mono_llvm_build_atomic_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
129129
}
130130

131131
LLVMValueRef
132-
mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
132+
mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMTypeRef Type, LLVMValueRef PointerVal,
133133
const char *Name, gboolean is_volatile, int alignment)
134134
{
135135
LoadInst *ins;
136136

137-
ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
137+
ins = unwrap(builder)->CreateLoad(unwrap(Type), unwrap(PointerVal), is_volatile, Name);
138138
ins->setAlignment (to_align (alignment));
139139

140140
return wrap(ins);
@@ -320,12 +320,22 @@ mono_llvm_set_call_nonnull_arg (LLVMValueRef wrapped_calli, int argNo)
320320
dyn_cast<CallBase>(calli)->addParamAttr (argNo, Attribute::NonNull);
321321
}
322322

323-
void
324-
mono_llvm_set_call_nonnull_ret (LLVMValueRef wrapped_calli)
323+
static void
324+
add_ret_attr (LLVMValueRef wrapped_calli, Attribute::AttrKind Kind)
325325
{
326326
Instruction *calli = unwrap<Instruction> (wrapped_calli);
327327

328-
dyn_cast<CallBase>(calli)->addAttribute (AttributeList::ReturnIndex, Attribute::NonNull);
328+
#if LLVM_API_VERSION >= 1400
329+
dyn_cast<CallBase>(calli)->addRetAttr (Kind);
330+
#else
331+
dyn_cast<CallBase>(calli)->addAttribute (AttributeList::ReturnIndex, Kind);
332+
#endif
333+
}
334+
335+
void
336+
mono_llvm_set_call_nonnull_ret (LLVMValueRef wrapped_calli)
337+
{
338+
add_ret_attr (wrapped_calli, Attribute::NonNull);
329339
}
330340

331341
void
@@ -423,17 +433,20 @@ mono_llvm_set_call_notailcall (LLVMValueRef func)
423433
void
424434
mono_llvm_set_call_noalias_ret (LLVMValueRef wrapped_calli)
425435
{
426-
Instruction *calli = unwrap<Instruction> (wrapped_calli);
427-
428-
dyn_cast<CallBase>(calli)->addAttribute (AttributeList::ReturnIndex, Attribute::NoAlias);
436+
add_ret_attr (wrapped_calli, Attribute::NoAlias);
429437
}
430438

431439
void
432440
mono_llvm_set_alignment_ret (LLVMValueRef call, int alignment)
433441
{
434442
Instruction *ins = unwrap<Instruction> (call);
435443
auto &ctx = ins->getContext ();
444+
445+
#if LLVM_API_VERSION >= 1400
446+
dyn_cast<CallBase>(ins)->addRetAttr (Attribute::getWithAlignment(ctx, to_align (alignment)));
447+
#else
436448
dyn_cast<CallBase>(ins)->addAttribute (AttributeList::ReturnIndex, Attribute::getWithAlignment(ctx, to_align (alignment)));
449+
#endif
437450
}
438451

439452
static Attribute::AttrKind
@@ -495,13 +508,21 @@ mono_llvm_add_param_byval_attr (LLVMValueRef param, LLVMTypeRef type)
495508
void
496509
mono_llvm_add_instr_attr (LLVMValueRef val, int index, AttrKind kind)
497510
{
511+
#if LLVM_API_VERSION >= 1400
512+
unwrap<CallBase> (val)->addParamAttr (index - 1, convert_attr (kind));
513+
#else
498514
unwrap<CallBase> (val)->addAttribute (index, convert_attr (kind));
515+
#endif
499516
}
500517

501518
void
502519
mono_llvm_add_instr_byval_attr (LLVMValueRef val, int index, LLVMTypeRef type)
503520
{
521+
#if LLVM_API_VERSION >= 1400
522+
unwrap<CallBase> (val)->addParamAttr (index - 1, Attribute::getWithByValType (*unwrap (LLVMGetGlobalContext ()), unwrap (type)));
523+
#else
504524
unwrap<CallBase> (val)->addAttribute (index, Attribute::getWithByValType (*unwrap (LLVMGetGlobalContext ()), unwrap (type)));
525+
#endif
505526
}
506527

507528
void*

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty,
6868
int alignment, const char *Name);
6969

7070
LLVMValueRef
71-
mono_llvm_build_atomic_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
71+
mono_llvm_build_atomic_load (LLVMBuilderRef builder, LLVMTypeRef Type, LLVMValueRef PointerVal,
7272
const char *Name, gboolean is_volatile, int alignment, BarrierKind barrier);
7373

7474
LLVMValueRef
75-
mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
75+
mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMTypeRef Type, LLVMValueRef PointerVal,
7676
const char *Name, gboolean is_volatile, int alignment);
7777

7878
LLVMValueRef

src/mono/mono/mini/mini-llvm.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6605,7 +6605,7 @@ MONO_RESTORE_WARNING
66056605
addr = convert (ctx, addr, LLVMPointerType (t, 0));
66066606

66076607
if (is_unaligned)
6608-
values [ins->dreg] = mono_llvm_build_aligned_load (builder, addr, dname, is_volatile, 1);
6608+
values [ins->dreg] = mono_llvm_build_aligned_load (builder, t, addr, dname, is_volatile, 1);
66096609
else
66106610
values [ins->dreg] = emit_load (builder, t, addr, dname, is_volatile);
66116611

@@ -7172,7 +7172,7 @@ MONO_RESTORE_WARNING
71727172
addr = convert (ctx, addr, LLVMPointerType (t, 0));
71737173

71747174
ARM64_ATOMIC_FENCE_FIX;
7175-
values [ins->dreg] = mono_llvm_build_atomic_load (builder, addr, dname, is_volatile, size, barrier);
7175+
values [ins->dreg] = mono_llvm_build_atomic_load (builder, t, addr, dname, is_volatile, size, barrier);
71767176
ARM64_ATOMIC_FENCE_FIX;
71777177

71787178
if (sext)
@@ -7511,7 +7511,11 @@ MONO_RESTORE_WARNING
75117511

75127512
indexes [0] = const_int32 (0);
75137513
indexes [1] = const_int32 (0);
7514+
#if LLVM_API_VERSION >= 1400
7515+
LLVMSetInitializer (ref_var, LLVMConstGEP2 (var_type, name_var, indexes, 2));
7516+
#else
75147517
LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
7518+
#endif
75157519
LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
75167520
LLVMSetExternallyInitialized (ref_var, TRUE);
75177521
LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
@@ -7626,7 +7630,7 @@ MONO_RESTORE_WARNING
76267630
LLVMValueRef src;
76277631

76287632
src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
7629-
values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
7633+
values [ins->dreg] = mono_llvm_build_aligned_load (builder, t, src, "", FALSE, 1);
76307634
break;
76317635
}
76327636
case OP_STOREX_MEMBASE: {
@@ -8439,8 +8443,9 @@ MONO_RESTORE_WARNING
84398443

84408444
case OP_SSE_LOADU: {
84418445
LLVMValueRef dst_ptr = convert (ctx, lhs, LLVMPointerType (primitive_type_to_llvm_type (inst_c1_type (ins)), 0));
8442-
LLVMValueRef dst_vec = LLVMBuildBitCast (builder, dst_ptr, LLVMPointerType (type_to_sse_type (ins->inst_c1), 0), "");
8443-
values [ins->dreg] = mono_llvm_build_aligned_load (builder, dst_vec, "", FALSE, ins->inst_c0); // inst_c0 is alignment
8446+
LLVMTypeRef etype = type_to_sse_type (ins->inst_c1);
8447+
LLVMValueRef dst_vec = LLVMBuildBitCast (builder, dst_ptr, LLVMPointerType (etype, 0), "");
8448+
values [ins->dreg] = mono_llvm_build_aligned_load (builder, etype, dst_vec, "", FALSE, ins->inst_c0); // inst_c0 is alignment
84448449
break;
84458450
}
84468451
case OP_SSE_MOVSS: {
@@ -8467,7 +8472,7 @@ MONO_RESTORE_WARNING
84678472
LLVMTypeRef srcty = LLVMGetElementType (rty);
84688473
LLVMValueRef zero = LLVMConstNull (rty);
84698474
LLVMValueRef addr = convert (ctx, lhs, LLVMPointerType (srcty, 0));
8470-
LLVMValueRef val = mono_llvm_build_aligned_load (builder, addr, "", FALSE, 1);
8475+
LLVMValueRef val = mono_llvm_build_aligned_load (builder, srcty, addr, "", FALSE, 1);
84718476
values [ins->dreg] = LLVMBuildInsertElement (builder, zero, val, const_int32 (0), dname);
84728477
break;
84738478
}
@@ -9097,7 +9102,7 @@ MONO_RESTORE_WARNING
90979102
case OP_SSE3_MOVDDUP_MEM: {
90989103
LLVMValueRef undef = LLVMGetUndef (v128_r8_t);
90999104
LLVMValueRef addr = convert (ctx, lhs, LLVMPointerType (r8_t, 0));
9100-
LLVMValueRef elem = mono_llvm_build_aligned_load (builder, addr, "sse3_movddup_mem", FALSE, 1);
9105+
LLVMValueRef elem = mono_llvm_build_aligned_load (builder, r8_t, addr, "sse3_movddup_mem", FALSE, 1);
91019106
LLVMValueRef val = LLVMBuildInsertElement (builder, undef, elem, const_int32 (0), "sse3_movddup_mem");
91029107
values [ins->dreg] = LLVMBuildShuffleVector (builder, val, undef, LLVMConstNull (LLVMVectorType (i4_t, 2)), "sse3_movddup_mem");
91039108
break;
@@ -9322,7 +9327,7 @@ MONO_RESTORE_WARNING
93229327
LLVMValueRef value;
93239328
if (LLVMGetTypeKind (LLVMTypeOf (lhs)) != LLVMVectorTypeKind) {
93249329
LLVMValueRef bitcasted = LLVMBuildBitCast (ctx->builder, lhs, LLVMPointerType (vec_type, 0), "");
9325-
value = mono_llvm_build_aligned_load (builder, bitcasted, "", FALSE, 1);
9330+
value = mono_llvm_build_aligned_load (builder, vec_type, bitcasted, "", FALSE, 1);
93269331
} else {
93279332
value = LLVMBuildBitCast (ctx->builder, lhs, vec_type, "");
93289333
}
@@ -9353,8 +9358,9 @@ MONO_RESTORE_WARNING
93539358

93549359
case OP_SSE41_LOADANT: {
93559360
LLVMValueRef dst_ptr = convert (ctx, lhs, LLVMPointerType (primitive_type_to_llvm_type (inst_c1_type (ins)), 0));
9356-
LLVMValueRef dst_vec = LLVMBuildBitCast (builder, dst_ptr, LLVMPointerType (type_to_sse_type (ins->inst_c1), 0), "");
9357-
LLVMValueRef load = mono_llvm_build_aligned_load (builder, dst_vec, "", FALSE, 16);
9361+
LLVMTypeRef etype = type_to_sse_type (ins->inst_c1);
9362+
LLVMValueRef dst_vec = LLVMBuildBitCast (builder, dst_ptr, LLVMPointerType (etype, 0), "");
9363+
LLVMValueRef load = mono_llvm_build_aligned_load (builder, etype, dst_vec, "", FALSE, 16);
93589364
set_nontemporal_flag (load);
93599365
values [ins->dreg] = load;
93609366
break;
@@ -10641,7 +10647,7 @@ MONO_RESTORE_WARNING
1064110647
LLVMTypeRef elem_t = LLVMGetElementType (ret_t);
1064210648
LLVMValueRef address = convert (ctx, arg3, LLVMPointerType (elem_t, 0));
1064310649
unsigned int alignment = mono_llvm_get_prim_size_bits (ret_t) / 8;
10644-
LLVMValueRef result = mono_llvm_build_aligned_load (builder, address, "arm64_ld1_insert", FALSE, alignment);
10650+
LLVMValueRef result = mono_llvm_build_aligned_load (builder, elem_t, address, "arm64_ld1_insert", FALSE, alignment);
1064510651
result = LLVMBuildInsertElement (builder, lhs, result, rhs, "arm64_ld1_insert");
1064610652
values [ins->dreg] = result;
1064710653
break;
@@ -10652,13 +10658,15 @@ MONO_RESTORE_WARNING
1065210658
LLVMTypeRef ret_t = simd_class_to_llvm_type (ctx, ins->klass);
1065310659
unsigned int alignment = mono_llvm_get_prim_size_bits (ret_t) / 8;
1065410660
LLVMValueRef address = lhs;
10661+
LLVMTypeRef etype = ret_t;
1065510662
LLVMTypeRef address_t = LLVMPointerType (ret_t, 0);
1065610663
if (replicate) {
1065710664
LLVMTypeRef elem_t = LLVMGetElementType (ret_t);
10665+
etype = elem_t;
1065810666
address_t = LLVMPointerType (elem_t, 0);
1065910667
}
1066010668
address = convert (ctx, address, address_t);
10661-
LLVMValueRef result = mono_llvm_build_aligned_load (builder, address, "arm64_ld1", FALSE, alignment);
10669+
LLVMValueRef result = mono_llvm_build_aligned_load (builder, etype, address, "arm64_ld1", FALSE, alignment);
1066210670
if (replicate) {
1066310671
unsigned int elems = LLVMGetVectorSize (ret_t);
1066410672
result = broadcast_element (ctx, result, elems);

src/mono/mono/mini/simd-intrinsics.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,11 +2517,20 @@ static SimdIntrinsic advsimd_methods [] = {
25172517
{SN_ReverseElement16, OP_ARM64_REVN, 16},
25182518
{SN_ReverseElement32, OP_ARM64_REVN, 32},
25192519
{SN_ReverseElement8, OP_ARM64_REVN, 8},
2520+
#if LLVM_API_VERSION >= 1400
2521+
{SN_ReverseElementBits, OP_XOP_OVR_X_X, INTRINS_BITREVERSE},
2522+
#else
25202523
{SN_ReverseElementBits, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_RBIT},
2524+
#endif
25212525
{SN_RoundAwayFromZero, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FRINTA},
25222526
{SN_RoundAwayFromZeroScalar, OP_XOP_OVR_SCALAR_X_X, INTRINS_AARCH64_ADV_SIMD_FRINTA},
2527+
#if LLVM_API_VERSION >= 1400
2528+
{SN_RoundToNearest, OP_XOP_OVR_X_X, INTRINS_ROUNDEVEN},
2529+
{SN_RoundToNearestScalar, OP_XOP_OVR_SCALAR_X_X, INTRINS_ROUNDEVEN},
2530+
#else
25232531
{SN_RoundToNearest, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FRINTN},
25242532
{SN_RoundToNearestScalar, OP_XOP_OVR_SCALAR_X_X, INTRINS_AARCH64_ADV_SIMD_FRINTN},
2533+
#endif
25252534
{SN_RoundToNegativeInfinity, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FRINTM},
25262535
{SN_RoundToNegativeInfinityScalar, OP_XOP_OVR_SCALAR_X_X, INTRINS_AARCH64_ADV_SIMD_FRINTM},
25272536
{SN_RoundToPositiveInfinity, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FRINTP},

0 commit comments

Comments
 (0)