@@ -1970,26 +1970,40 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
1970
1970
// Check if \p Ty is a valid type for the elementwise math builtins. If it is
1971
1971
// not a valid type, emit an error message and return true. Otherwise return
1972
1972
// false.
1973
- static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc,
1974
- QualType ArgTy, int ArgIndex) {
1975
- if (!ArgTy->getAs<VectorType>() &&
1976
- !ConstantMatrixType::isValidElementType(ArgTy)) {
1977
- return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1978
- << ArgIndex << /* vector, integer or float ty*/ 0 << ArgTy;
1979
- }
1980
-
1981
- return false;
1982
- }
1983
-
1984
- static bool checkFPMathBuiltinElementType(Sema &S, SourceLocation Loc,
1985
- QualType ArgTy, int ArgIndex) {
1973
+ static bool
1974
+ checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy,
1975
+ Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr,
1976
+ int ArgOrdinal) {
1986
1977
QualType EltTy = ArgTy;
1987
1978
if (auto *VecTy = EltTy->getAs<VectorType>())
1988
1979
EltTy = VecTy->getElementType();
1989
1980
1990
- if (!EltTy->isRealFloatingType()) {
1991
- return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1992
- << ArgIndex << /* vector or float ty*/ 5 << ArgTy;
1981
+ switch (ArgTyRestr) {
1982
+ case Sema::EltwiseBuiltinArgTyRestriction::None:
1983
+ if (!ArgTy->getAs<VectorType>() &&
1984
+ !ConstantMatrixType::isValidElementType(ArgTy)) {
1985
+ return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1986
+ << ArgOrdinal << /* vector, integer or float ty*/ 0 << ArgTy;
1987
+ }
1988
+ break;
1989
+ case Sema::EltwiseBuiltinArgTyRestriction::FloatTy:
1990
+ if (!EltTy->isRealFloatingType()) {
1991
+ return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1992
+ << ArgOrdinal << /* vector or float ty*/ 5 << ArgTy;
1993
+ }
1994
+ break;
1995
+ case Sema::EltwiseBuiltinArgTyRestriction::IntegerTy:
1996
+ if (!EltTy->isIntegerType()) {
1997
+ return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1998
+ << ArgOrdinal << /* vector or int ty*/ 10 << ArgTy;
1999
+ }
2000
+ break;
2001
+ case Sema::EltwiseBuiltinArgTyRestriction::SignedIntOrFloatTy:
2002
+ if (EltTy->isUnsignedIntegerType()) {
2003
+ return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
2004
+ << 1 << /* signed integer or float ty*/ 3 << ArgTy;
2005
+ }
2006
+ break;
1993
2007
}
1994
2008
1995
2009
return false;
@@ -2695,23 +2709,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2695
2709
2696
2710
// __builtin_elementwise_abs restricts the element type to signed integers or
2697
2711
// floating point types only.
2698
- case Builtin::BI__builtin_elementwise_abs: {
2699
- if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2712
+ case Builtin::BI__builtin_elementwise_abs:
2713
+ if (PrepareBuiltinElementwiseMathOneArgCall(
2714
+ TheCall, EltwiseBuiltinArgTyRestriction::SignedIntOrFloatTy))
2700
2715
return ExprError();
2701
-
2702
- QualType ArgTy = TheCall->getArg(0)->getType();
2703
- QualType EltTy = ArgTy;
2704
-
2705
- if (auto *VecTy = EltTy->getAs<VectorType>())
2706
- EltTy = VecTy->getElementType();
2707
- if (EltTy->isUnsignedIntegerType()) {
2708
- Diag(TheCall->getArg(0)->getBeginLoc(),
2709
- diag::err_builtin_invalid_arg_type)
2710
- << 1 << /* signed integer or float ty*/ 3 << ArgTy;
2711
- return ExprError();
2712
- }
2713
2716
break;
2714
- }
2715
2717
2716
2718
// These builtins restrict the element type to floating point
2717
2719
// types only.
@@ -2737,81 +2739,46 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2737
2739
case Builtin::BI__builtin_elementwise_tan:
2738
2740
case Builtin::BI__builtin_elementwise_tanh:
2739
2741
case Builtin::BI__builtin_elementwise_trunc:
2740
- case Builtin::BI__builtin_elementwise_canonicalize: {
2741
- if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2742
- return ExprError();
2743
-
2744
- QualType ArgTy = TheCall->getArg(0)->getType();
2745
- if (checkFPMathBuiltinElementType(*this, TheCall->getArg(0)->getBeginLoc(),
2746
- ArgTy, 1))
2742
+ case Builtin::BI__builtin_elementwise_canonicalize:
2743
+ if (PrepareBuiltinElementwiseMathOneArgCall(
2744
+ TheCall, EltwiseBuiltinArgTyRestriction::FloatTy))
2747
2745
return ExprError();
2748
2746
break;
2749
- }
2750
- case Builtin::BI__builtin_elementwise_fma: {
2747
+ case Builtin::BI__builtin_elementwise_fma:
2751
2748
if (BuiltinElementwiseTernaryMath(TheCall))
2752
2749
return ExprError();
2753
2750
break;
2754
- }
2755
2751
2756
2752
// These builtins restrict the element type to floating point
2757
2753
// types only, and take in two arguments.
2758
2754
case Builtin::BI__builtin_elementwise_minimum:
2759
2755
case Builtin::BI__builtin_elementwise_maximum:
2760
2756
case Builtin::BI__builtin_elementwise_atan2:
2761
2757
case Builtin::BI__builtin_elementwise_fmod:
2762
- case Builtin::BI__builtin_elementwise_pow: {
2763
- if (BuiltinElementwiseMath(TheCall, /*FPOnly=*/true))
2758
+ case Builtin::BI__builtin_elementwise_pow:
2759
+ if (BuiltinElementwiseMath(TheCall,
2760
+ EltwiseBuiltinArgTyRestriction::FloatTy))
2764
2761
return ExprError();
2765
2762
break;
2766
- }
2767
-
2768
2763
// These builtins restrict the element type to integer
2769
2764
// types only.
2770
2765
case Builtin::BI__builtin_elementwise_add_sat:
2771
- case Builtin::BI__builtin_elementwise_sub_sat: {
2772
- if (BuiltinElementwiseMath(TheCall))
2773
- return ExprError();
2774
-
2775
- const Expr *Arg = TheCall->getArg(0);
2776
- QualType ArgTy = Arg->getType();
2777
- QualType EltTy = ArgTy;
2778
-
2779
- if (auto *VecTy = EltTy->getAs<VectorType>())
2780
- EltTy = VecTy->getElementType();
2781
-
2782
- if (!EltTy->isIntegerType()) {
2783
- Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
2784
- << 1 << /* integer ty */ 6 << ArgTy;
2766
+ case Builtin::BI__builtin_elementwise_sub_sat:
2767
+ if (BuiltinElementwiseMath(TheCall,
2768
+ EltwiseBuiltinArgTyRestriction::IntegerTy))
2785
2769
return ExprError();
2786
- }
2787
2770
break;
2788
- }
2789
-
2790
2771
case Builtin::BI__builtin_elementwise_min:
2791
2772
case Builtin::BI__builtin_elementwise_max:
2792
2773
if (BuiltinElementwiseMath(TheCall))
2793
2774
return ExprError();
2794
2775
break;
2795
2776
case Builtin::BI__builtin_elementwise_popcount:
2796
- case Builtin::BI__builtin_elementwise_bitreverse: {
2797
- if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2798
- return ExprError();
2799
-
2800
- const Expr *Arg = TheCall->getArg(0);
2801
- QualType ArgTy = Arg->getType();
2802
- QualType EltTy = ArgTy;
2803
-
2804
- if (auto *VecTy = EltTy->getAs<VectorType>())
2805
- EltTy = VecTy->getElementType();
2806
-
2807
- if (!EltTy->isIntegerType()) {
2808
- Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
2809
- << 1 << /* integer ty */ 6 << ArgTy;
2777
+ case Builtin::BI__builtin_elementwise_bitreverse:
2778
+ if (PrepareBuiltinElementwiseMathOneArgCall(
2779
+ TheCall, EltwiseBuiltinArgTyRestriction::IntegerTy))
2810
2780
return ExprError();
2811
- }
2812
2781
break;
2813
- }
2814
-
2815
2782
case Builtin::BI__builtin_elementwise_copysign: {
2816
2783
if (checkArgCount(TheCall, 2))
2817
2784
return ExprError();
@@ -2823,10 +2790,12 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2823
2790
2824
2791
QualType MagnitudeTy = Magnitude.get()->getType();
2825
2792
QualType SignTy = Sign.get()->getType();
2826
- if (checkFPMathBuiltinElementType(*this, TheCall->getArg(0)->getBeginLoc(),
2827
- MagnitudeTy, 1) ||
2828
- checkFPMathBuiltinElementType(*this, TheCall->getArg(1)->getBeginLoc(),
2829
- SignTy, 2)) {
2793
+ if (checkMathBuiltinElementType(
2794
+ *this, TheCall->getArg(0)->getBeginLoc(), MagnitudeTy,
2795
+ EltwiseBuiltinArgTyRestriction::FloatTy, 1) ||
2796
+ checkMathBuiltinElementType(
2797
+ *this, TheCall->getArg(1)->getBeginLoc(), SignTy,
2798
+ EltwiseBuiltinArgTyRestriction::FloatTy, 2)) {
2830
2799
return ExprError();
2831
2800
}
2832
2801
@@ -15215,7 +15184,8 @@ static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E) {
15215
15184
return S.UsualUnaryFPConversions(Res.get());
15216
15185
}
15217
15186
15218
- bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
15187
+ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(
15188
+ CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr) {
15219
15189
if (checkArgCount(TheCall, 1))
15220
15190
return true;
15221
15191
@@ -15226,15 +15196,17 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
15226
15196
TheCall->setArg(0, A.get());
15227
15197
QualType TyA = A.get()->getType();
15228
15198
15229
- if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
15199
+ if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA,
15200
+ ArgTyRestr, 1))
15230
15201
return true;
15231
15202
15232
15203
TheCall->setType(TyA);
15233
15204
return false;
15234
15205
}
15235
15206
15236
- bool Sema::BuiltinElementwiseMath(CallExpr *TheCall, bool FPOnly) {
15237
- if (auto Res = BuiltinVectorMath(TheCall, FPOnly); Res.has_value()) {
15207
+ bool Sema::BuiltinElementwiseMath(CallExpr *TheCall,
15208
+ EltwiseBuiltinArgTyRestriction ArgTyRestr) {
15209
+ if (auto Res = BuiltinVectorMath(TheCall, ArgTyRestr); Res.has_value()) {
15238
15210
TheCall->setType(*Res);
15239
15211
return false;
15240
15212
}
@@ -15267,8 +15239,9 @@ static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS,
15267
15239
return false;
15268
15240
}
15269
15241
15270
- std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
15271
- bool FPOnly) {
15242
+ std::optional<QualType>
15243
+ Sema::BuiltinVectorMath(CallExpr *TheCall,
15244
+ EltwiseBuiltinArgTyRestriction ArgTyRestr) {
15272
15245
if (checkArgCount(TheCall, 2))
15273
15246
return std::nullopt;
15274
15247
@@ -15289,26 +15262,21 @@ std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
15289
15262
QualType TyA = Args[0]->getType();
15290
15263
QualType TyB = Args[1]->getType();
15291
15264
15265
+ if (checkMathBuiltinElementType(*this, LocA, TyA, ArgTyRestr, 1))
15266
+ return std::nullopt;
15267
+
15292
15268
if (TyA.getCanonicalType() != TyB.getCanonicalType()) {
15293
15269
Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB;
15294
15270
return std::nullopt;
15295
15271
}
15296
15272
15297
- if (FPOnly) {
15298
- if (checkFPMathBuiltinElementType(*this, LocA, TyA, 1))
15299
- return std::nullopt;
15300
- } else {
15301
- if (checkMathBuiltinElementType(*this, LocA, TyA, 1))
15302
- return std::nullopt;
15303
- }
15304
-
15305
15273
TheCall->setArg(0, Args[0]);
15306
15274
TheCall->setArg(1, Args[1]);
15307
15275
return TyA;
15308
15276
}
15309
15277
15310
- bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
15311
- bool CheckForFloatArgs ) {
15278
+ bool Sema::BuiltinElementwiseTernaryMath(
15279
+ CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr ) {
15312
15280
if (checkArgCount(TheCall, 3))
15313
15281
return true;
15314
15282
@@ -15328,20 +15296,11 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
15328
15296
Args[I] = Converted.get();
15329
15297
}
15330
15298
15331
- if (CheckForFloatArgs) {
15332
- int ArgOrdinal = 1;
15333
- for (Expr *Arg : Args) {
15334
- if (checkFPMathBuiltinElementType(*this, Arg->getBeginLoc(),
15335
- Arg->getType(), ArgOrdinal++))
15336
- return true;
15337
- }
15338
- } else {
15339
- int ArgOrdinal = 1;
15340
- for (Expr *Arg : Args) {
15341
- if (checkMathBuiltinElementType(*this, Arg->getBeginLoc(), Arg->getType(),
15342
- ArgOrdinal++))
15343
- return true;
15344
- }
15299
+ int ArgOrdinal = 1;
15300
+ for (Expr *Arg : Args) {
15301
+ if (checkMathBuiltinElementType(*this, Arg->getBeginLoc(), Arg->getType(),
15302
+ ArgTyRestr, ArgOrdinal++))
15303
+ return true;
15345
15304
}
15346
15305
15347
15306
for (int I = 1; I < 3; ++I) {
0 commit comments