Skip to content

Commit

Permalink
Fix VSO 462269.
Browse files Browse the repository at this point in the history
When decomposing a long compare on 32-bit platforms, the operands to the
decomposed compare must be sign- or zero-extended appropriately.
  • Loading branch information
pgavlin authored and RussKeldorph committed Aug 18, 2017
1 parent dbc9793 commit 089fe7b
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 2 deletions.
44 changes: 42 additions & 2 deletions src/jit/decomposelongs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,8 @@ GenTree* DecomposeLongs::DecomposeCast(LIR::Use& use)
// check provided by codegen.
//

loResult = loSrcOp;
const bool signExtend = (cast->gtFlags & GTF_UNSIGNED) == 0;
loResult = EnsureIntSized(loSrcOp, signExtend);

hiResult = cast;
hiResult->gtType = TYP_INT;
Expand Down Expand Up @@ -649,7 +650,9 @@ GenTree* DecomposeLongs::DecomposeCast(LIR::Use& use)
}
else if (varTypeIsUnsigned(srcType))
{
loResult = cast->gtGetOp1();
const bool signExtend = (cast->gtFlags & GTF_UNSIGNED) == 0;
loResult = EnsureIntSized(cast->gtGetOp1(), signExtend);

hiResult = m_compiler->gtNewZeroConNode(TYP_INT);

Range().InsertAfter(cast, hiResult);
Expand Down Expand Up @@ -1881,6 +1884,43 @@ GenTree* DecomposeLongs::RepresentOpAsLocalVar(GenTree* op, GenTree* user, GenTr
}
}

//------------------------------------------------------------------------
// DecomposeLongs::EnsureIntSized:
// Checks to see if the given node produces an int-sized value and
// performs the appropriate widening if it does not.
//
// Arguments:
// node - The node that may need to be widened.
// signExtend - True if the value should be sign-extended; false if it
// should be zero-extended.
//
// Return Value:
// The node that produces the widened value.
GenTree* DecomposeLongs::EnsureIntSized(GenTree* node, bool signExtend)
{
assert(node != nullptr);
if (!varTypeIsSmall(node))
{
assert(genTypeSize(node) == genTypeSize(TYP_INT));
return node;
}

if (node->OperIs(GT_LCL_VAR) && !m_compiler->lvaTable[node->AsLclVarCommon()->gtLclNum].lvNormalizeOnLoad())
{
node->gtType = TYP_INT;
return node;
}

GenTree* const cast = m_compiler->gtNewCastNode(TYP_INT, node, node->TypeGet());
if (!signExtend)
{
cast->gtFlags |= GTF_UNSIGNED;
}

Range().InsertAfter(node, cast);
return cast;
}

//------------------------------------------------------------------------
// GetHiOper: Convert arithmetic operator to "high half" operator of decomposed node.
//
Expand Down
1 change: 1 addition & 0 deletions src/jit/decomposelongs.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class DecomposeLongs
// Helper functions
GenTree* FinalizeDecomposition(LIR::Use& use, GenTree* loResult, GenTree* hiResult, GenTree* insertResultAfter);
GenTree* RepresentOpAsLocalVar(GenTree* op, GenTree* user, GenTree** edge);
GenTree* EnsureIntSized(GenTree* node, bool signExtend);

GenTree* StoreNodeToVar(LIR::Use& use);
static genTreeOps GetHiOper(genTreeOps oper);
Expand Down
142 changes: 142 additions & 0 deletions tests/src/JIT/Regression/JitBlue/DevDiv_462269/DevDiv_462269.il
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

.assembly extern mscorlib{}
.assembly ILGEN_MODULE{}
.class ILGEN_CLASS
{
.method static int64 ILGEN_METHOD(unsigned int32, float32, unsigned int8, char, int64, float64)
{
.maxstack 65535
.locals init (float64, unsigned int32, int64, int32, unsigned int16, unsigned int64, char, int8, unsigned int32, bool, bool)

ldloc.s 0x02
ldloc.s 0x02
add
conv.ovf.u2
not
ldarg 0x0004
ldloc 0x0005
conv.ovf.i8.un
conv.ovf.i2
shl
ldarg.s 0x02
conv.ovf.u4
ldarg 0x0004
conv.ovf.u1.un
rem.un
shr.un
not
ldarg.s 0x04
not
div
ldloc 0x0005
add
conv.ovf.u8.un
ldloc.s 0x05
ldloc 0x0002
ldarg.s 0x04
div.un
neg
ldarg 0x0004
ldloc.s 0x06
conv.ovf.i8
conv.ovf.u1.un
conv.ovf.i8.un
sub
sub.ovf
and
ldarg 0x0005
ldarg.s 0x05
ceq
starg.s 0x03
ldarg 0x0003
conv.ovf.i8
ldarg.s 0x03
conv.ovf.u8
ldloc.s 0x04
shl
cgt
ldarg.s 0x03
neg
cgt
not
shr
ldarg.s 0x01
pop
and
conv.ovf.u4
ceq
pop
ldloc 0x0000
ldloc 0x0007
conv.r.un
neg
mul
ckfinite
ldloc 0x0000
ckfinite
neg
mul
pop
ldloc.s 0x05
ldloc 0x0005
and
ldc.r8 float64(0xc4a68d93e8d67cec)
conv.ovf.i8.un
dup
and
and
ldarg 0x0004
ldarg 0x0000
ldarg 0x0003
clt
shl
conv.ovf.u4
ldarg.s 0x00
shr.un
conv.ovf.u8
ldloc 0x0006
pop
xor
conv.ovf.i8.un
conv.i8
neg
ldarg.s 0x01
conv.i1
conv.u8
nop
add.ovf.un
ldloc.s 0x02
conv.u8
mul.ovf
ret
}

.method static int32 Main()
{
.entrypoint

.try
{
ldc.i4 0
ldc.r4 0
ldc.i4 0
dup
ldc.i8 0
ldc.r8 0
call int64 ILGEN_CLASS::ILGEN_METHOD(unsigned int32, float32, unsigned int8, char, int64, float64)
pop
leave.s done
}
catch [mscorlib]System.Exception
{
leave.s done
}

done:
ldc.i4 100
ret
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
<OutputType>Exe</OutputType>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
<Visible>False</Visible>
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<PropertyGroup>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="DevDiv_462269.il" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
</PropertyGroup>
</Project>

0 comments on commit 089fe7b

Please sign in to comment.