-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Ensure Max/Min for floating-point on x86/x64 are not handled as commutative #75683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18659,10 +18659,45 @@ bool GenTree::isCommutativeHWIntrinsic() const | |
| assert(gtOper == GT_HWINTRINSIC); | ||
|
|
||
| #ifdef TARGET_XARCH | ||
| return HWIntrinsicInfo::IsCommutative(AsHWIntrinsic()->GetHWIntrinsicId()); | ||
| #else | ||
| return false; | ||
| const GenTreeHWIntrinsic* node = AsHWIntrinsic(); | ||
| NamedIntrinsic id = node->GetHWIntrinsicId(); | ||
|
|
||
| if (HWIntrinsicInfo::IsCommutative(id)) | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| if (HWIntrinsicInfo::IsMaybeCommutative(id)) | ||
| { | ||
| switch (id) | ||
| { | ||
| case NI_SSE_Max: | ||
| case NI_SSE_Min: | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| case NI_SSE2_Max: | ||
| case NI_SSE2_Min: | ||
| { | ||
| return !varTypeIsFloating(node->GetSimdBaseType()); | ||
| } | ||
|
|
||
| case NI_AVX_Max: | ||
| case NI_AVX_Min: | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| default: | ||
| { | ||
| unreached(); | ||
| } | ||
| } | ||
| } | ||
| #endif // TARGET_XARCH | ||
|
|
||
| return false; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Notably Arm64 is returning constant false and it shouldn't be. Given this needs to be backported to .NET 7, I didn't "fix" this (its not a correctness bug, just a case where we might generate "worse" codegen). I plan on putting up a follow up PR to ensure Arm64 intrinsics are handled as commutative (they are already correctly marked as required, this function returning false is the blocker for them) |
||
| } | ||
|
|
||
| bool GenTree::isContainableHWIntrinsic() const | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System.Runtime.Intrinsics; | ||
| using System.Runtime.Intrinsics.X86; | ||
|
|
||
| public unsafe class ImageSharp_2117 | ||
| { | ||
| public static int Main(string[] args) | ||
| { | ||
| if (Sse.IsSupported) | ||
| { | ||
| Vector128<float> fnan = Vector128.Create(float.NaN); | ||
| Vector128<float> res1 = Sse.Max(Sse.LoadVector128((float*)(&fnan)), Vector128<float>.Zero); | ||
| Vector128<float> res2 = Sse.Min(Sse.LoadVector128((float*)(&fnan)), Vector128<float>.Zero); | ||
|
|
||
| if (float.IsNaN(res1[0]) || float.IsNaN(res2[0])) | ||
| { | ||
| return 0; | ||
| } | ||
| } | ||
|
|
||
| if (Sse2.IsSupported) | ||
| { | ||
| Vector128<double> dnan = Vector128.Create(double.NaN); | ||
| Vector128<double> res3 = Sse2.Max(Sse2.LoadVector128((double*)(&dnan)), Vector128<double>.Zero); | ||
| Vector128<double> res4 = Sse2.Min(Sse2.LoadVector128((double*)(&dnan)), Vector128<double>.Zero); | ||
|
|
||
| if (double.IsNaN(res3[0]) || double.IsNaN(res4[0])) | ||
| { | ||
| return 0; | ||
| } | ||
| } | ||
|
|
||
| return 100; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <AllowUnsafeBlocks>True</AllowUnsafeBlocks> | ||
| </PropertyGroup> | ||
| <PropertyGroup> | ||
| <DebugType>None</DebugType> | ||
| <Optimize>True</Optimize> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <Compile Include="$(MSBuildProjectName).cs" /> | ||
| </ItemGroup> | ||
| </Project> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've kept this "simple" since we need to backport into .NET 7.
It isn't just a "return false", however, because we will want to specially handle the case in .NET 8 since certain scenarios can be commutative and this makes the follow up PR significantly simpler.