Skip to content

Commit 464b46a

Browse files
[clang][CodeGen][X86_64] Honor per-function AVX ABI in C/C++ call paths, maintain old psABI for PlayStation. (#193298)
Fixes #64706 Wire per function x86 AVX ABI level into CodeGen arrangement methods so __attribute(__target("avx"))) / __attribute(__target("avx512f"))) on methods, ctors, and free-functions affects ABI lowering consistently. Specifically: - Added X86AVXABILevel member to CGFunctionInfo. - Populated X86AVXABILevel member in CGFunctionInfo objects via arrangement methods declared in CodeGenTypes.h. - Respect CGFunctionInfo AVX Level in X86_64ABIInfo::computeInfo. - Add/extend regression tests for: - free-function target-attribute AVX ABI lowering - C++ method/ctor target-attribute AVX ABI lowering - PS4/PS5 legacy ABI behavior (no per-function AVX ABI change) --------- Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
1 parent b9869c8 commit 464b46a

28 files changed

Lines changed: 627 additions & 124 deletions

clang/docs/ReleaseNotes.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
5050

5151
### ABI Changes in This Version
5252

53+
- Except on PlayStation, Clang now derives the x86-64 System V AVX ABI level
54+
for 256- and 512-bit vector arguments and returns from effective per-function
55+
target features. Features and `arch=` CPUs that imply AVX or AVX512F are
56+
honored, and calls use the caller's features, matching GCC. Per-function
57+
features cannot lower the translation-unit ABI level;
58+
`-fclang-abi-compat=23` restores the previous behavior. (#GH193298)
59+
5360
### AST Dumping Potentially Breaking Changes
5461

5562
### Clang Frontend Potentially Breaking Changes

clang/include/clang/Basic/ABIVersions.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ ABI_VER_MAJOR(21)
140140
/// local classes as nested-name entities instead of local-name entities.
141141
ABI_VER_MAJOR(22)
142142

143+
/// Attempt to be ABI-compatible with code generated by Clang 23.0.x.
144+
/// This causes clang to:
145+
/// - Ignore per-function target attributes when determining the x86 AVX ABI
146+
/// level.
147+
ABI_VER_MAJOR(23)
148+
143149
/// Conform to the underlying platform's C and C++ ABIs as closely as we can.
144150
ABI_VER_LATEST(Latest)
145151

clang/include/clang/Basic/LangOptions.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ LANGOPT(ForceEmitVTables, 1, 0, NotCompatible, "whether to emit all vtables")
426426
LANGOPT(AllowEditorPlaceholders, 1, 0, Benign,
427427
"allow editor placeholders in source")
428428

429-
ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest, NotCompatible,
429+
ENUM_LANGOPT(ClangABICompat, ClangABI, 5, ClangABI::Latest, NotCompatible,
430430
"version of Clang that we should attempt to be ABI-compatible "
431431
"with")
432432

clang/include/clang/CodeGen/CGFunctionInfo.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@
1717

1818
#include "clang/AST/CanonicalType.h"
1919
#include "clang/AST/CharUnits.h"
20-
#include "clang/AST/Decl.h"
2120
#include "clang/AST/Type.h"
22-
#include "llvm/IR/DerivedTypes.h"
2321
#include "llvm/ADT/FoldingSet.h"
22+
#include "llvm/IR/DerivedTypes.h"
2423
#include "llvm/Support/TrailingObjects.h"
2524
#include <cassert>
2625

@@ -653,6 +652,10 @@ class CGFunctionInfo final
653652
/// Log 2 of the maximum vector width.
654653
unsigned MaxVectorWidth : 4;
655654

655+
/// X86 AVX Level, can be different from global / module level AVX level
656+
/// because of target attributes.
657+
unsigned X86ABIAVXLevel = 0;
658+
656659
RequiredArgs Required;
657660

658661
/// The struct representing all arguments passed in memory. Only used when
@@ -683,7 +686,8 @@ class CGFunctionInfo final
683686
public:
684687
static CGFunctionInfo *
685688
create(unsigned llvmCC, bool instanceMethod, bool chainCall,
686-
bool delegateCall, const FunctionType::ExtInfo &extInfo,
689+
bool delegateCall, unsigned X86ABIAVXLevel,
690+
const FunctionType::ExtInfo &extInfo,
687691
ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
688692
ArrayRef<CanQualType> argTypes, RequiredArgs required);
689693
void operator delete(void *p) { ::operator delete(p); }
@@ -809,6 +813,8 @@ class CGFunctionInfo final
809813
MaxVectorWidth = llvm::countr_zero(Width) + 1;
810814
}
811815

816+
unsigned getX86ABIAVXLevel() const { return X86ABIAVXLevel; }
817+
812818
void Profile(llvm::FoldingSetNodeID &ID) {
813819
ID.AddInteger(getASTCallingConvention());
814820
ID.AddBoolean(InstanceMethod);
@@ -821,6 +827,7 @@ class CGFunctionInfo final
821827
ID.AddInteger(RegParm);
822828
ID.AddBoolean(NoCfCheck);
823829
ID.AddBoolean(CmseNSCall);
830+
ID.AddInteger(X86ABIAVXLevel);
824831
ID.AddInteger(Required.getOpaqueData());
825832
ID.AddBoolean(HasExtParameterInfos);
826833
if (HasExtParameterInfos) {
@@ -833,6 +840,7 @@ class CGFunctionInfo final
833840
}
834841
static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
835842
bool ChainCall, bool IsDelegateCall,
843+
unsigned X86ABIAVXLevel,
836844
const FunctionType::ExtInfo &info,
837845
ArrayRef<ExtParameterInfo> paramInfos,
838846
RequiredArgs required, CanQualType resultType,
@@ -848,6 +856,7 @@ class CGFunctionInfo final
848856
ID.AddInteger(info.getRegParm());
849857
ID.AddBoolean(info.getNoCfCheck());
850858
ID.AddBoolean(info.getCmseNSCall());
859+
ID.AddInteger(X86ABIAVXLevel);
851860
ID.AddInteger(required.getOpaqueData());
852861
ID.AddBoolean(!paramInfos.empty());
853862
if (!paramInfos.empty()) {

clang/include/clang/CodeGen/CodeGenABITypes.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,22 @@ const CGFunctionInfo &
8181
arrangeCXXMethodCall(CodeGenModule &CGM, CanQualType returnType,
8282
ArrayRef<CanQualType> argTypes, FunctionType::ExtInfo info,
8383
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
84-
RequiredArgs args);
84+
RequiredArgs args, const FunctionDecl *CallerFD);
8585

8686
const CGFunctionInfo &arrangeFreeFunctionCall(
8787
CodeGenModule &CGM, CanQualType returnType, ArrayRef<CanQualType> argTypes,
8888
FunctionType::ExtInfo info,
89-
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
90-
RequiredArgs args);
89+
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos, RequiredArgs args,
90+
const FunctionDecl *CallerFD);
9191

9292
// An overload with an empty `paramInfos`
9393
inline const CGFunctionInfo &
9494
arrangeFreeFunctionCall(CodeGenModule &CGM, CanQualType returnType,
9595
ArrayRef<CanQualType> argTypes,
96-
FunctionType::ExtInfo info, RequiredArgs args) {
97-
return arrangeFreeFunctionCall(CGM, returnType, argTypes, info, {}, args);
96+
FunctionType::ExtInfo info, RequiredArgs args,
97+
const FunctionDecl *CallerFD) {
98+
return arrangeFreeFunctionCall(CGM, returnType, argTypes, info, {}, args,
99+
CallerFD);
98100
}
99101

100102
/// Returns the implicit arguments to add to a complete, non-delegating C++

clang/lib/CodeGen/ABIInfo.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class FixedVectorType;
2626
namespace clang {
2727
class ASTContext;
2828
class CodeGenOptions;
29+
class FunctionDecl;
2930
class TargetInfo;
3031

3132
namespace CodeGen {
@@ -69,6 +70,14 @@ class ABIInfo {
6970
/// functions.
7071
llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; }
7172

73+
// Get X86ABIAVXLevel for the given FunctionDecl and ExtInfo.
74+
// This can be different than the global / module level X86ABIAVXLevel
75+
// due to function attributes.
76+
virtual unsigned getX86ABIAVXLevel(const FunctionDecl *,
77+
const FunctionType::ExtInfo &) const {
78+
return 0;
79+
}
80+
7281
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
7382

7483
/// EmitVAArg - Emit the target dependent code to load a value of

clang/lib/CodeGen/CGCUDARuntime.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ static llvm::Value *emitGetParamBuf(CodeGenFunction &CGF,
5353
Args.add(RValue::get(CGF.CGM.getSize(Offset)),
5454
CGF.getContext().getSizeType());
5555
const CGFunctionInfo &CallInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall(
56-
Args, GetParamBufProto, /*ChainCall=*/false);
56+
Args, GetParamBufProto, /*ChainCall=*/false,
57+
CGF.getCurrentFunctionDecl());
5758
auto Ret = CGF.EmitCall(CallInfo, Callee, /*ReturnValue=*/{}, Args);
5859

5960
return Ret.getScalarVal();
@@ -116,7 +117,7 @@ RValue CGCUDARuntime::EmitCUDADeviceKernelCallExpr(
116117
LaunchCallArgs[1] = CallArg(RValue::get(Config), CGM.getContext().VoidPtrTy);
117118
const CGFunctionInfo &LaunchCallInfo = CGM.getTypes().arrangeFreeFunctionCall(
118119
LaunchCallArgs, LaunchCalleeFuncTy->getAs<FunctionProtoType>(),
119-
/*ChainCall=*/false);
120+
/*ChainCall=*/false, CGF.getCurrentFunctionDecl());
120121
CGF.EmitCall(LaunchCallInfo, LaunchCallee, ReturnValue, LaunchCallArgs,
121122
CallOrInvoke,
122123
/*IsMustTail=*/false, E->getExprLoc());

0 commit comments

Comments
 (0)