Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2151,17 +2151,18 @@ void CodeGen::instGen_Set_Reg_To_Base_Plus_Imm(emitAttr size,
insFlags flags DEBUGARG(size_t targetHandle)
DEBUGARG(GenTreeFlags gtFlags))
{
// If the imm values < 12 bits, we can use a single "add rsvd, reg2, #imm".
// Otherwise, use "mov rsvd, #imm", followed up "add rsvd, reg2, rsvd".
// If the immediate can be encoded by add/sub, use a single instruction.
// Otherwise, use "mov dstReg, #imm", followed by "add dstReg, baseReg, dstReg".
// Keep baseReg as the second operand in the fallback since it can be SP.

if (imm < 4096)
if (emitter::emitIns_valid_imm_for_add(imm, size))
{
GetEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, dstReg, baseReg, imm);
GetEmitter()->emitIns_R_R_I(INS_add, size, dstReg, baseReg, imm);
}
else
Comment thread
a74nh marked this conversation as resolved.
{
instGen_Set_Reg_To_Imm(size, dstReg, imm);
GetEmitter()->emitIns_R_R_R(INS_add, size, dstReg, dstReg, baseReg);
GetEmitter()->emitIns_R_R_R(INS_add, size, dstReg, baseReg, dstReg);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/emitarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15017,8 +15017,8 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
// First load/store tmpReg with the large offset constant
codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset);
// Then add the base register
// rd = rd + base
emitIns_R_R_R(INS_add, addType, tmpReg, tmpReg, memBase->GetRegNum());
// rd = base + rd
emitIns_R_R_R(INS_add, addType, tmpReg, memBase->GetRegNum(), tmpReg);
Comment thread
a74nh marked this conversation as resolved.

noway_assert(emitInsIsLoad(ins) || (tmpReg != dataReg));
noway_assert(tmpReg != index->GetRegNum());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.IL">
<PropertyGroup>
<LanguageTargets>$(RepoRoot)src/coreclr/.nuget/Microsoft.NET.Sdk.IL/Microsoft.NET.Sdk.IL.targets.template</LanguageTargets>
<Optimize>True</Optimize>
<RequiresProcessIsolation>true</RequiresProcessIsolation>
<CLRTestTargetUnsupported Condition="'$(TargetArchitecture)' != 'arm64'">true</CLRTestTargetUnsupported>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).il" />
<CLRTestEnvironmentVariable Include="DOTNET_TieredCompilation" Value="0" />
<CLRTestEnvironmentVariable Include="DOTNET_JitStressModeNames" Value="STRESS_LCL_FLDS" />
<CLRTestEnvironmentVariable Include="DOTNET_JitSaveFpLrWithCalleeSavedRegisters" Value="2" />
</ItemGroup>
</Project>
207 changes: 207 additions & 0 deletions src/tests/JIT/Regression/JitBlue/GitHub_130437/GitHub_130437.il
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

.assembly extern mscorlib {}
.assembly extern System.Numerics.Vectors {}
.assembly extern System.Runtime.Intrinsics {}

.assembly GitHub_130437 {}
.module GitHub_130437.dll

.class private explicit ansi sealed beforefieldinit LargeFrame
extends [mscorlib]System.ValueType
{
.pack 1
.size 8192
}

.class private auto ansi beforefieldinit GitHub_130437
extends [mscorlib]System.Object
{
.method public hidebysig static int32
Main() cil managed
{
.entrypoint
.maxstack 2

call bool [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Arm.Sve2::get_IsSupported()
brtrue.s SVE_SUPPORTED

ldc.i4.s 100
ret

SVE_SUPPORTED:
call int64 GitHub_130437::RunBasicScenario_UnsafeRead()
ldc.i4.s 44
conv.i8
ceq
brfalse.s FAIL

ldc.i4.s 100
ret

FAIL:
ldc.i4.m1
ret
}

.method private hidebysig static int64
RunBasicScenario_UnsafeRead() cil managed noinlining
{
.maxstack 4
.locals init (
// The mask local must be allocated above the large frame local so the
// SP-based predicate spill/reload uses a large positive offset.
[0] valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64> mask,
[1] valuetype LargeFrame largeFrame,
[2] uint32[] baseArray,
[3] int64[] maskArray,
[4] int64[] offsetsArray,
[5] uint32* pinned basePinned,
[6] int64* pinned maskPinned,
[7] int64* pinned offsetsPinned,
[8] valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64> result1,
[9] valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64> result2,
[10] int32 index)

ldc.i4 1024
newarr [mscorlib]System.UInt32
stloc.2

ldloc.2
ldc.i4.0
ldc.i4.s 20
stelem.i4

ldc.i4.s 64
newarr [mscorlib]System.Int64
stloc.3

ldc.i4.0
stloc.s index

FILL_MASK:
ldloc.s index
ldc.i4.s 64
bge.s FILL_MASK_DONE

ldloc.3
ldloc.s index
ldc.i4.1
conv.i8
stelem.i8

ldloc.s index
ldc.i4.1
add
stloc.s index
br.s FILL_MASK

FILL_MASK_DONE:
ldc.i4.s 64
newarr [mscorlib]System.Int64
stloc.s offsetsArray

ldloc.2
ldc.i4.0
ldelema [mscorlib]System.UInt32
stloc.s basePinned

ldloc.3
ldc.i4.0
ldelema [mscorlib]System.Int64
stloc.s maskPinned

ldloc.s offsetsArray
ldc.i4.0
ldelema [mscorlib]System.Int64
stloc.s offsetsPinned

ldloc.s maskPinned
ldobj valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>
stloc.0

ldloca.s largeFrame
call void GitHub_130437::TouchLargeFrame(valuetype LargeFrame&)

ldloc.0
ldloc.s basePinned
ldloc.s offsetsPinned
ldobj valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>
call valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64> [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Arm.Sve2::GatherVectorUInt32WithByteOffsetsZeroExtendNonTemporal(valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>, uint32*, valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>)
stloc.s result1

ldloc.0
ldloc.s basePinned
ldloc.s offsetsPinned
ldobj valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>
call valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64> [System.Runtime.Intrinsics]System.Runtime.Intrinsics.Arm.Sve2::GatherVectorUInt32WithByteOffsetsZeroExtendNonTemporal(valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>, uint32*, valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>)
stloc.s result2

ldloca.s result1
ldc.i4.0
call instance !0 valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>::get_Item(int32)

ldloca.s result2
ldc.i4.0
call instance !0 valuetype [System.Numerics.Vectors]System.Numerics.Vector`1<int64>::get_Item(int32)
add

ldloca.s largeFrame
call int64 GitHub_130437::SumLargeFrame(valuetype LargeFrame&)
add
ret
}

.method private hidebysig static void
TouchLargeFrame(valuetype LargeFrame& frame) cil managed noinlining
{
.maxstack 3

ldarg.0
conv.u
ldc.i4.0
add
ldc.i4.1
stind.i1

ldarg.0
conv.u
ldc.i4 4096
add
ldc.i4.2
stind.i1

ldarg.0
conv.u
ldc.i4 8191
add
ldc.i4.3
stind.i1

ret
}

.method private hidebysig static int64
SumLargeFrame(valuetype LargeFrame& frame) cil managed noinlining
{
.maxstack 3

ldarg.0
conv.u
ldc.i4.0
add
ldind.u1
conv.i8

ldarg.0
conv.u
ldc.i4 8191
add
ldind.u1
conv.i8
add

ret
}
}
Loading