@@ -2765,44 +2765,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2765
2765
// types only.
2766
2766
case Builtin::BI__builtin_elementwise_add_sat:
2767
2767
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
-
2806
2768
if (BuiltinElementwiseMath(TheCall))
2807
2769
return ExprError();
2808
2770
@@ -2828,28 +2790,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2828
2790
break;
2829
2791
case Builtin::BI__builtin_elementwise_popcount:
2830
2792
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
-
2850
2793
if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2851
2794
return ExprError();
2852
2795
2796
+ const Expr *Arg = TheCall->getArg(0);
2797
+ QualType ArgTy = Arg->getType();
2853
2798
QualType EltTy = ArgTy;
2854
2799
2855
2800
if (auto *VecTy = EltTy->getAs<VectorType>())
@@ -14649,11 +14594,18 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) {
14649
14594
_2, _3, _4));
14650
14595
}
14651
14596
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
+
14652
14604
bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
14653
14605
if (checkArgCount(TheCall, 1))
14654
14606
return true;
14655
14607
14656
- ExprResult A = UsualUnaryConversions( TheCall->getArg(0));
14608
+ ExprResult A = UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(0));
14657
14609
if (A.isInvalid())
14658
14610
return true;
14659
14611
@@ -14668,57 +14620,63 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
14668
14620
}
14669
14621
14670
14622
bool 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 ;
14676
14628
}
14677
14629
14678
14630
bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) {
14679
- QualType Res;
14680
- if (BuiltinVectorMath(TheCall, Res) )
14631
+ std::optional< QualType> Res = BuiltinVectorMath(TheCall) ;
14632
+ if (! Res)
14681
14633
return true;
14682
14634
14683
- if (auto *VecTy0 = Res->getAs<VectorType>())
14635
+ if (auto *VecTy0 = (* Res) ->getAs<VectorType>())
14684
14636
TheCall->setType(VecTy0->getElementType());
14685
14637
else
14686
- TheCall->setType(Res);
14638
+ TheCall->setType(* Res);
14687
14639
14688
14640
return false;
14689
14641
}
14690
14642
14691
- bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) {
14643
+ std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
14644
+ bool FPOnly) {
14692
14645
if (checkArgCount(TheCall, 2))
14693
- return true ;
14646
+ return std::nullopt ;
14694
14647
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);
14702
14650
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
+ }
14705
14659
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
+ }
14710
14668
14711
14669
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 ;
14714
14672
} else {
14715
- if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc() , TyA, 1))
14716
- return true ;
14673
+ if (checkMathBuiltinElementType(*this, LocA , TyA, 1))
14674
+ return std::nullopt ;
14717
14675
}
14718
14676
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 ;
14722
14680
}
14723
14681
14724
14682
bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
@@ -14728,7 +14686,8 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
14728
14686
14729
14687
Expr *Args[3];
14730
14688
for (int I = 0; I < 3; ++I) {
14731
- ExprResult Converted = UsualUnaryConversions(TheCall->getArg(I));
14689
+ ExprResult Converted =
14690
+ UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(I));
14732
14691
if (Converted.isInvalid())
14733
14692
return true;
14734
14693
Args[I] = Converted.get();
0 commit comments