MSVC 19.00.24215.1 generates wrong SSE/AVX mixed code with LTCG - by dmitry.azaraev

Status : 

 


3
0
Sign in
to vote
ID 3103806 Comments
Status Active Workarounds
Type Bug Repros 0
Opened 9/20/2016 3:26:23 PM
Access Restriction Public

Description

MSVC in LTCG mode generates unexpected code if object files mix SSE and AVX code, depening on object file order.

Issue originally was been reproduced and workaroundede with Chromium Embedded Framework: https://bitbucket.org/chromiumembedded/cef/issues/1999
(if you want to see full story), also contains reproduction example. Just now attached file still not appears here.

See details for reproduction steps.

PS: vs14-kb3165756.exe are installed, but it is no make any sense. Actual VS version is 14.0.25431.01 Update 3 but can't select it on this site.
Sign in to post a comment.
Posted by dmitry.azaraev on 10/11/2016 at 10:37 AM
Hello, Charles.

Thanks for pointing to source of issue, there is exactly program-wide ODR violation. And sorry for delay.

But... anyway something wrong happens behind the scene (i'm understand that there we hit in undefined behavior), but i'm should point again:

1. In case if we order SSE, then AVX - both ctors (and btw indexers also) are inlined and used module's instruction set - i.e. we obtain best optimized result for both cases.

2. In reverse order: something prevent to inline method... i'm feel that compiler can't inline avx code in sse code and feel violation, and compiler just cheats here: it is doesn't use wrong instructions in SSE module, but it calls generated method with AVX instructions.

My main concern: Compiler can generate ineffective and invalid code: no inlines, and additionally - it is violates instruction set. And there is happens absolutely *silently*. So unless we hit in invalid instruction exception - we doesn't known about hidden issue. It will be great if it is possible to somehow diagnose this situations. My feedback about this mainly.

My workaround: Reorder modules from SSE to AVX. This looks like currently works fine (but code still should be correct, original libraries also changes inlined implementations, but in worst case they will fallback to firstly declared implementation - SSE). Main advantage - that i'm doesn't need change any line of code.

About anonymous namespaces: Yep, this is can be used to workaround this reproduction example only. Original code contains 20K+ modules total. Using anonymous namespaces *will* bloat binary and additionally changes names in stacktraces what is most of times is unintended. Also pulling inner class in anonymous namespace is not enough: we should put in anonymous namespaces all declarations to top level (for example SkMatrix which uses Sk4f also should be in own namespaces), otherwise first definition of SkMatrix will be choosen, and we hit in same issue again, and it is hard to track (because it is can't be solved at library level). While header/near header-only classes designed to be transparent for users - using anonymous ns is inacceptable (IMO).

So actual resolution requires change code and/or do not mix instruction sets. But (hard IMO) while instruction set is implementation specific - compiler should care about them as it should: it is absolutely expected to have per-instruction set type implementation (generated code): not per module, per instruction set. Yep, some kind of back to C. I'm can't expect any kind of this, because it is states as UB, and again my feedback is only about lack of diagnosis, while unexpected/wrong code is generated.
Posted by Charles [MSFT] on 9/30/2016 at 12:25 AM
Dmitry,

This comes to ODR violation. Linker sees two instances of the same definition. Linker can pick any of them and usually picks the first one.

In this case, the constructor Sk4f has two different versions SSE and AVX. Both are not inlined in the caller functions (sse.obj, avx.obj). With the order "avx.obj, sse.obj", the avx version is picked by linker. That results sse.obj calls the avx code and crashing. On the other hand, if the constructor is inlined, or avx.obj calls SSE version, it works fine on avx supported hardware.

So from compiler/linker point of view, it is expected.

To workaround the problem, you can add namespace for Sk4f in the header. That will create two different definitions of the constructor. sse.obj and avx.obj modules will call the correct one respectively.

Charles Fu
Microsoft VC++ Team
Posted by Charles [MSFT] on 9/30/2016 at 12:25 AM
Dmitry,

This comes to ODR violation. Linker sees two instances of the same definition. Linker can pick any of them and usually picks the first one.

In this case, the constructor Sk4f has two different versions SSE and AVX. Both are not inlined in the caller functions (sse.obj, avx.obj). With the order "avx.obj, sse.obj", the avx version is picked by linker. That results sse.obj calls the avx code and crashing. On the other hand, if the constructor is inlined, or avx.obj calls SSE version, it works fine on avx supported hardware.

So from compiler/linker point of view, it is expected.

To workaround the problem, you can add namespace for Sk4f in the header. That will create two different definitions of the constructor. sse.obj and avx.obj modules will call the correct one respectively.

Charles Fu
Microsoft VC++ Team
Posted by Bruce Dawson2 on 9/28/2016 at 8:13 PM
Connect's "attach a file" functionality has been broken for most or all of a year. I don't know why.

Here are some useful concrete links regarding this bug in one place:
1. Reproduction example: https://bitbucket.org/chromiumembedded/cef/issues/attachments/1999/chromiumembedded/cef/1474399239.3/1999/vs2015u3-ltcg-bug-1.zip
2. Quick analysis: https://bitbucket.org/chromiumembedded/cef/issues/1999#comment-30763602
Posted by dmitry.azaraev on 9/27/2016 at 9:00 AM
I'm attach reproduction example here triple times. Files doesn't appears here.
If you want get reproduction example (and they still doesn't appear here), you can get it from https://bitbucket.org/chromiumembedded/cef/issues/1999 (vs2015u3-ltcg-bug-1.zip).
Posted by Microsoft on 9/20/2016 at 10:01 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If you require immediate assistance with this issue, please contact product support at http://support.microsoft.com/oas/default.aspx?prid=15825.