From da6ed1197abcb1be420351af1bb3758de6048c8f Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Tue, 26 Mar 2019 16:13:40 -0700 Subject: Handle addressing modes for HW intrinsics (#22944) * Handle addressing modes for HW intrinsics Also, eliminate some places where the code size estimates were over-estimating. Contribute to #19550 Fix #19521 --- .../JitBlue/GitHub_19550/GitHub_19550.cs | 143 +++++++++++++++++++++ .../JitBlue/GitHub_19550/GitHub_19550.csproj | 16 +++ 2 files changed, 159 insertions(+) create mode 100644 tests/src/JIT/Regression/JitBlue/GitHub_19550/GitHub_19550.cs create mode 100644 tests/src/JIT/Regression/JitBlue/GitHub_19550/GitHub_19550.csproj (limited to 'tests/src/JIT') diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_19550/GitHub_19550.cs b/tests/src/JIT/Regression/JitBlue/GitHub_19550/GitHub_19550.cs new file mode 100644 index 0000000000..0e8f03c977 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_19550/GitHub_19550.cs @@ -0,0 +1,143 @@ +// 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. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System.Threading; + +// Test folding of addressing expressions + +public class Program +{ + struct S + { + public float f0; + public float f1; + public float f2; + public float f3; + public float f4; + public float f5; + public float f6; + public float f7; + public float f8; + public float f9; + public float f10; + public float f11; + public float f12; + public float f13; + public float f14; + public float f15; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int Test(ref S s, Vector128 v, int offset) + { + int returnVal = 100; + + if (Sse2.IsSupported) + { + fixed (float* p = &s.f0) + { + // We need an address aligned on 16 bytes, so we need to add a *float* offset to get there. + int alignmentOffset = (0x10 - ((int)p & 0xc)) >> 2; + try + { + // This is the aligned case. + // We're going to store a scalar at an offset of 2 from the aligned location. + // As it happens, we know that the struct has been initialized to all zeros, + // and the vector passed in was all ones, so now we have a one at offset 2. + Sse2.StoreScalar(p + alignmentOffset + 2, Sse2.Subtract(v, Sse2.LoadAlignedVector128(p + offset + alignmentOffset + 4))); + + // Now do a load from the aligned location. + // That should give us {0, 0, 1, 0}. + Vector128 v2; + if (Sse41.IsSupported) + { + v2 = Sse41.LoadAlignedVector128NonTemporal((byte*)(p + alignmentOffset)).AsSingle(); + } + else + { + v2 = Sse2.LoadVector128((byte*)(p + alignmentOffset)).AsSingle(); + } + if (!v2.Equals(Vector128.Create(0.0F, 0.0F, 1.0F, 0.0F))) + { + Console.WriteLine("Aligned case FAILED: v2 = " + v2); + returnVal = -1; + } + + // This is the unaligned case. The value we're loading to subtract is one element earlier than what we just stored. + // So we're doing { 1, 1, 1, 1 } - { 0, 1, 0, 0 } = { 1, 0, 1, 1 } + Sse2.Store(p + alignmentOffset + 1, Sse2.Subtract(v, Sse2.LoadVector128(p + offset + alignmentOffset + 1))); + // Now do an unaligned load from that location. + v2 = Sse2.LoadVector128(p + alignmentOffset + 1); + if (!v2.Equals(Vector128.Create(1.0F, 0.0F, 1.0F, 1.0F))) + { + Console.WriteLine("Unaligned case FAILED: v2 = " + v2); + returnVal = -1; + } + + } + catch (Exception e) + { + Console.WriteLine("Unexpected exception: " + e.Message); + returnVal = -1; + } + } + } + return returnVal; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe int Test256(ref S s, Vector256 v, int offset) + { + int returnVal = 100; + if (Avx.IsSupported) + { + // offset must be a multiple of the vector size in floats. + offset &= ~3; + fixed (float* p = &s.f0) + { + try + { + Avx.Store(p + 1, Avx.Subtract(v, Avx.LoadVector256(p + offset + 1))); + Vector256 v2 = Avx.LoadVector256(p + 1); + if (!v2.Equals(v)) + { + Console.WriteLine("Vector256 case FAILED: v = " + v + ", v2 = " + v2); + returnVal = -1; + } + } + catch (Exception e) + { + Console.WriteLine("Unexpected exception: " + e.Message); + returnVal = -1; + } + } + } + return returnVal; + } + + static int Main() + { + S s = new S(); + Vector128 v = Vector128.Create(1.0F); + int returnVal = Test(ref s, v, 0); + if (returnVal != 100) + { + Console.WriteLine("Vector128 test failed."); + } + + // Get a new vector initialized to zeros. + S s2 = new S(); + Vector256 v2 = Vector256.Create(1.0F); + if (Test256(ref s2, v2, 4) != 100) + { + Console.WriteLine("Vector256 test failed."); + returnVal = -1; + } + return returnVal; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_19550/GitHub_19550.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_19550/GitHub_19550.csproj new file mode 100644 index 0000000000..1ef998940b --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_19550/GitHub_19550.csproj @@ -0,0 +1,16 @@ + + + + + $(MSBuildProjectName) + Exe + None + True + True + + + + + + + -- cgit v1.2.3