You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Clang is structured in a way that makes it hard to correctly initialize the target ABI for macOS M1 targets. Clang itself addresses the issue in Driver::BuildCompilation, where it sets a -target-abi flag if necessary to correctly initialize the ABI. However, clients of Clang that use the CompilerInvocation::CreateFromArgs entry point (or other, lower-level entry points) have no good way to get access to this setting, without either parsing the output of Driver::BuildCompilation or hard-coding it themselves. Such clients include LLDB and Terra (https://terralang.org/).
See terralang/terra#605 for an example of how this has caused miscompilations in Terra.
Root Cause Analysis
Clang's AArch64TargetInfo initializes an ABI of aapcs by default:
You can scan the rest of the file for darwinpcs. You won't find it. Despite having (apparent) customizations for Darwin, this file does not know how to properly initialize the ABI for Darwin AArch64 targets.
To avoid miscompilations (especially with varargs), a value of darwinpcs is required. Clang sets this value in RenderAArch64ABI, which is called transitively by Driver::BuildCompilation.
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
ABIName = A->getValue();
elseif (Triple.isOSDarwin())
ABIName = "darwinpcs";
else
ABIName = "aapcs";
CmdArgs.push_back("-target-abi");
CmdArgs.push_back(ABIName);
}
As you can see in the code above, this value is not stored anywhere in the ToolChain. It is only stored in CmdArgs, which makes its way (eventually) into the arguments for a job constructed by Driver::BuildCompilation. Therefore, clients that use the CompilerInvocation::CreateFromArgs entry point do not take advantage of any of this logic, and have to find a way to pass the -target-abi flag themselves.
Impact
Clang itself works fine because it initializes the -target-abi flag via Driver::BuildCompilation.
However, clients of Clang that use CompilerInvocation::CreateFromArgs (or other, lower-level entry points) have no reasonable way to access this flag. The best that can be done at the moment is to run Driver::BuildCompilation, find the -cc1 job, and look through the flags for -target-abi. There is not even a helper method on Compilation or ToolChain to help fish out this information based on what Driver::BuildCompilation returns.
Reproduction
Because it requires a client of Clang other than Clang itself, the only way to reproduce is to build a Clang client. Terra as of commit f46c5cabd13632417d382e27d35b91f8eac923a4 is sufficient for this purpose, and works with LLVM 14. A minimal reproducer can be found at terralang/terra#605, along with stack traces and code analysis.
It is likely (though I have not tested this) that writing varargs code in LLDB on macOS M1 would trigger the same issue.
The text was updated successfully, but these errors were encountered:
Clang is structured in a way that makes it hard to correctly initialize the target ABI for macOS M1 targets. Clang itself addresses the issue in
Driver::BuildCompilation
, where it sets a-target-abi
flag if necessary to correctly initialize the ABI. However, clients of Clang that use theCompilerInvocation::CreateFromArgs
entry point (or other, lower-level entry points) have no good way to get access to this setting, without either parsing the output ofDriver::BuildCompilation
or hard-coding it themselves. Such clients include LLDB and Terra (https://terralang.org/).See terralang/terra#605 for an example of how this has caused miscompilations in Terra.
Root Cause Analysis
Clang's AArch64TargetInfo initializes an ABI of
aapcs
by default:llvm-project/clang/lib/Basic/Targets/AArch64.cpp
Line 66 in e05edb1
You can scan the rest of the file for
darwinpcs
. You won't find it. Despite having (apparent) customizations for Darwin, this file does not know how to properly initialize the ABI for Darwin AArch64 targets.To avoid miscompilations (especially with varargs), a value of
darwinpcs
is required. Clang sets this value inRenderAArch64ABI
, which is called transitively byDriver::BuildCompilation
.llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
Lines 1842 to 1854 in e05edb1
As you can see in the code above, this value is not stored anywhere in the
ToolChain
. It is only stored inCmdArgs
, which makes its way (eventually) into the arguments for a job constructed byDriver::BuildCompilation
. Therefore, clients that use theCompilerInvocation::CreateFromArgs
entry point do not take advantage of any of this logic, and have to find a way to pass the-target-abi
flag themselves.Impact
Clang itself works fine because it initializes the
-target-abi
flag viaDriver::BuildCompilation
.However, clients of Clang that use
CompilerInvocation::CreateFromArgs
(or other, lower-level entry points) have no reasonable way to access this flag. The best that can be done at the moment is to runDriver::BuildCompilation
, find the-cc1
job, and look through the flags for-target-abi
. There is not even a helper method onCompilation
orToolChain
to help fish out this information based on whatDriver::BuildCompilation
returns.Reproduction
Because it requires a client of Clang other than Clang itself, the only way to reproduce is to build a Clang client. Terra as of commit f46c5cabd13632417d382e27d35b91f8eac923a4 is sufficient for this purpose, and works with LLVM 14. A minimal reproducer can be found at terralang/terra#605, along with stack traces and code analysis.
It is likely (though I have not tested this) that writing varargs code in LLDB on macOS M1 would trigger the same issue.
The text was updated successfully, but these errors were encountered: