[clang] [Clang] [Driver] Ensure `-fms-volatile` is set for x86 for `*-windows-msvc` triple on non cl driver modes (PR #107509)

Max Winkler via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 8 23:22:05 PDT 2024


MaxEW707 wrote:

> I don't have a very strong opinion. I find it surprising in that the clang driver is supposed to be gcc-compatible, and having to use `clang -fstrict-aliasing` (but only when targeting Windows) to get the default behavior looks a bit surprising.
> 
> (I agree it's a better default, but imho it's a better default on non-Windows too, and nobody found that convincing apparently ;))

I guess that depends on what the intention is with the driver vs the target triple. From the code and the [driver docs](https://clang.llvm.org/docs/DriverInternals.html) it appears the intention is that the driver interface should be agnostic to the triple.

I can understand the view point where that gets fuzzy with options like `strict-aliasing` which the c and c++ standards allow and most compilers do opt to do this optimization by default which I also agree that I prefer the opposite being the default instead :).
I can also understand the view point where projects compiling entirely with clang on windows would prefer more saner defaults from the toolchain than what msvc has as defaults.
For my statements below I do want to make it clear that I am referring to the target triple, `[arch]-windows-msvc`, and not the target triple, `[arch]-windows-gnu`. I would expect the `-gnu`, mingw, triple to have all the default gnu compiler behaviours.

My coworkers and I found it more confusing that we couldn't just build msvc compatible source files with `clang` out of the box with the correct `[arch]-windows-msvc` triple targeting msvc compatibility. Especially around options like `-fjmc` which until my previous PR would just error unless the driver mode was `cl`.
Part of this expectation comes from us internally treating clang as clang in our source code and in our custom build system. We only need to check if we are android clang, sony clang, apple clang, etc in rare cases in the code. Usually it is bugs that happen due to vendors branching clang some commits before the final public release so the version numbers are identical but the vendor clang is missing some bug fix commits.
Part of this expectation also comes from the [cross-compile](https://clang.llvm.org/docs/CrossCompilation.html#general-cross-compilation-options-in-clang) model of clang where we can build any target from any machine. We do have one team building a small win32 tool on Linux VMs (yes we ran into many issues with case insensitivity in the Windows headers but symlinks solve that :)). I wouldn't be surprised if we start looking at building more win32 code on Linux machines due to the easier management, the much lower process creation overhead and filesystem overhead compared to Windows which adds to build times on Windows builders.
I even worked at places where Linux builds were built on Windows with a packaged clang toolchain plus dependent libs. Games are a win32 shop first, less today overall, so building Linux server executables on Windows that you can run in WSL and debug from VS is a workflow many users are more familiar with when doing day to day dev. Plus you avoid the overhead of the even slower WSL filesystem when accessing your checked out code via the mountpoints into your Windows volumes.

Some targets today do enable non gcc options in the clang driver mode.
To be compatible with IBM XL, https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/AIX.cpp#L556, enables the xl pragma pack behaviour when the target triple is AIX.
Similarly the Sony targets enable `-fdeclspec` by default and also allow some Microsoft extensions hidden behind `-fms-extensions`, https://github.com/llvm/llvm-project/commit/fd4db5331e512d23d2d1c832065acbe226e7616d#diff-fabe5169278c853cdf933a1b8269d2e102e0f814d685e7cdde59f48731d28721L298.

In the `windows-msvc` target mode we also enable `-fdelayed-template-parsing` by default as does msvc, https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/Clang.cpp#L7306. If we are concerned about `-fms-volatile` and `-fstrict-aliasing` then I am assuming non conforming two phase lookup by default would also be a concern.
All of our code targeting msvc on pc sets `/permissive-` to get `/Zc:twoPhase`, https://learn.microsoft.com/en-us/cpp/build/reference/zc-twophase?view=msvc-170, conforming behaviour since newer Windows SDK headers are fixed to work under conforming behaviour.
Likewise in our build system we set `-fno-delayed-template-parsing` for code I am trying to move from msvc to clang to get the same conforming behaviour with the clang driver as with the cl driver on pc builds. Unfortunately some console builds still require non conforming behaviour due to system headers.

My point of view is if a user is building with the `-windows-msvc` target and thus using the Windows SDK headers, ATL headers, MFC headers, msvc stl, msvc headers provided by a VS Toolchain install, etc then I think we should conform to msvc's behaviour no matter what driver interface is used.

Side note I do think a lot of the msvc target code can be refactored into, [MSVCToolChain::addClangTargetOptions](https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/MSVC.cpp#L1018), as other target toolchains seem to do.

> For this patch here, I don't know if gcc even has a fms-volatile. If not, this here seems less surprising to me than the strict aliasing patch.

gcc does not have an equivalent `-fms-volatile` from memory and I also couldn't find anything similar from my spelunking of the gcc options.
gcc does however treat volatile load and stores as acquire and release when compiling for Itanium. I couldn't find a generic option to invoke this behviour on other architectures.

https://github.com/llvm/llvm-project/pull/107509


More information about the cfe-commits mailing list