// check provided by codegen.
//
- loResult = loSrcOp;
+ const bool signExtend = (cast->gtFlags & GTF_UNSIGNED) == 0;
+ loResult = EnsureIntSized(loSrcOp, signExtend);
hiResult = cast;
hiResult->gtType = TYP_INT;
}
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);
}
//------------------------------------------------------------------------
+// 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.
//
// Arguments:
// 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);
--- /dev/null
+// 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
+ }
+}
--- /dev/null
+<?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>