Skip to content

Commit

Permalink
[JIT] ARM32/ARM64 - Fixed zero/sign-extension for GT_STORE_LCL_VAR
Browse files Browse the repository at this point in the history
…in codegen (#84716)

* Try to zero-extend if it is possible

* Added test

* Fix arm32 as well

* Remove branch check for arm32. Added more specific check for arm64.

* Remove unwanted code

* Trying to fix build

* use general register check

* Update Runtime_84693.cs
  • Loading branch information
TIHan committed Apr 18, 2023
1 parent dbcffe7 commit 9cc8163
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
16 changes: 14 additions & 2 deletions src/coreclr/jit/codegenarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,8 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree)
LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
var_types targetType = varDsc->GetRegisterType(tree);

emitter* emit = GetEmitter();

if (targetType == TYP_LONG)
{
genStoreLongLclVar(tree);
Expand Down Expand Up @@ -1114,13 +1116,23 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree)
instruction ins = ins_StoreFromSrc(dataReg, targetType);
emitAttr attr = emitTypeSize(targetType);

emitter* emit = GetEmitter();
emit->emitIns_S_R(ins, attr, dataReg, varNum, /* offset */ 0);
}
else // store into register (i.e move into register)
{
// Assign into targetReg when dataReg (from op1) is not the same register
inst_Mov(targetType, targetReg, dataReg, /* canSkip */ true);
// Only zero/sign extend if we are using general registers.
if (varTypeIsIntegral(targetType) && emit->isGeneralRegister(targetReg) &&
emit->isGeneralRegister(dataReg))
{
// We use 'emitActualTypeSize' as the instructions require 4BYTE.
inst_Mov_Extend(targetType, /* srcInReg */ true, targetReg, dataReg, /* canSkip */ true,
emitActualTypeSize(targetType));
}
else
{
inst_Mov(targetType, targetReg, dataReg, /* canSkip */ true);
}
}

genUpdateLifeStore(tree, targetReg, varDsc);
Expand Down
12 changes: 11 additions & 1 deletion src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2940,7 +2940,17 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* lclNode)
else // store into register (i.e move into register)
{
// Assign into targetReg when dataReg (from op1) is not the same register
inst_Mov(targetType, targetReg, dataReg, /* canSkip */ true);
// Only zero/sign extend if we are using general registers.
if (varTypeIsIntegral(targetType) && emit->isGeneralRegister(targetReg) && emit->isGeneralRegister(dataReg))
{
// We use 'emitActualTypeSize' as the instructions require 8BYTE or 4BYTE.
inst_Mov_Extend(targetType, /* srcInReg */ true, targetReg, dataReg, /* canSkip */ true,
emitActualTypeSize(targetType));
}
else
{
inst_Mov(targetType, targetReg, dataReg, /* canSkip */ true);
}
}
genUpdateLifeStore(lclNode, targetReg, varDsc);
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/emitarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4185,7 +4185,7 @@ void emitter::emitIns_Mov(

case INS_sxtw:
{
assert(size == EA_8BYTE);
assert((size == EA_8BYTE) || (size == EA_4BYTE));
FALLTHROUGH;
}

Expand Down
40 changes: 40 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_84693/Runtime_84693.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Xunit;

public class Test
{
// This is trying to verify that we zero-extend from the result of "(byte)(-s_2)".
public class Program
{
public static short s_2;

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Consume(int x) {}

[MethodImpl(MethodImplOptions.NoInlining)]
public static int M8(byte arg0)
{
s_2 = 1;
arg0 = (byte)(-s_2);
var vr1 = arg0 & arg0;
Consume(vr1);
return vr1;
}
}

[Fact]
public static int TestEntryPoint() {
var result = Test.Program.M8(1);
if (result != 255)
{
return 0;
}
return 100;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit 9cc8163

Please sign in to comment.