@@ -1968,26 +1968,40 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
1968
1968
// Check if \p Ty is a valid type for the elementwise math builtins. If it is
1969
1969
// not a valid type, emit an error message and return true. Otherwise return
1970
1970
// false.
1971
- static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc,
1972
- QualType ArgTy, int ArgIndex) {
1973
- if (!ArgTy->getAs<VectorType>() &&
1974
- !ConstantMatrixType::isValidElementType(ArgTy)) {
1975
- return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1976
- << ArgIndex << /* vector, integer or float ty*/ 0 << ArgTy;
1977
- }
1978
-
1979
- return false;
1980
- }
1981
-
1982
- static bool checkFPMathBuiltinElementType(Sema &S, SourceLocation Loc,
1983
- QualType ArgTy, int ArgIndex) {
1971
+ static bool
1972
+ checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy,
1973
+ Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr,
1974
+ int ArgOrdinal) {
1984
1975
QualType EltTy = ArgTy;
1985
1976
if (auto *VecTy = EltTy->getAs<VectorType>())
1986
1977
EltTy = VecTy->getElementType();
1987
1978
1988
- if (!EltTy->isRealFloatingType()) {
1989
- return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1990
- << ArgIndex << /* vector or float ty*/ 5 << ArgTy;
1979
+ switch (ArgTyRestr) {
1980
+ case Sema::EltwiseBuiltinArgTyRestriction::None:
1981
+ if (!ArgTy->getAs<VectorType>() &&
1982
+ !ConstantMatrixType::isValidElementType(ArgTy)) {
1983
+ return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1984
+ << ArgOrdinal << /* vector, integer or float ty*/ 0 << ArgTy;
1985
+ }
1986
+ break;
1987
+ case Sema::EltwiseBuiltinArgTyRestriction::FloatTy:
1988
+ if (!EltTy->isRealFloatingType()) {
1989
+ return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1990
+ << ArgOrdinal << /* vector or float ty*/ 5 << ArgTy;
1991
+ }
1992
+ break;
1993
+ case Sema::EltwiseBuiltinArgTyRestriction::IntegerTy:
1994
+ if (!EltTy->isIntegerType()) {
1995
+ return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
1996
+ << ArgOrdinal << /* vector or int ty*/ 10 << ArgTy;
1997
+ }
1998
+ break;
1999
+ case Sema::EltwiseBuiltinArgTyRestriction::SignedIntOrFloatTy:
2000
+ if (EltTy->isUnsignedIntegerType()) {
2001
+ return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
2002
+ << 1 << /* signed integer or float ty*/ 3 << ArgTy;
2003
+ }
2004
+ break;
1991
2005
}
1992
2006
1993
2007
return false;
@@ -2694,23 +2708,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2694
2708
2695
2709
// __builtin_elementwise_abs restricts the element type to signed integers or
2696
2710
// floating point types only.
2697
- case Builtin::BI__builtin_elementwise_abs: {
2698
- if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2711
+ case Builtin::BI__builtin_elementwise_abs:
2712
+ if (PrepareBuiltinElementwiseMathOneArgCall(
2713
+ TheCall, EltwiseBuiltinArgTyRestriction::SignedIntOrFloatTy))
2699
2714
return ExprError();
2700
-
2701
- QualType ArgTy = TheCall->getArg(0)->getType();
2702
- QualType EltTy = ArgTy;
2703
-
2704
- if (auto *VecTy = EltTy->getAs<VectorType>())
2705
- EltTy = VecTy->getElementType();
2706
- if (EltTy->isUnsignedIntegerType()) {
2707
- Diag(TheCall->getArg(0)->getBeginLoc(),
2708
- diag::err_builtin_invalid_arg_type)
2709
- << 1 << /* signed integer or float ty*/ 3 << ArgTy;
2710
- return ExprError();
2711
- }
2712
2715
break;
2713
- }
2714
2716
2715
2717
// These builtins restrict the element type to floating point
2716
2718
// types only.
@@ -2736,81 +2738,46 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2736
2738
case Builtin::BI__builtin_elementwise_tan:
2737
2739
case Builtin::BI__builtin_elementwise_tanh:
2738
2740
case Builtin::BI__builtin_elementwise_trunc:
2739
- case Builtin::BI__builtin_elementwise_canonicalize: {
2740
- if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2741
- return ExprError();
2742
-
2743
- QualType ArgTy = TheCall->getArg(0)->getType();
2744
- if (checkFPMathBuiltinElementType(*this, TheCall->getArg(0)->getBeginLoc(),
2745
- ArgTy, 1))
2741
+ case Builtin::BI__builtin_elementwise_canonicalize:
2742
+ if (PrepareBuiltinElementwiseMathOneArgCall(
2743
+ TheCall, EltwiseBuiltinArgTyRestriction::FloatTy))
2746
2744
return ExprError();
2747
2745
break;
2748
- }
2749
- case Builtin::BI__builtin_elementwise_fma: {
2746
+ case Builtin::BI__builtin_elementwise_fma:
2750
2747
if (BuiltinElementwiseTernaryMath(TheCall))
2751
2748
return ExprError();
2752
2749
break;
2753
- }
2754
2750
2755
2751
// These builtins restrict the element type to floating point
2756
2752
// types only, and take in two arguments.
2757
2753
case Builtin::BI__builtin_elementwise_minimum:
2758
2754
case Builtin::BI__builtin_elementwise_maximum:
2759
2755
case Builtin::BI__builtin_elementwise_atan2:
2760
2756
case Builtin::BI__builtin_elementwise_fmod:
2761
- case Builtin::BI__builtin_elementwise_pow: {
2762
- if (BuiltinElementwiseMath(TheCall, /*FPOnly=*/true))
2757
+ case Builtin::BI__builtin_elementwise_pow:
2758
+ if (BuiltinElementwiseMath(TheCall,
2759
+ EltwiseBuiltinArgTyRestriction::FloatTy))
2763
2760
return ExprError();
2764
2761
break;
2765
- }
2766
-
2767
2762
// These builtins restrict the element type to integer
2768
2763
// types only.
2769
2764
case Builtin::BI__builtin_elementwise_add_sat:
2770
- case Builtin::BI__builtin_elementwise_sub_sat: {
2771
- if (BuiltinElementwiseMath(TheCall))
2772
- return ExprError();
2773
-
2774
- const Expr *Arg = TheCall->getArg(0);
2775
- QualType ArgTy = Arg->getType();
2776
- QualType EltTy = ArgTy;
2777
-
2778
- if (auto *VecTy = EltTy->getAs<VectorType>())
2779
- EltTy = VecTy->getElementType();
2780
-
2781
- if (!EltTy->isIntegerType()) {
2782
- Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
2783
- << 1 << /* integer ty */ 6 << ArgTy;
2765
+ case Builtin::BI__builtin_elementwise_sub_sat:
2766
+ if (BuiltinElementwiseMath(TheCall,
2767
+ EltwiseBuiltinArgTyRestriction::IntegerTy))
2784
2768
return ExprError();
2785
- }
2786
2769
break;
2787
- }
2788
-
2789
2770
case Builtin::BI__builtin_elementwise_min:
2790
2771
case Builtin::BI__builtin_elementwise_max:
2791
2772
if (BuiltinElementwiseMath(TheCall))
2792
2773
return ExprError();
2793
2774
break;
2794
2775
case Builtin::BI__builtin_elementwise_popcount:
2795
- case Builtin::BI__builtin_elementwise_bitreverse: {
2796
- if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2797
- return ExprError();
2798
-
2799
- const Expr *Arg = TheCall->getArg(0);
2800
- QualType ArgTy = Arg->getType();
2801
- QualType EltTy = ArgTy;
2802
-
2803
- if (auto *VecTy = EltTy->getAs<VectorType>())
2804
- EltTy = VecTy->getElementType();
2805
-
2806
- if (!EltTy->isIntegerType()) {
2807
- Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
2808
- << 1 << /* integer ty */ 6 << ArgTy;
2776
+ case Builtin::BI__builtin_elementwise_bitreverse:
2777
+ if (PrepareBuiltinElementwiseMathOneArgCall(
2778
+ TheCall, EltwiseBuiltinArgTyRestriction::IntegerTy))
2809
2779
return ExprError();
2810
- }
2811
2780
break;
2812
- }
2813
-
2814
2781
case Builtin::BI__builtin_elementwise_copysign: {
2815
2782
if (checkArgCount(TheCall, 2))
2816
2783
return ExprError();
@@ -2822,10 +2789,12 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2822
2789
2823
2790
QualType MagnitudeTy = Magnitude.get()->getType();
2824
2791
QualType SignTy = Sign.get()->getType();
2825
- if (checkFPMathBuiltinElementType(*this, TheCall->getArg(0)->getBeginLoc(),
2826
- MagnitudeTy, 1) ||
2827
- checkFPMathBuiltinElementType(*this, TheCall->getArg(1)->getBeginLoc(),
2828
- SignTy, 2)) {
2792
+ if (checkMathBuiltinElementType(
2793
+ *this, TheCall->getArg(0)->getBeginLoc(), MagnitudeTy,
2794
+ EltwiseBuiltinArgTyRestriction::FloatTy, 1) ||
2795
+ checkMathBuiltinElementType(
2796
+ *this, TheCall->getArg(1)->getBeginLoc(), SignTy,
2797
+ EltwiseBuiltinArgTyRestriction::FloatTy, 2)) {
2829
2798
return ExprError();
2830
2799
}
2831
2800
@@ -14661,7 +14630,8 @@ static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E) {
14661
14630
return S.UsualUnaryFPConversions(Res.get());
14662
14631
}
14663
14632
14664
- bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
14633
+ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(
14634
+ CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr) {
14665
14635
if (checkArgCount(TheCall, 1))
14666
14636
return true;
14667
14637
@@ -14672,15 +14642,17 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
14672
14642
TheCall->setArg(0, A.get());
14673
14643
QualType TyA = A.get()->getType();
14674
14644
14675
- if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
14645
+ if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA,
14646
+ ArgTyRestr, 1))
14676
14647
return true;
14677
14648
14678
14649
TheCall->setType(TyA);
14679
14650
return false;
14680
14651
}
14681
14652
14682
- bool Sema::BuiltinElementwiseMath(CallExpr *TheCall, bool FPOnly) {
14683
- if (auto Res = BuiltinVectorMath(TheCall, FPOnly); Res.has_value()) {
14653
+ bool Sema::BuiltinElementwiseMath(CallExpr *TheCall,
14654
+ EltwiseBuiltinArgTyRestriction ArgTyRestr) {
14655
+ if (auto Res = BuiltinVectorMath(TheCall, ArgTyRestr); Res.has_value()) {
14684
14656
TheCall->setType(*Res);
14685
14657
return false;
14686
14658
}
@@ -14713,8 +14685,9 @@ static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS,
14713
14685
return false;
14714
14686
}
14715
14687
14716
- std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
14717
- bool FPOnly) {
14688
+ std::optional<QualType>
14689
+ Sema::BuiltinVectorMath(CallExpr *TheCall,
14690
+ EltwiseBuiltinArgTyRestriction ArgTyRestr) {
14718
14691
if (checkArgCount(TheCall, 2))
14719
14692
return std::nullopt;
14720
14693
@@ -14735,26 +14708,21 @@ std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
14735
14708
QualType TyA = Args[0]->getType();
14736
14709
QualType TyB = Args[1]->getType();
14737
14710
14711
+ if (checkMathBuiltinElementType(*this, LocA, TyA, ArgTyRestr, 1))
14712
+ return std::nullopt;
14713
+
14738
14714
if (TyA.getCanonicalType() != TyB.getCanonicalType()) {
14739
14715
Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB;
14740
14716
return std::nullopt;
14741
14717
}
14742
14718
14743
- if (FPOnly) {
14744
- if (checkFPMathBuiltinElementType(*this, LocA, TyA, 1))
14745
- return std::nullopt;
14746
- } else {
14747
- if (checkMathBuiltinElementType(*this, LocA, TyA, 1))
14748
- return std::nullopt;
14749
- }
14750
-
14751
14719
TheCall->setArg(0, Args[0]);
14752
14720
TheCall->setArg(1, Args[1]);
14753
14721
return TyA;
14754
14722
}
14755
14723
14756
- bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
14757
- bool CheckForFloatArgs ) {
14724
+ bool Sema::BuiltinElementwiseTernaryMath(
14725
+ CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr ) {
14758
14726
if (checkArgCount(TheCall, 3))
14759
14727
return true;
14760
14728
@@ -14774,20 +14742,11 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
14774
14742
Args[I] = Converted.get();
14775
14743
}
14776
14744
14777
- if (CheckForFloatArgs) {
14778
- int ArgOrdinal = 1;
14779
- for (Expr *Arg : Args) {
14780
- if (checkFPMathBuiltinElementType(*this, Arg->getBeginLoc(),
14781
- Arg->getType(), ArgOrdinal++))
14782
- return true;
14783
- }
14784
- } else {
14785
- int ArgOrdinal = 1;
14786
- for (Expr *Arg : Args) {
14787
- if (checkMathBuiltinElementType(*this, Arg->getBeginLoc(), Arg->getType(),
14788
- ArgOrdinal++))
14789
- return true;
14790
- }
14745
+ int ArgOrdinal = 1;
14746
+ for (Expr *Arg : Args) {
14747
+ if (checkMathBuiltinElementType(*this, Arg->getBeginLoc(), Arg->getType(),
14748
+ ArgTyRestr, ArgOrdinal++))
14749
+ return true;
14791
14750
}
14792
14751
14793
14752
for (int I = 1; I < 3; ++I) {
0 commit comments