<div dir="ltr"><div dir="ltr">On Thu, 3 Dec 2020 at 13:55, Reid Kleckner via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">1. Re: funsigned-char, it seems to work for me:<div><br><div>$ cat t.cpp <br>static_assert((int)((char)255) == 255, "char should be unsigned");<br><br>$ clang -c --target=x86_64-windows-windows-gnu -funsigned-char t.cpp   <br></div><div># success</div><div><br></div><div>Removing the flag makes it fail.</div><div><br></div><div><br></div><div>2. The meaning of the "ABI" part of the triple</div><div><br></div><div>I had not encountered that CrossCompiling.rst document until today. This is what I see in the Triple.h document:</div><div>ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT<br></div><div>In the code, the fourth component is referred to as the "environment". The environment is kind of a catch-all extension of the triple, which normally has three components: ISA, vendor, OS. The environment allows some more target customization, and everyone uses it for different purposes. I think it's hard to come up with a unified theory of what the triple environment really is. As you can see, we encode the MSVC CRT version in there, because sometimes the backend needs to know it. Some targets have an object file format override in the environment. You can see this in triples that end in -elf or -macho.</div><div><br></div><div>So, to answer your question about what part of the triple controls the object file format, there's no real good answer. It's not a well designed piece of infrastructure. :( Mainly, though, it's the OS that defines the object file format.</div><div><br></div><div>For Windows, there are two main environments: msvc and gnu. Both use COFF objects, but with slightly different contents. Generally, for plain C code, VC link.exe can handle GNU COFF objects. However, if you start doing interesting things (C++, __attribute__((weak)), some other things) eventually you will run into some incompatibilities. If you plan to use the Visual C++ linker, I would recommend using the msvc environment.</div><div><br></div><div><br></div><div>3. __chkstk_ms<br><br></div><div>This is a good example of the ways that -gnu and -msvc change LLVM's behavior. __chkstk_ms is provided by mingw's version of libgcc, I believe. Using the gnu environment makes LLVM use this helper.</div><div><br></div><div>chkstk and chkst_ms touch all the stack pages, similar to GCC's -fstack-clash-protector feature. Making objects static moved them from the stack to globals, reducing your stack frame size, avoiding the need for this helper.</div><div><br></div><div>You could fix this issue by linking against LLVM's compiler-rt which provides both helpers.</div><div><br></div><div><br></div><div>4. fms-compatibility vs fms-extensions</div><div><br></div><div>The idea behind these options is that fms-compatibility is the set of compatibility hacks that we would prefer to avoid, and fms-extensions is the set of language extensions that fit in the language well. For example, fms-extensions should enable a variety of builtin intrinsic functions, like _InterlockedCompareExchange, __fastfail, __noop. It enables __declspec(align).</div><div><br></div><div>fms-compatibility usually has more to do with forcing the compiler to accept certain invalid C++ code patterns involving templates. However, in practice it controls far more than that.</div><div><br></div><div><br></div><div>5. Docs on -m* flags</div><div><br></div><div>Yeah, I don't know what to say. There isn't really a singular point of responsibility in the community for keeping the docs up to date, consistent, and easy to find. As you've seen, things tend to be pretty spotty. clang --help probably isn't the right place for in-depth documentation, but there should be some central place that we can hook everything into. We have a UsersManual, but even a single web page can't describe every feature of clang. It's certainly an area for improvement.</div></div></div></blockquote><div><br></div><div>In addition to the UsersManual, there's <a href="http://clang.llvm.org/docs/ClangCommandLineReference.html">http://clang.llvm.org/docs/ClangCommandLineReference.html</a>, which aims to be a complete listing of all the command line flags. It's generated from the .td file, so it shouldn't miss out any flags (except the ones that are specified as being hidden), but as you'll see, there is no documentation whatsoever for many of the flags, and in most cases this reference contains no information beyond what's in the terse `--help` output.</div><div><br></div><div>So that's far from ideal; it can at least answer the "what -m flags exist?" question, but not the follow-up question "what do they do?".</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>I think -m micro-architectural flags, in particular, are the kind of thing that gets added on a case-by-case basis without any documentation or review. Every architecture has its own world of options.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Nov 28, 2020 at 12:53 PM Javier Múgica via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi:<br>
<br>
After successfully and easily compiling a project in Windows with clang-cl I wanted to change the command to clang. clang itself lies in Linux (WSL 2.0) and the C library to be used is that of MSVC. Eventually I learned about the triple, but by that time I had almost succeeded. I run into several issues:<br>
<br>
|1.| (Seems a bug). -fno-signed-char (or -funsigned-char) is ignored depending on the triple settings:<br>
<br>
targeting Linux, default option for the triple   O.K.<br>
targeting Windows, x86_64-windows-windows-msvc<xx.xx.x>     O.K.<br>
targeting Windows, x86_64-windows-windows-gnu     wrong<br>
<br>
and there were some other combination where it was also wrong. The compiler insists in char being signed, which generates me hundreds of warnings.<br>
<br>
|2.| <abi> in the triple<br>
<br>
According to CrossCompilation.rst, "Finally, the ABI option is something that will pick default CPU/FPU,<br>
define the specific behaviour of your code (PCS, extensions), and also choose the correct library calls, etc."<br>
<br>
So, it seems it is not what defines the format of the generated object files (what I would expect given its "abi" name). Since I had already managed to make clang compile the sources by specifying the -isystem directories, and I wanted to avoid any windows related magic as much as possible, I tried to specify x86_64-windows-windows-none or x86_64-pc-windows-none, but "none" there, or "unknown" always got replaced by msvc19.11.0. Maybe it does not make sense to have the abi unknown? Therefore I finally compiled with x86_64-windows-windows-gnu, although gnu had nothing to do with my compilation.<br>
<br>
I would expect that the application binary interface specification on the command line (or elsewhere) is what would make llvm generate object files for either or other consumer, but having seen that specifying "gnu" there generates .obj files just as specifying "msvc"; i.e., object files that Windows' link program handles well, it seems it is not.<br>
<br>
So the question is: what in the triple is what makes the backend generate object files in one or the other format?<br>
<br>
Except for the architecture part of the triple, which is clear what it means, I have found the documentation for the other parts (when I at last could find it) unclear in what they change or determine in a compilation process.<br>
<br>
So, compiling with x86_64-windows-windows-gnu -fno-builtin -fms-compatibility -fshort-wchar -Wno-pointer-sign -fvisibility-ms-compat<br>
<br>
and a bunch of defines like -D _M_X64=100, everything runs fine and linking the objects from Windows, with its link command, works properly, just as if I had compiled with x86_64-windows-windows-msvc19.16.00, EXCEPT for the function <br>
<br>
___chk_stk_ms<br>
<br>
which the linker cannot find. This function is inserted by the compiler when a function requires a large amount of stack space. I solved this by declaring the problematic objects static, but I'd like to know why this happens.<br>
<br>
By the way, even without -fms-compatibility, just with -fdeclspec and some #defines in the code, I also succeeded in compiling.<br>
<br>
|4.| -fms-compatibility vs. -fms-extensions<br>
<br>
The help which is displayed by clang -help says<br>
<br>
  -fms-compatibility      Enable full Microsoft Visual C++ compatibility<br>
  -fms-extensions         Accept some non-standard constructs supported by the Microsoft compiler<br>
<br>
which is not very informative. Which one enables less stuff? Is one a superset of the other. "Enable full Microsoft Visual C++ compatibility" seems to imply that this indeed is a superset of the other, but considering that even compiling with clang-cl there are the options /Ze and /Za which enable o disable Microsoft extensions, one is lead to think that the -fms-extensions are beyond the compatibility provided by -fms-compatibility. What, then?<br>
<br>
|5.| -m... options.<br>
<br>
I know that once I have specified my architecture to be x86_64 there are options that can improve the performance of the binaries: "Once your target is specified, it's time to pick the hardware you'll<br>
be compiling to. For every architecture, a default set of CPU/FPU/ABI will be chosen, so you'll almost always have to change it via flags."<br>
Where can the available flags be found? If they are so important and can have such an impact on the program, why is the documentation for them so difficult to find? (Specially if you are working off-line as I use to).<br>
<br>
<br>
In general, it seems that a good, thought document explaining each of the parts of the "triple" AND what the determine in the compilation process, and those -m flags would be very welcome, and if clang -help would point where that documentation could be found that would be very helpful also. Just browse the internet for Q&A related to the triple, and you'll find that "official" explanations should definitely be easier to find.<br>
<br>
Thanks in advance<br>
<br>
-- Javier A. Múgica<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>