@@ -170,8 +170,22 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
170
170
171
171
void checkFunctionCallABI (CodeGenModule &CGM, SourceLocation CallLoc,
172
172
const FunctionDecl *Caller,
173
- const FunctionDecl *Callee,
174
- const CallArgList &Args) const override ;
173
+ const FunctionDecl *Callee, const CallArgList &Args,
174
+ QualType ReturnType) const override ;
175
+
176
+ private:
177
+ // Diagnose calls between functions with incompatible Streaming SVE
178
+ // attributes.
179
+ void checkFunctionCallABIStreaming (CodeGenModule &CGM, SourceLocation CallLoc,
180
+ const FunctionDecl *Caller,
181
+ const FunctionDecl *Callee) const ;
182
+ // Diagnose calls which must pass arguments in floating-point registers when
183
+ // the selected target does not have floating-point registers.
184
+ void checkFunctionCallABISoftFloat (CodeGenModule &CGM, SourceLocation CallLoc,
185
+ const FunctionDecl *Caller,
186
+ const FunctionDecl *Callee,
187
+ const CallArgList &Args,
188
+ QualType ReturnType) const ;
175
189
};
176
190
177
191
class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo {
@@ -853,37 +867,42 @@ static bool isStreamingCompatible(const FunctionDecl *F) {
853
867
return false ;
854
868
}
855
869
870
+ // Report an error if an argument or return value of type Ty would need to be
871
+ // passed in a floating-point register.
872
+ static void diagnoseIfNeedsFPReg (DiagnosticsEngine &Diags,
873
+ const StringRef ABIName,
874
+ const AArch64ABIInfo &ABIInfo,
875
+ const QualType &Ty, const NamedDecl *D) {
876
+ const Type *HABase = nullptr ;
877
+ uint64_t HAMembers = 0 ;
878
+ if (Ty->isFloatingType () || Ty->isVectorType () ||
879
+ ABIInfo.isHomogeneousAggregate (Ty, HABase, HAMembers)) {
880
+ Diags.Report (D->getLocation (), diag::err_target_unsupported_type_for_abi)
881
+ << D->getDeclName () << Ty << ABIName;
882
+ }
883
+ }
884
+
885
+ // If we are using a hard-float ABI, but do not have floating point registers,
886
+ // then report an error for any function arguments or returns which would be
887
+ // passed in floating-pint registers.
856
888
void AArch64TargetCodeGenInfo::checkFunctionABI (
857
889
CodeGenModule &CGM, const FunctionDecl *FuncDecl) const {
858
890
const AArch64ABIInfo &ABIInfo = getABIInfo<AArch64ABIInfo>();
859
891
const TargetInfo &TI = ABIInfo.getContext ().getTargetInfo ();
860
892
861
- // If we are using a hard-float ABI, but do not have floating point
862
- // registers, then report an error for any function arguments or returns
863
- // which would be passed in floating-pint registers.
864
- auto CheckType = [&CGM, &TI, &ABIInfo](const QualType &Ty,
865
- const NamedDecl *D) {
866
- const Type *HABase = nullptr ;
867
- uint64_t HAMembers = 0 ;
868
- if (Ty->isFloatingType () || Ty->isVectorType () ||
869
- ABIInfo.isHomogeneousAggregate (Ty, HABase, HAMembers)) {
870
- CGM.getDiags ().Report (D->getLocation (),
871
- diag::err_target_unsupported_type_for_abi)
872
- << D->getDeclName () << Ty << TI.getABI ();
873
- }
874
- };
875
-
876
893
if (!TI.hasFeature (" fp" ) && !ABIInfo.isSoftFloat ()) {
877
- CheckType (FuncDecl->getReturnType (), FuncDecl);
894
+ diagnoseIfNeedsFPReg (CGM.getDiags (), TI.getABI (), ABIInfo,
895
+ FuncDecl->getReturnType (), FuncDecl);
878
896
for (ParmVarDecl *PVD : FuncDecl->parameters ()) {
879
- CheckType (PVD->getType (), PVD);
897
+ diagnoseIfNeedsFPReg (CGM.getDiags (), TI.getABI (), ABIInfo, PVD->getType (),
898
+ PVD);
880
899
}
881
900
}
882
901
}
883
902
884
- void AArch64TargetCodeGenInfo::checkFunctionCallABI (
903
+ void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming (
885
904
CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller,
886
- const FunctionDecl *Callee, const CallArgList &Args ) const {
905
+ const FunctionDecl *Callee) const {
887
906
if (!Caller || !Callee || !Callee->hasAttr <AlwaysInlineAttr>())
888
907
return ;
889
908
@@ -903,6 +922,37 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABI(
903
922
<< Callee->getDeclName ();
904
923
}
905
924
925
+ // If the target does not have floating-point registers, but we are using a
926
+ // hard-float ABI, there is no way to pass floating-point, vector or HFA values
927
+ // to functions, so we report an error.
928
+ void AArch64TargetCodeGenInfo::checkFunctionCallABISoftFloat (
929
+ CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller,
930
+ const FunctionDecl *Callee, const CallArgList &Args,
931
+ QualType ReturnType) const {
932
+ const AArch64ABIInfo &ABIInfo = getABIInfo<AArch64ABIInfo>();
933
+ const TargetInfo &TI = ABIInfo.getContext ().getTargetInfo ();
934
+
935
+ if (!Caller || TI.hasFeature (" fp" ) || ABIInfo.isSoftFloat ())
936
+ return ;
937
+
938
+ diagnoseIfNeedsFPReg (CGM.getDiags (), TI.getABI (), ABIInfo, ReturnType,
939
+ Caller);
940
+
941
+ for (const CallArg &Arg : Args)
942
+ diagnoseIfNeedsFPReg (CGM.getDiags (), TI.getABI (), ABIInfo, Arg.getType (),
943
+ Caller);
944
+ }
945
+
946
+ void AArch64TargetCodeGenInfo::checkFunctionCallABI (CodeGenModule &CGM,
947
+ SourceLocation CallLoc,
948
+ const FunctionDecl *Caller,
949
+ const FunctionDecl *Callee,
950
+ const CallArgList &Args,
951
+ QualType ReturnType) const {
952
+ checkFunctionCallABIStreaming (CGM, CallLoc, Caller, Callee);
953
+ checkFunctionCallABISoftFloat (CGM, CallLoc, Caller, Callee, Args, ReturnType);
954
+ }
955
+
906
956
void AArch64ABIInfo::appendAttributeMangling (TargetClonesAttr *Attr,
907
957
unsigned Index,
908
958
raw_ostream &Out) const {
0 commit comments