Skip to content

Commit

Permalink
Ensure that we don't try to constant fold BSF(0) or BSR(0) (#81516)
Browse files Browse the repository at this point in the history
* Ensure that we don't try to constant fold BSF(0) or BSR(0)

* Ensure the test returns 100 and has correct usings

* Apply formatting patch
  • Loading branch information
tannergooding authored Feb 2, 2023
1 parent 60fa29b commit 4354abd
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 8 deletions.
36 changes: 28 additions & 8 deletions src/coreclr/jit/valuenum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6121,40 +6121,60 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunUnary(
case NI_X86Base_BitScanForward:
{
assert(!varTypeIsSmall(type) && !varTypeIsLong(type));
int32_t value = GetConstantInt32(arg0VN);

int32_t value = GetConstantInt32(arg0VN);
uint32_t result = BitOperations::BitScanForward(static_cast<uint32_t>(value));
if (value == 0)
{
// bsf is undefined for 0
break;
}

uint32_t result = BitOperations::BitScanForward(static_cast<uint32_t>(value));
return VNForIntCon(static_cast<int32_t>(result));
}

case NI_X86Base_X64_BitScanForward:
{
assert(varTypeIsLong(type));
int64_t value = GetConstantInt64(arg0VN);

int64_t value = GetConstantInt64(arg0VN);
uint32_t result = BitOperations::BitScanForward(static_cast<uint64_t>(value));
if (value == 0)
{
// bsf is undefined for 0
break;
}

uint32_t result = BitOperations::BitScanForward(static_cast<uint64_t>(value));
return VNForLongCon(static_cast<int64_t>(result));
}

case NI_X86Base_BitScanReverse:
{
assert(!varTypeIsSmall(type) && !varTypeIsLong(type));
int32_t value = GetConstantInt32(arg0VN);

int32_t value = GetConstantInt32(arg0VN);
uint32_t result = BitOperations::BitScanReverse(static_cast<uint32_t>(value));
if (value == 0)
{
// bsr is undefined for 0
break;
}

uint32_t result = BitOperations::BitScanReverse(static_cast<uint32_t>(value));
return VNForIntCon(static_cast<int32_t>(result));
}

case NI_X86Base_X64_BitScanReverse:
{
assert(varTypeIsLong(type));
int64_t value = GetConstantInt64(arg0VN);

int64_t value = GetConstantInt64(arg0VN);
uint32_t result = BitOperations::BitScanReverse(static_cast<uint64_t>(value));
if (value == 0)
{
// bsr is undefined for 0
break;
}

uint32_t result = BitOperations::BitScanReverse(static_cast<uint64_t>(value));
return VNForLongCon(static_cast<int64_t>(result));
}
#endif // TARGET_XARCH
Expand Down
25 changes: 25 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_81460/Runtime_81460.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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.Numerics;
using System.Runtime.CompilerServices;

public static class FloatingPointHelper<TSelf>
where TSelf : IFloatingPoint<TSelf>
{
public static int GetExponentShortestBitLength(TSelf value)
=> value.GetExponentShortestBitLength();
}

class Runtime_81460
{
static int Main()
{
return (Test() == 0) ? 100 : 0;
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static int Test() =>
FloatingPointHelper<double>.GetExponentShortestBitLength(1.0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit 4354abd

Please sign in to comment.