@@ -2765,44 +2765,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
27652765 // types only.
27662766 case Builtin::BI__builtin_elementwise_add_sat:
27672767 case Builtin::BI__builtin_elementwise_sub_sat: {
2768- if (checkArgCount(TheCall, 2))
2769- return ExprError();
2770- ExprResult LHS = TheCall->getArg(0);
2771- ExprResult RHS = TheCall->getArg(1);
2772- QualType LHSType = LHS.get()->getType().getUnqualifiedType();
2773- QualType RHSType = RHS.get()->getType().getUnqualifiedType();
2774- // If both LHS/RHS are promotable integer types, do not perform the usual
2775- // conversions - we must keep the saturating operation at the correct
2776- // bitwidth.
2777- if (Context.isPromotableIntegerType(LHSType) &&
2778- Context.isPromotableIntegerType(RHSType)) {
2779- // First, convert each argument to an r-value.
2780- ExprResult ResLHS = DefaultFunctionArrayLvalueConversion(LHS.get());
2781- if (ResLHS.isInvalid())
2782- return ExprError();
2783- LHS = ResLHS.get();
2784-
2785- ExprResult ResRHS = DefaultFunctionArrayLvalueConversion(RHS.get());
2786- if (ResRHS.isInvalid())
2787- return ExprError();
2788- RHS = ResRHS.get();
2789-
2790- LHSType = LHS.get()->getType().getUnqualifiedType();
2791- RHSType = RHS.get()->getType().getUnqualifiedType();
2792-
2793- // If the two integer types are not of equal order, cast the smaller
2794- // integer one to the larger one
2795- if (int Order = Context.getIntegerTypeOrder(LHSType, RHSType); Order == 1)
2796- RHS = ImpCastExprToType(RHS.get(), LHSType, CK_IntegralCast);
2797- else if (Order == -1)
2798- LHS = ImpCastExprToType(LHS.get(), RHSType, CK_IntegralCast);
2799-
2800- TheCall->setArg(0, LHS.get());
2801- TheCall->setArg(1, RHS.get());
2802- TheCall->setType(LHS.get()->getType().getUnqualifiedType());
2803- break;
2804- }
2805-
28062768 if (BuiltinElementwiseMath(TheCall))
28072769 return ExprError();
28082770
@@ -2828,28 +2790,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
28282790 break;
28292791 case Builtin::BI__builtin_elementwise_popcount:
28302792 case Builtin::BI__builtin_elementwise_bitreverse: {
2831- if (checkArgCount(TheCall, 1))
2832- return ExprError();
2833-
2834- Expr *Arg = TheCall->getArg(0);
2835- QualType ArgTy = Arg->getType();
2836-
2837- // If the argument is a promotable integer type, do not perform the usual
2838- // conversions - we must keep the operation at the correct bitwidth.
2839- if (Context.isPromotableIntegerType(ArgTy)) {
2840- // Convert the argument to an r-value - avoid the usual conversions.
2841- ExprResult ResLHS = DefaultFunctionArrayLvalueConversion(Arg);
2842- if (ResLHS.isInvalid())
2843- return ExprError();
2844- Arg = ResLHS.get();
2845- TheCall->setArg(0, Arg);
2846- TheCall->setType(Arg->getType());
2847- break;
2848- }
2849-
28502793 if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
28512794 return ExprError();
28522795
2796+ const Expr *Arg = TheCall->getArg(0);
2797+ QualType ArgTy = Arg->getType();
28532798 QualType EltTy = ArgTy;
28542799
28552800 if (auto *VecTy = EltTy->getAs<VectorType>())
@@ -14649,11 +14594,18 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) {
1464914594 _2, _3, _4));
1465014595}
1465114596
14597+ static ExprResult UsualUnaryConversionsNoPromoteInt(Sema &S, Expr *E) {
14598+ // Don't promote integer types
14599+ if (QualType Ty = E->getType(); S.getASTContext().isPromotableIntegerType(Ty))
14600+ return S.DefaultFunctionArrayLvalueConversion(E);
14601+ return S.UsualUnaryConversions(E);
14602+ }
14603+
1465214604bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
1465314605 if (checkArgCount(TheCall, 1))
1465414606 return true;
1465514607
14656- ExprResult A = UsualUnaryConversions( TheCall->getArg(0));
14608+ ExprResult A = UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(0));
1465714609 if (A.isInvalid())
1465814610 return true;
1465914611
@@ -14668,57 +14620,63 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
1466814620}
1466914621
1467014622bool Sema::BuiltinElementwiseMath(CallExpr *TheCall, bool FPOnly) {
14671- QualType Res;
14672- if (BuiltinVectorMath(TheCall, Res, FPOnly))
14673- return true ;
14674- TheCall->setType(Res);
14675- return false ;
14623+ if (auto Res = BuiltinVectorMath(TheCall, FPOnly); Res.has_value()) {
14624+ TheCall->setType(* Res);
14625+ return false ;
14626+ }
14627+ return true ;
1467614628}
1467714629
1467814630bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) {
14679- QualType Res;
14680- if (BuiltinVectorMath(TheCall, Res) )
14631+ std::optional< QualType> Res = BuiltinVectorMath(TheCall) ;
14632+ if (! Res)
1468114633 return true;
1468214634
14683- if (auto *VecTy0 = Res->getAs<VectorType>())
14635+ if (auto *VecTy0 = (* Res) ->getAs<VectorType>())
1468414636 TheCall->setType(VecTy0->getElementType());
1468514637 else
14686- TheCall->setType(Res);
14638+ TheCall->setType(* Res);
1468714639
1468814640 return false;
1468914641}
1469014642
14691- bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) {
14643+ std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
14644+ bool FPOnly) {
1469214645 if (checkArgCount(TheCall, 2))
14693- return true ;
14646+ return std::nullopt ;
1469414647
14695- ExprResult A = TheCall->getArg(0);
14696- ExprResult B = TheCall->getArg(1);
14697- // Do standard promotions between the two arguments, returning their common
14698- // type.
14699- Res = UsualArithmeticConversions(A, B, TheCall->getExprLoc(), ACK_Comparison);
14700- if (A.isInvalid() || B.isInvalid())
14701- return true;
14648+ checkEnumArithmeticConversions(TheCall->getArg(0), TheCall->getArg(1),
14649+ TheCall->getExprLoc(), ACK_Comparison);
1470214650
14703- QualType TyA = A.get()->getType();
14704- QualType TyB = B.get()->getType();
14651+ Expr *Args[2];
14652+ for (int I = 0; I < 2; ++I) {
14653+ ExprResult Converted =
14654+ UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(I));
14655+ if (Converted.isInvalid())
14656+ return std::nullopt;
14657+ Args[I] = Converted.get();
14658+ }
1470514659
14706- if (Res.isNull() || TyA.getCanonicalType() != TyB.getCanonicalType())
14707- return Diag(A.get()->getBeginLoc(),
14708- diag::err_typecheck_call_different_arg_types)
14709- << TyA << TyB;
14660+ SourceLocation LocA = Args[0]->getBeginLoc();
14661+ QualType TyA = Args[0]->getType();
14662+ QualType TyB = Args[1]->getType();
14663+
14664+ if (TyA.getCanonicalType() != TyB.getCanonicalType()) {
14665+ Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB;
14666+ return std::nullopt;
14667+ }
1471014668
1471114669 if (FPOnly) {
14712- if (checkFPMathBuiltinElementType(*this, A.get()->getBeginLoc() , TyA, 1))
14713- return true ;
14670+ if (checkFPMathBuiltinElementType(*this, LocA , TyA, 1))
14671+ return std::nullopt ;
1471414672 } else {
14715- if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc() , TyA, 1))
14716- return true ;
14673+ if (checkMathBuiltinElementType(*this, LocA , TyA, 1))
14674+ return std::nullopt ;
1471714675 }
1471814676
14719- TheCall->setArg(0, A.get() );
14720- TheCall->setArg(1, B.get() );
14721- return false ;
14677+ TheCall->setArg(0, Args[0] );
14678+ TheCall->setArg(1, Args[1] );
14679+ return TyA ;
1472214680}
1472314681
1472414682bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
@@ -14728,7 +14686,8 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
1472814686
1472914687 Expr *Args[3];
1473014688 for (int I = 0; I < 3; ++I) {
14731- ExprResult Converted = UsualUnaryConversions(TheCall->getArg(I));
14689+ ExprResult Converted =
14690+ UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(I));
1473214691 if (Converted.isInvalid())
1473314692 return true;
1473414693 Args[I] = Converted.get();
0 commit comments