diff options
author | Eugene Rozenfeld <erozen@microsoft.com> | 2015-11-11 19:15:55 -0800 |
---|---|---|
committer | Eugene Rozenfeld <erozen@microsoft.com> | 2015-11-11 19:15:55 -0800 |
commit | 76b0ffaa1d61c14c510bd1fae9b12df4f3e2d3f2 (patch) | |
tree | bc579d76cfee9fc39f24ed7ca9b00b18350f6dbd /tests/src/JIT/CodeGenBringUpTests/Rotate.cs | |
parent | 7092c6432877fb18e9bcd331c5504317fb5eccee (diff) | |
download | coreclr-76b0ffaa1d61c14c510bd1fae9b12df4f3e2d3f2.tar.gz coreclr-76b0ffaa1d61c14c510bd1fae9b12df4f3e2d3f2.tar.bz2 coreclr-76b0ffaa1d61c14c510bd1fae9b12df4f3e2d3f2.zip |
Implement improvements for rotation matching.
1. Recognize patterns with XOR instead of OR, e.g., (x << 5) ^ (x >> 27).
2. Recognize patterns with instance or static fields and ref params.
Only GTF_PERSISTENT_SIDE_EFFECTS (i.e., calls and assignments) and
GTF_ORDER_SIDEEFF (i.e., volatile accesses) prevent tree matching.
Before this change we used GTF_ALL_EFFECT.
Diffstat (limited to 'tests/src/JIT/CodeGenBringUpTests/Rotate.cs')
-rw-r--r-- | tests/src/JIT/CodeGenBringUpTests/Rotate.cs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/tests/src/JIT/CodeGenBringUpTests/Rotate.cs b/tests/src/JIT/CodeGenBringUpTests/Rotate.cs index 2218741a38..936718ce50 100644 --- a/tests/src/JIT/CodeGenBringUpTests/Rotate.cs +++ b/tests/src/JIT/CodeGenBringUpTests/Rotate.cs @@ -8,6 +8,12 @@ using System.Runtime.CompilerServices; public class Test { + static ulong s_field; + + ulong field; + + volatile uint volatile_field; + [MethodImpl(MethodImplOptions.NoInlining)] static uint rol32(uint value, int amount) { @@ -47,6 +53,12 @@ public class Test } [MethodImpl(MethodImplOptions.NoInlining)] + static uint rol32xor(uint value, int amount) + { + return (value << amount) ^ (value >> (32 - amount)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] static uint ror32(uint value, int amount) { return (value << ((32 - amount))) | (value >> amount); @@ -67,6 +79,12 @@ public class Test } [MethodImpl(MethodImplOptions.NoInlining)] + uint ror32vfield(int amount) + { + return (volatile_field << ((32 - amount))) | (volatile_field >> amount); + } + + [MethodImpl(MethodImplOptions.NoInlining)] static ulong rol64(ulong value, int amount) { return (value << amount) | (value >> (64 - amount)); @@ -87,6 +105,12 @@ public class Test } [MethodImpl(MethodImplOptions.NoInlining)] + ulong rol64field(int amount) + { + return (field << amount) | (field >> (64 - amount)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] static ulong ror64(ulong value, int amount) { return (value << (64 - amount)) | (value >> amount); @@ -107,6 +131,12 @@ public class Test } [MethodImpl(MethodImplOptions.NoInlining)] + static ulong ror64sfield(int amount) + { + return (s_field << (64 - amount)) | (s_field >> amount); + } + + [MethodImpl(MethodImplOptions.NoInlining)] static uint rol32_call(uint value, int amount) { return (foo(value) << amount) | (foo(value) >> (32 - amount)); @@ -136,11 +166,19 @@ public class Test return (value >> 10) | (value << 5); } + Test(ulong i, uint j) + { + field = i; + volatile_field = j; + } + public static int Main() { const int Pass = 100; const int Fail = -1; + s_field = 0x123456789abcdef; + if (rol32(0x12345678, 16) != 0x56781234) { return Fail; @@ -231,6 +269,28 @@ public class Test return Fail; } + if (rol32xor(0x12345678, 16) != 0x56781234) + { + return Fail; + } + + if (ror64sfield(7) != 0xde02468acf13579b) + { + return Fail; + } + + Test test = new Test(0x123456789abcdef, 0x12345678); + + if (test.rol64field(11) != 0x1a2b3c4d5e6f7809) + { + return Fail; + } + + if (test.ror32vfield(3) != 0x2468acf) + { + return Fail; + } + return Pass; } } |