1 //===------ SemaPPC.cpp ------ PowerPC target-specific routines -----------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements semantic analysis functions specific to PowerPC.
11 //===----------------------------------------------------------------------===//
13 #include "clang/Sema/SemaPPC.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/Attr.h"
16 #include "clang/AST/CharUnits.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/Type.h"
19 #include "clang/Basic/DiagnosticSema.h"
20 #include "clang/Basic/SourceLocation.h"
21 #include "clang/Basic/TargetBuiltins.h"
22 #include "clang/Basic/TargetInfo.h"
23 #include "clang/Sema/Sema.h"
24 #include "llvm/ADT/APSInt.h"
28 SemaPPC::SemaPPC(Sema
&S
) : SemaBase(S
) {}
30 void SemaPPC::checkAIXMemberAlignment(SourceLocation Loc
, const Expr
*Arg
) {
31 const auto *ICE
= dyn_cast
<ImplicitCastExpr
>(Arg
->IgnoreParens());
35 const auto *DR
= dyn_cast
<DeclRefExpr
>(ICE
->getSubExpr());
39 const auto *PD
= dyn_cast
<ParmVarDecl
>(DR
->getDecl());
40 if (!PD
|| !PD
->getType()->isRecordType())
43 QualType ArgType
= Arg
->getType();
44 for (const FieldDecl
*FD
:
45 ArgType
->castAs
<RecordType
>()->getDecl()->fields()) {
46 if (const auto *AA
= FD
->getAttr
<AlignedAttr
>()) {
47 CharUnits Alignment
= getASTContext().toCharUnitsFromBits(
48 AA
->getAlignment(getASTContext()));
49 if (Alignment
.getQuantity() == 16) {
50 Diag(FD
->getLocation(), diag::warn_not_xl_compatible
) << FD
;
51 Diag(Loc
, diag::note_misaligned_member_used_here
) << PD
;
57 static bool isPPC_64Builtin(unsigned BuiltinID
) {
58 // These builtins only work on PPC 64bit targets.
60 case PPC::BI__builtin_divde
:
61 case PPC::BI__builtin_divdeu
:
62 case PPC::BI__builtin_bpermd
:
63 case PPC::BI__builtin_pdepd
:
64 case PPC::BI__builtin_pextd
:
65 case PPC::BI__builtin_ppc_cdtbcd
:
66 case PPC::BI__builtin_ppc_cbcdtd
:
67 case PPC::BI__builtin_ppc_addg6s
:
68 case PPC::BI__builtin_ppc_ldarx
:
69 case PPC::BI__builtin_ppc_stdcx
:
70 case PPC::BI__builtin_ppc_tdw
:
71 case PPC::BI__builtin_ppc_trapd
:
72 case PPC::BI__builtin_ppc_cmpeqb
:
73 case PPC::BI__builtin_ppc_setb
:
74 case PPC::BI__builtin_ppc_mulhd
:
75 case PPC::BI__builtin_ppc_mulhdu
:
76 case PPC::BI__builtin_ppc_maddhd
:
77 case PPC::BI__builtin_ppc_maddhdu
:
78 case PPC::BI__builtin_ppc_maddld
:
79 case PPC::BI__builtin_ppc_load8r
:
80 case PPC::BI__builtin_ppc_store8r
:
81 case PPC::BI__builtin_ppc_insert_exp
:
82 case PPC::BI__builtin_ppc_extract_sig
:
83 case PPC::BI__builtin_ppc_addex
:
84 case PPC::BI__builtin_darn
:
85 case PPC::BI__builtin_darn_raw
:
86 case PPC::BI__builtin_ppc_compare_and_swaplp
:
87 case PPC::BI__builtin_ppc_fetch_and_addlp
:
88 case PPC::BI__builtin_ppc_fetch_and_andlp
:
89 case PPC::BI__builtin_ppc_fetch_and_orlp
:
90 case PPC::BI__builtin_ppc_fetch_and_swaplp
:
96 bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo
&TI
,
99 ASTContext
&Context
= getASTContext();
100 bool IsTarget64Bit
= TI
.getTypeWidth(TI
.getIntPtrType()) == 64;
103 if (isPPC_64Builtin(BuiltinID
) && !IsTarget64Bit
)
104 return Diag(TheCall
->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt
)
105 << TheCall
->getSourceRange();
110 case PPC::BI__builtin_altivec_crypto_vshasigmaw
:
111 case PPC::BI__builtin_altivec_crypto_vshasigmad
:
112 return SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 0, 1) ||
113 SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 0, 15);
114 case PPC::BI__builtin_altivec_dss
:
115 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 3);
116 case PPC::BI__builtin_tbegin
:
117 case PPC::BI__builtin_tend
:
118 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 1);
119 case PPC::BI__builtin_tsr
:
120 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 7);
121 case PPC::BI__builtin_tabortwc
:
122 case PPC::BI__builtin_tabortdc
:
123 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 31);
124 case PPC::BI__builtin_tabortwci
:
125 case PPC::BI__builtin_tabortdci
:
126 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 31) ||
127 SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 0, 31);
128 // According to GCC 'Basic PowerPC Built-in Functions Available on ISA 2.05',
129 // __builtin_(un)pack_longdouble are available only if long double uses IBM
130 // extended double representation.
131 case PPC::BI__builtin_unpack_longdouble
:
132 if (SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 0, 1))
135 case PPC::BI__builtin_pack_longdouble
:
136 if (&TI
.getLongDoubleFormat() != &llvm::APFloat::PPCDoubleDouble())
137 return Diag(TheCall
->getBeginLoc(), diag::err_ppc_builtin_requires_abi
)
140 case PPC::BI__builtin_altivec_dst
:
141 case PPC::BI__builtin_altivec_dstt
:
142 case PPC::BI__builtin_altivec_dstst
:
143 case PPC::BI__builtin_altivec_dststt
:
144 return SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 0, 3);
145 case PPC::BI__builtin_vsx_xxpermdi
:
146 case PPC::BI__builtin_vsx_xxsldwi
:
147 return BuiltinVSX(TheCall
);
148 case PPC::BI__builtin_unpack_vector_int128
:
149 return SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 0, 1);
150 case PPC::BI__builtin_altivec_vgnb
:
151 return SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 2, 7);
152 case PPC::BI__builtin_vsx_xxeval
:
153 return SemaRef
.BuiltinConstantArgRange(TheCall
, 3, 0, 255);
154 case PPC::BI__builtin_altivec_vsldbi
:
155 return SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 0, 7);
156 case PPC::BI__builtin_altivec_vsrdbi
:
157 return SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 0, 7);
158 case PPC::BI__builtin_vsx_xxpermx
:
159 return SemaRef
.BuiltinConstantArgRange(TheCall
, 3, 0, 7);
160 case PPC::BI__builtin_ppc_tw
:
161 case PPC::BI__builtin_ppc_tdw
:
162 return SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 1, 31);
163 case PPC::BI__builtin_ppc_cmprb
:
164 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 1);
165 // For __rlwnm, __rlwimi and __rldimi, the last parameter mask must
166 // be a constant that represents a contiguous bit field.
167 case PPC::BI__builtin_ppc_rlwnm
:
168 return SemaRef
.ValueIsRunOfOnes(TheCall
, 2);
169 case PPC::BI__builtin_ppc_rlwimi
:
170 return SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 0, 31) ||
171 SemaRef
.ValueIsRunOfOnes(TheCall
, 3);
172 case PPC::BI__builtin_ppc_rldimi
:
173 return SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 0, 63) ||
174 SemaRef
.ValueIsRunOfOnes(TheCall
, 3);
175 case PPC::BI__builtin_ppc_addex
: {
176 if (SemaRef
.BuiltinConstantArgRange(TheCall
, 2, 0, 3))
178 // Output warning for reserved values 1 to 3.
180 TheCall
->getArg(2)->getIntegerConstantExpr(Context
)->getSExtValue();
182 Diag(TheCall
->getBeginLoc(), diag::warn_argument_undefined_behaviour
)
186 case PPC::BI__builtin_ppc_mtfsb0
:
187 case PPC::BI__builtin_ppc_mtfsb1
:
188 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 31);
189 case PPC::BI__builtin_ppc_mtfsf
:
190 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 255);
191 case PPC::BI__builtin_ppc_mtfsfi
:
192 return SemaRef
.BuiltinConstantArgRange(TheCall
, 0, 0, 7) ||
193 SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 0, 15);
194 case PPC::BI__builtin_ppc_alignx
:
195 return SemaRef
.BuiltinConstantArgPower2(TheCall
, 0);
196 case PPC::BI__builtin_ppc_rdlam
:
197 return SemaRef
.ValueIsRunOfOnes(TheCall
, 2);
198 case PPC::BI__builtin_vsx_ldrmb
:
199 case PPC::BI__builtin_vsx_strmb
:
200 return SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 1, 16);
201 case PPC::BI__builtin_altivec_vcntmbb
:
202 case PPC::BI__builtin_altivec_vcntmbh
:
203 case PPC::BI__builtin_altivec_vcntmbw
:
204 case PPC::BI__builtin_altivec_vcntmbd
:
205 return SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 0, 1);
206 case PPC::BI__builtin_vsx_xxgenpcvbm
:
207 case PPC::BI__builtin_vsx_xxgenpcvhm
:
208 case PPC::BI__builtin_vsx_xxgenpcvwm
:
209 case PPC::BI__builtin_vsx_xxgenpcvdm
:
210 return SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 0, 3);
211 case PPC::BI__builtin_ppc_test_data_class
: {
212 // Check if the first argument of the __builtin_ppc_test_data_class call is
213 // valid. The argument must be 'float' or 'double' or '__float128'.
214 QualType ArgType
= TheCall
->getArg(0)->getType();
215 if (ArgType
!= QualType(Context
.FloatTy
) &&
216 ArgType
!= QualType(Context
.DoubleTy
) &&
217 ArgType
!= QualType(Context
.Float128Ty
))
218 return Diag(TheCall
->getBeginLoc(),
219 diag::err_ppc_invalid_test_data_class_type
);
220 return SemaRef
.BuiltinConstantArgRange(TheCall
, 1, 0, 127);
222 case PPC::BI__builtin_ppc_maxfe
:
223 case PPC::BI__builtin_ppc_minfe
:
224 case PPC::BI__builtin_ppc_maxfl
:
225 case PPC::BI__builtin_ppc_minfl
:
226 case PPC::BI__builtin_ppc_maxfs
:
227 case PPC::BI__builtin_ppc_minfs
: {
228 if (Context
.getTargetInfo().getTriple().isOSAIX() &&
229 (BuiltinID
== PPC::BI__builtin_ppc_maxfe
||
230 BuiltinID
== PPC::BI__builtin_ppc_minfe
))
231 return Diag(TheCall
->getBeginLoc(), diag::err_target_unsupported_type
)
232 << "builtin" << true << 128 << QualType(Context
.LongDoubleTy
)
233 << false << Context
.getTargetInfo().getTriple().str();
234 // Argument type should be exact.
235 QualType ArgType
= QualType(Context
.LongDoubleTy
);
236 if (BuiltinID
== PPC::BI__builtin_ppc_maxfl
||
237 BuiltinID
== PPC::BI__builtin_ppc_minfl
)
238 ArgType
= QualType(Context
.DoubleTy
);
239 else if (BuiltinID
== PPC::BI__builtin_ppc_maxfs
||
240 BuiltinID
== PPC::BI__builtin_ppc_minfs
)
241 ArgType
= QualType(Context
.FloatTy
);
242 for (unsigned I
= 0, E
= TheCall
->getNumArgs(); I
< E
; ++I
)
243 if (TheCall
->getArg(I
)->getType() != ArgType
)
244 return Diag(TheCall
->getBeginLoc(),
245 diag::err_typecheck_convert_incompatible
)
246 << TheCall
->getArg(I
)->getType() << ArgType
<< 1 << 0 << 0;
249 #define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \
250 case PPC::BI__builtin_##Name: \
251 return BuiltinPPCMMACall(TheCall, BuiltinID, Types);
252 #include "clang/Basic/BuiltinsPPC.def"
254 llvm_unreachable("must return from switch");
257 // Check if the given type is a non-pointer PPC MMA type. This function is used
258 // in Sema to prevent invalid uses of restricted PPC MMA types.
259 bool SemaPPC::CheckPPCMMAType(QualType Type
, SourceLocation TypeLoc
) {
260 ASTContext
&Context
= getASTContext();
261 if (Type
->isPointerType() || Type
->isArrayType())
264 QualType CoreType
= Type
.getCanonicalType().getUnqualifiedType();
265 #define PPC_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id##Ty
267 #include "clang/Basic/PPCTypes.def"
269 Diag(TypeLoc
, diag::err_ppc_invalid_use_mma_type
);
275 /// DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str,
276 /// advancing the pointer over the consumed characters. The decoded type is
277 /// returned. If the decoded type represents a constant integer with a
278 /// constraint on its value then Mask is set to that value. The type descriptors
279 /// used in Str are specific to PPC MMA builtins and are documented in the file
280 /// defining the PPC builtins.
281 static QualType
DecodePPCMMATypeFromStr(ASTContext
&Context
, const char *&Str
,
283 bool RequireICE
= false;
284 ASTContext::GetBuiltinTypeError Error
= ASTContext::GE_None
;
287 return Context
.getVectorType(Context
.UnsignedCharTy
, 16,
288 VectorKind::AltiVecVector
);
291 unsigned size
= strtoul(Str
, &End
, 10);
292 assert(End
!= Str
&& "Missing constant parameter constraint");
295 return Context
.IntTy
;
299 unsigned size
= strtoul(Str
, &End
, 10);
300 assert(End
!= Str
&& "Missing PowerPC MMA type size");
304 #define PPC_VECTOR_TYPE(typeName, Id, size) \
306 Type = Context.Id##Ty; \
308 #include "clang/Basic/PPCTypes.def"
310 llvm_unreachable("Invalid PowerPC MMA vector type");
312 bool CheckVectorArgs
= false;
313 while (!CheckVectorArgs
) {
316 Type
= Context
.getPointerType(Type
);
319 Type
= Type
.withConst();
322 CheckVectorArgs
= true;
330 return Context
.DecodeTypeStr(--Str
, Context
, Error
, RequireICE
, true);
334 bool SemaPPC::BuiltinPPCMMACall(CallExpr
*TheCall
, unsigned BuiltinID
,
335 const char *TypeStr
) {
337 assert((TypeStr
[0] != '\0') &&
338 "Invalid types in PPC MMA builtin declaration");
340 ASTContext
&Context
= getASTContext();
344 // The first type in TypeStr is the type of the value returned by the
345 // builtin. So we first read that type and change the type of TheCall.
346 QualType type
= DecodePPCMMATypeFromStr(Context
, TypeStr
, Mask
);
347 TheCall
->setType(type
);
349 while (*TypeStr
!= '\0') {
351 QualType ExpectedType
= DecodePPCMMATypeFromStr(Context
, TypeStr
, Mask
);
352 if (ArgNum
>= TheCall
->getNumArgs()) {
357 Expr
*Arg
= TheCall
->getArg(ArgNum
);
358 QualType PassedType
= Arg
->getType();
359 QualType StrippedRVType
= PassedType
.getCanonicalType();
361 // Strip Restrict/Volatile qualifiers.
362 if (StrippedRVType
.isRestrictQualified() ||
363 StrippedRVType
.isVolatileQualified())
364 StrippedRVType
= StrippedRVType
.getCanonicalType().getUnqualifiedType();
366 // The only case where the argument type and expected type are allowed to
367 // mismatch is if the argument type is a non-void pointer (or array) and
368 // expected type is a void pointer.
369 if (StrippedRVType
!= ExpectedType
)
370 if (!(ExpectedType
->isVoidPointerType() &&
371 (StrippedRVType
->isPointerType() || StrippedRVType
->isArrayType())))
372 return Diag(Arg
->getBeginLoc(),
373 diag::err_typecheck_convert_incompatible
)
374 << PassedType
<< ExpectedType
<< 1 << 0 << 0;
376 // If the value of the Mask is not 0, we have a constraint in the size of
377 // the integer argument so here we ensure the argument is a constant that
378 // is in the valid range.
380 SemaRef
.BuiltinConstantArgRange(TheCall
, ArgNum
, 0, Mask
, true))
386 // In case we exited early from the previous loop, there are other types to
387 // read from TypeStr. So we need to read them all to ensure we have the right
388 // number of arguments in TheCall and if it is not the case, to display a
389 // better error message.
390 while (*TypeStr
!= '\0') {
391 (void)DecodePPCMMATypeFromStr(Context
, TypeStr
, Mask
);
394 if (SemaRef
.checkArgCount(TheCall
, ArgNum
))
400 bool SemaPPC::BuiltinVSX(CallExpr
*TheCall
) {
401 unsigned ExpectedNumArgs
= 3;
402 if (SemaRef
.checkArgCount(TheCall
, ExpectedNumArgs
))
405 // Check the third argument is a compile time constant
406 if (!TheCall
->getArg(2)->isIntegerConstantExpr(getASTContext()))
407 return Diag(TheCall
->getBeginLoc(),
408 diag::err_vsx_builtin_nonconstant_argument
)
409 << 3 /* argument index */ << TheCall
->getDirectCallee()
410 << SourceRange(TheCall
->getArg(2)->getBeginLoc(),
411 TheCall
->getArg(2)->getEndLoc());
413 QualType Arg1Ty
= TheCall
->getArg(0)->getType();
414 QualType Arg2Ty
= TheCall
->getArg(1)->getType();
416 // Check the type of argument 1 and argument 2 are vectors.
417 SourceLocation BuiltinLoc
= TheCall
->getBeginLoc();
418 if ((!Arg1Ty
->isVectorType() && !Arg1Ty
->isDependentType()) ||
419 (!Arg2Ty
->isVectorType() && !Arg2Ty
->isDependentType())) {
420 return Diag(BuiltinLoc
, diag::err_vec_builtin_non_vector
)
421 << TheCall
->getDirectCallee() << /*isMorethantwoArgs*/ false
422 << SourceRange(TheCall
->getArg(0)->getBeginLoc(),
423 TheCall
->getArg(1)->getEndLoc());
426 // Check the first two arguments are the same type.
427 if (!getASTContext().hasSameUnqualifiedType(Arg1Ty
, Arg2Ty
)) {
428 return Diag(BuiltinLoc
, diag::err_vec_builtin_incompatible_vector
)
429 << TheCall
->getDirectCallee() << /*isMorethantwoArgs*/ false
430 << SourceRange(TheCall
->getArg(0)->getBeginLoc(),
431 TheCall
->getArg(1)->getEndLoc());
434 // When default clang type checking is turned off and the customized type
435 // checking is used, the returning type of the function must be explicitly
436 // set. Otherwise it is _Bool by default.
437 TheCall
->setType(Arg1Ty
);