[cfe-dev] clang not observing -fno-signed-char, and other triple realted issues
Richard Smith via cfe-dev
cfe-dev at lists.llvm.org
Thu Dec 3 14:05:33 PST 2020
On Thu, 3 Dec 2020 at 13:55, Reid Kleckner via cfe-dev <
cfe-dev at lists.llvm.org> wrote:
> 1. Re: funsigned-char, it seems to work for me:
> $ cat t.cpp
> static_assert((int)((char)255) == 255, "char should be unsigned");
> $ clang -c --target=x86_64-windows-windows-gnu -funsigned-char t.cpp
> # success
> Removing the flag makes it fail.
> 2. The meaning of the "ABI" part of the triple
> I had not encountered that CrossCompiling.rst document until today. This
> is what I see in the Triple.h document:
> 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.
> 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.
> 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.
> 3. __chkstk_ms
> 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.
> 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.
> You could fix this issue by linking against LLVM's compiler-rt which
> provides both helpers.
> 4. fms-compatibility vs fms-extensions
> 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
> 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.
> 5. Docs on -m* flags
> 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.
In addition to the UsersManual, there's
http://clang.llvm.org/docs/ClangCommandLineReference.html, 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.
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?".
> 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.
> On Sat, Nov 28, 2020 at 12:53 PM Javier Múgica via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>> 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:
>> |1.| (Seems a bug). -fno-signed-char (or -funsigned-char) is ignored
>> depending on the triple settings:
>> targeting Linux, default option for the triple O.K.
>> targeting Windows, x86_64-windows-windows-msvc<xx.xx.x> O.K.
>> targeting Windows, x86_64-windows-windows-gnu wrong
>> and there were some other combination where it was also wrong. The
>> compiler insists in char being signed, which generates me hundreds of
>> |2.| <abi> in the triple
>> According to CrossCompilation.rst, "Finally, the ABI option is something
>> that will pick default CPU/FPU,
>> define the specific behaviour of your code (PCS, extensions), and also
>> choose the correct library calls, etc."
>> 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.
>> 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.
>> So the question is: what in the triple is what makes the backend generate
>> object files in one or the other format?
>> 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
>> So, compiling with x86_64-windows-windows-gnu -fno-builtin
>> -fms-compatibility -fshort-wchar -Wno-pointer-sign -fvisibility-ms-compat
>> 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
>> 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
>> By the way, even without -fms-compatibility, just with -fdeclspec and
>> some #defines in the code, I also succeeded in compiling.
>> |4.| -fms-compatibility vs. -fms-extensions
>> The help which is displayed by clang -help says
>> -fms-compatibility Enable full Microsoft Visual C++ compatibility
>> -fms-extensions Accept some non-standard constructs supported
>> by the Microsoft compiler
>> 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?
>> |5.| -m... options.
>> 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
>> 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."
>> 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).
>> 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.
>> Thanks in advance
>> -- Javier A. Múgica
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the cfe-dev