@@ -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>())
@@ -14640,11 +14585,18 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) {
14640
14585
_2, _3, _4));
14641
14586
}
14642
14587
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
+
14643
14595
bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
14644
14596
if (checkArgCount(TheCall, 1))
14645
14597
return true;
14646
14598
14647
- ExprResult A = UsualUnaryConversions( TheCall->getArg(0));
14599
+ ExprResult A = UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(0));
14648
14600
if (A.isInvalid())
14649
14601
return true;
14650
14602
@@ -14659,57 +14611,63 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
14659
14611
}
14660
14612
14661
14613
bool 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 ;
14667
14619
}
14668
14620
14669
14621
bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) {
14670
- QualType Res;
14671
- if (BuiltinVectorMath(TheCall, Res) )
14622
+ std::optional< QualType> Res = BuiltinVectorMath(TheCall) ;
14623
+ if (! Res)
14672
14624
return true;
14673
14625
14674
- if (auto *VecTy0 = Res->getAs<VectorType>())
14626
+ if (auto *VecTy0 = (* Res) ->getAs<VectorType>())
14675
14627
TheCall->setType(VecTy0->getElementType());
14676
14628
else
14677
- TheCall->setType(Res);
14629
+ TheCall->setType(* Res);
14678
14630
14679
14631
return false;
14680
14632
}
14681
14633
14682
- bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) {
14634
+ std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
14635
+ bool FPOnly) {
14683
14636
if (checkArgCount(TheCall, 2))
14684
- return true ;
14637
+ return std::nullopt ;
14685
14638
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);
14693
14641
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
+ }
14696
14650
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
+ }
14701
14659
14702
14660
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 ;
14705
14663
} else {
14706
- if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc() , TyA, 1))
14707
- return true ;
14664
+ if (checkMathBuiltinElementType(*this, LocA , TyA, 1))
14665
+ return std::nullopt ;
14708
14666
}
14709
14667
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 ;
14713
14671
}
14714
14672
14715
14673
bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
@@ -14719,7 +14677,8 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
14719
14677
14720
14678
Expr *Args[3];
14721
14679
for (int I = 0; I < 3; ++I) {
14722
- ExprResult Converted = UsualUnaryConversions(TheCall->getArg(I));
14680
+ ExprResult Converted =
14681
+ UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(I));
14723
14682
if (Converted.isInvalid())
14724
14683
return true;
14725
14684
Args[I] = Converted.get();
0 commit comments