{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/1616","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/1616/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/1616/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/1616/events","html_url":"https://github.com/dotnet/corefx/issues/1616","id":72828337,"number":1616,"title":"bug: Vector<long> extracting components with a literal leads to incorrect code gen.","user":{"login":"mburbea","id":213233,"avatar_url":"https://avatars.githubusercontent.com/u/213233?v=3","gravatar_id":"","url":"https://api.github.com/users/mburbea","html_url":"https://github.com/mburbea","followers_url":"https://api.github.com/users/mburbea/followers","following_url":"https://api.github.com/users/mburbea/following{/other_user}","gists_url":"https://api.github.com/users/mburbea/gists{/gist_id}","starred_url":"https://api.github.com/users/mburbea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mburbea/subscriptions","organizations_url":"https://api.github.com/users/mburbea/orgs","repos_url":"https://api.github.com/users/mburbea/repos","events_url":"https://api.github.com/users/mburbea/events{/privacy}","received_events_url":"https://api.github.com/users/mburbea/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-05-03T16:27:41Z","updated_at":"2015-05-12T20:17:35Z","closed_at":null,"body":"It appears that if you try to retrieve components of a `Vector<T>` with a constant something wrong is occurring and an incorrect code is generated.\r\nThis does not happen when extracting to an array, or when you use a variable (like say through a for-loop). This only happens when you extract literal components.\r\n\r\nHere is a simple reproduction.  This happened in VS2015 RC\r\n```csharp\r\n\r\n        static bool TestLiterals(Vector<long> vl)\r\n        {\r\n            var v = vl[0];\r\n            var v1 = vl[1];\r\n            var v2 = vl[2];\r\n            var v3 = vl[3];\r\n            return v != 0 || v1 != 0 || v2 != 0 || v3 != 0;\r\n            \r\n        }\r\n        static bool TestLoop(Vector<long> vl)\r\n        {\r\n            for(int i=0; i < Vector<long>.Count; i++)\r\n            {\r\n                var v = vl[i];\r\n                if (v != 0) return true;\r\n            }\r\n            return false;\r\n        }\r\n        static void Main(string[] args)\r\n        {\r\n            var array = new long[4] { 0, 0, 0, 1 };\r\n            var vector = new Vector<long>(array);\r\n            Console.WriteLine(Vector<long>.Count);\r\n            Console.WriteLine(TestLiterals(vector));\r\n            Console.WriteLine(TestLoop(vector));\r\n        }\r\n```\r\nOn my i5 broadwell chip it printed:\r\n```\r\n4\r\nFalse\r\nTrue\r\n```\r\nThis is very much the wrong result. The correct answer should be:\r\n```\r\n4\r\nTrue\r\nTrue\r\n```\r\nIt's pretty easy to see that both methods should yield the same result. Here is the assembly of the `testliteral` And the error becomes obvious.\r\n```\r\n**00007FFB1E086E20  vmovupd     ymm0,ymmword ptr [rcx]  \r\n00007FFB1E086E25  vmovd       rax,xmm0  **\r\n**00007FFB1E086E2A  vmovupd     ymm0,ymmword ptr [rcx]  \r\n00007FFB1E086E2F  vmovaps     ymm1,ymm0  \r\n00007FFB1E086E34  vpsrldq     ymm1,ymm1,8  \r\n00007FFB1E086E3A  vmovd       rdx,xmm1  **\r\n00007FFB1E086E3F  vmovupd     ymm0,ymmword ptr [rcx]  \r\n00007FFB1E086E44  vmovaps     ymm1,ymm0  \r\n00007FFB1E086E49  vpsrldq     ymm1,ymm1,10h  \r\n00007FFB1E086E4F  vmovd       r8,xmm1  \r\n00007FFB1E086E54  vmovupd     ymm0,ymmword ptr [rcx]  \r\n00007FFB1E086E59  vmovaps     ymm1,ymm0  \r\n00007FFB1E086E5E  vpsrldq     ymm1,ymm1,18h  \r\n00007FFB1E086E64  vmovd       rcx,xmm1  \r\n00007FFB1E086E69  or          rax,rdx  \r\n00007FFB1E086E6C  or          rax,r8  \r\n00007FFB1E086E6F  test        rax,rax  \r\n00007FFB1E086E72  jne         00007FFB1E086E7E  \r\n```\r\nThe input vector is in `ymm0` and it is using `ymm1` as its scratch buffer, first copying and then shifting the register by the offset but is trying to pull the component out of `xmm1`!\r\n\r\nIt appears that the compiler while having some concept of AVX registers, is still confused. \r\n"},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/101408523","html_url":"https://github.com/dotnet/corefx/issues/1616#issuecomment-101408523","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/1616","id":101408523,"user":{"login":"CarolEidt","id":2973870,"avatar_url":"https://avatars.githubusercontent.com/u/2973870?v=3","gravatar_id":"","url":"https://api.github.com/users/CarolEidt","html_url":"https://github.com/CarolEidt","followers_url":"https://api.github.com/users/CarolEidt/followers","following_url":"https://api.github.com/users/CarolEidt/following{/other_user}","gists_url":"https://api.github.com/users/CarolEidt/gists{/gist_id}","starred_url":"https://api.github.com/users/CarolEidt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CarolEidt/subscriptions","organizations_url":"https://api.github.com/users/CarolEidt/orgs","repos_url":"https://api.github.com/users/CarolEidt/repos","events_url":"https://api.github.com/users/CarolEidt/events{/privacy}","received_events_url":"https://api.github.com/users/CarolEidt/received_events","type":"User","site_admin":false},"created_at":"2015-05-12T20:17:35Z","updated_at":"2015-05-12T20:17:35Z","body":"This bug was fixed post-RC - though I'm not sure why the second example would work.  The bug was due to the fact that the vpsrldq instruction operates separately on the two halves of the ymm register - so the upper half must be first extracted to a lower half (xmm) register.  You can see the code for this here: https://github.com/dotnet/coreclr/blob/master/src/jit/simdcodegenxarch.cpp in the method CodeGen::genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode)."}}