@@ -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>())
@@ -14640,11 +14585,18 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) {
1464014585 _2, _3, _4));
1464114586}
1464214587
14588+ static ExprResult UsualUnaryConversionsNoPromoteInt(Sema &S, Expr *E) {
14589+ // Don't promote integer types
14590+ if (QualType Ty = E->getType(); S.getASTContext().isPromotableIntegerType(Ty))
14591+ return S.DefaultFunctionArrayLvalueConversion(E);
14592+ return S.UsualUnaryConversions(E);
14593+ }
14594+
1464314595bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
1464414596 if (checkArgCount(TheCall, 1))
1464514597 return true;
1464614598
14647- ExprResult A = UsualUnaryConversions( TheCall->getArg(0));
14599+ ExprResult A = UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(0));
1464814600 if (A.isInvalid())
1464914601 return true;
1465014602
@@ -14659,57 +14611,63 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
1465914611}
1466014612
1466114613bool Sema::BuiltinElementwiseMath(CallExpr *TheCall, bool FPOnly) {
14662- QualType Res;
14663- if (BuiltinVectorMath(TheCall, Res, FPOnly))
14664- return true ;
14665- TheCall->setType(Res);
14666- return false ;
14614+ if (auto Res = BuiltinVectorMath(TheCall, FPOnly); Res.has_value()) {
14615+ TheCall->setType(* Res);
14616+ return false ;
14617+ }
14618+ return true ;
1466714619}
1466814620
1466914621bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) {
14670- QualType Res;
14671- if (BuiltinVectorMath(TheCall, Res) )
14622+ std::optional< QualType> Res = BuiltinVectorMath(TheCall) ;
14623+ if (! Res)
1467214624 return true;
1467314625
14674- if (auto *VecTy0 = Res->getAs<VectorType>())
14626+ if (auto *VecTy0 = (* Res) ->getAs<VectorType>())
1467514627 TheCall->setType(VecTy0->getElementType());
1467614628 else
14677- TheCall->setType(Res);
14629+ TheCall->setType(* Res);
1467814630
1467914631 return false;
1468014632}
1468114633
14682- bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) {
14634+ std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
14635+ bool FPOnly) {
1468314636 if (checkArgCount(TheCall, 2))
14684- return true ;
14637+ return std::nullopt ;
1468514638
14686- ExprResult A = TheCall->getArg(0);
14687- ExprResult B = TheCall->getArg(1);
14688- // Do standard promotions between the two arguments, returning their common
14689- // type.
14690- Res = UsualArithmeticConversions(A, B, TheCall->getExprLoc(), ACK_Comparison);
14691- if (A.isInvalid() || B.isInvalid())
14692- return true;
14639+ checkEnumArithmeticConversions(TheCall->getArg(0), TheCall->getArg(1),
14640+ TheCall->getExprLoc(), ACK_Comparison);
1469314641
14694- QualType TyA = A.get()->getType();
14695- QualType TyB = B.get()->getType();
14642+ Expr *Args[2];
14643+ for (int I = 0; I < 2; ++I) {
14644+ ExprResult Converted =
14645+ UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(I));
14646+ if (Converted.isInvalid())
14647+ return std::nullopt;
14648+ Args[I] = Converted.get();
14649+ }
1469614650
14697- if (Res.isNull() || TyA.getCanonicalType() != TyB.getCanonicalType())
14698- return Diag(A.get()->getBeginLoc(),
14699- diag::err_typecheck_call_different_arg_types)
14700- << TyA << TyB;
14651+ SourceLocation LocA = Args[0]->getBeginLoc();
14652+ QualType TyA = Args[0]->getType();
14653+ QualType TyB = Args[1]->getType();
14654+
14655+ if (TyA.getCanonicalType() != TyB.getCanonicalType()) {
14656+ Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB;
14657+ return std::nullopt;
14658+ }
1470114659
1470214660 if (FPOnly) {
14703- if (checkFPMathBuiltinElementType(*this, A.get()->getBeginLoc() , TyA, 1))
14704- return true ;
14661+ if (checkFPMathBuiltinElementType(*this, LocA , TyA, 1))
14662+ return std::nullopt ;
1470514663 } else {
14706- if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc() , TyA, 1))
14707- return true ;
14664+ if (checkMathBuiltinElementType(*this, LocA , TyA, 1))
14665+ return std::nullopt ;
1470814666 }
1470914667
14710- TheCall->setArg(0, A.get() );
14711- TheCall->setArg(1, B.get() );
14712- return false ;
14668+ TheCall->setArg(0, Args[0] );
14669+ TheCall->setArg(1, Args[1] );
14670+ return TyA ;
1471314671}
1471414672
1471514673bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
@@ -14719,7 +14677,8 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
1471914677
1472014678 Expr *Args[3];
1472114679 for (int I = 0; I < 3; ++I) {
14722- ExprResult Converted = UsualUnaryConversions(TheCall->getArg(I));
14680+ ExprResult Converted =
14681+ UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(I));
1472314682 if (Converted.isInvalid())
1472414683 return true;
1472514684 Args[I] = Converted.get();
0 commit comments