This define should correspond to CMPXCHG16B being available which requires 64-bit mode.
I checked and gcc also seems to only define this in 64-bit mode.
Differential D59287
[X86] Only define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 in 64-bit mode. craig.topper on Mar 12 2019, 10:52 PM. Authored by
Details This define should correspond to CMPXCHG16B being available which requires 64-bit mode. I checked and gcc also seems to only define this in 64-bit mode.
Diff Detail
Event TimelineComment Actions I don't think this is quite right: CX16 is literally "I have cmpxchg16b". In clang/lib/Basic/Targets/X86.h we do: void setMaxAtomicWidth() override { if (hasFeature("cx16")) MaxAtomicInlineWidth = 128; } Your change makes it inconsistent. We also have HasCX16 which should be kept consistent. The problem seems to be that cx16 can be set for 32-bit targets. Comment Actions Isn’t that setMaxAtomicWidth in the x86-64 derived class? As far as preventing “cx16” from being set in 32-bit mode, we’ll need to check the behavior of CPUID in 32-bit mode or -march=native might still end up setting it. Comment Actions Right you are!
What I want to make sure is that your fix to the macro (which seems correct!) doesn't diverge from what the rest LLVM ends up doing with atomics. i.e. the macro says "no cmpxchg16b" but somehow codegen does generate it. Comment Actions Most if not all of the test cases in test/CodeGen/X86/atomic128.ll fail with a fatal error if you run it in 32-bit mode with -mattr=+cx16 Looks like the backend is also bad at checking 64 bit mode. Comment Actions So you're saying we're consistent, but in a bad way? It seems like an i386 target just shouldn't be allowed to set cx16, no? Comment Actions Is this ok with the backend fixed? Or do you want me factor this into HasCX16 which I think is only used by the defineMacro and the return for hasFeature("cx16")? And I think hasFeature("cx16") is only used by that getMaxAtomicWidth() code which is only called on 64 bit. Or we could maybe ignore "cx16" in setFeatureEnabled on 32 bit targets? But I think that would break always_inline on a target attribute with cx16 in 32 bit mode which gcc does allow. https://godbolt.org/z/TW985s Comment Actions This is definitely better.
I'm not sure. Does clang ever error out when you have inconsistent platform features and arch on the command line? That seems like what we should be doing here, no? Comment Actions I think the only error we have for X86 is trying to use a -march for a cpu that only supports 32 bit but compiling 64 bit code. I dont' think we can error for -mcx16 on a 32-bit target. For -march=native, the driver will call getHostCPUFeatures and get a list of features. As far as I can tell CPUID will report cx16 is supported even in 32-bit mode if the host CPU supports it in 64-bit mode. The driver will pass the list of features returned by getHostCPUFeatures onto the command line of the cc1 invocation. Those command line options will then be fed to initFeatureMap/setFeatureEnabled. We don't have the information to distinquish that from the user passing -mcx16. -mcx16 is intercepted by the driver and passed to cc1 in a similar way. I don't think we can filter cx16 from getHostCPUFeatures in 32-bit mode since the host might be running in 32-bit mode, but we could be passing -m64 to the compiler. So I don't think getHostCPUFeatures can look at the current operating mode of the CPU. I guess we could error for -mcx16 in the driver itself. But due to march native we'd still have to protect the code in cc1. Unless we also had the driver filter the output of getHostCPUFeatures before passing to cc1. Which if we did that then we probably could error from initFeatureMap/setFeatureEnabled. But gcc doesn't error for any use of cx16 in 32-bit mode so might be bad for compatibility anyway? Comment Actions OK, that seems unfortunate but unlikely and consistency terrible with GCC. Let's do it. Comment Actions I agree that its not great, but I don't think we're going to do much better - and matching gcc behaviours does make sense here. |