diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3255,34 +3255,33 @@ } } +static bool isPPC_64Builtin(unsigned BuiltinID) { + // These builtins only work on PPC 64bit targets. + switch (BuiltinID) { + case PPC::BI__builtin_divde: + case PPC::BI__builtin_divdeu: + case PPC::BI__builtin_bpermd: + return true; + } + return false; +} + +static bool SemaFeatureCheck(Sema &S, CallExpr *TheCall, + StringRef FeatureToCheck, unsigned DiagID) { + if (!S.Context.getTargetInfo().hasFeature(FeatureToCheck)) + return S.Diag(TheCall->getBeginLoc(), DiagID) << TheCall->getSourceRange(); + return false; +}; + bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall) { unsigned i = 0, l = 0, u = 0; - bool Is64BitBltin = BuiltinID == PPC::BI__builtin_divde || - BuiltinID == PPC::BI__builtin_divdeu || - BuiltinID == PPC::BI__builtin_bpermd; bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64; - bool IsBltinExtDiv = BuiltinID == PPC::BI__builtin_divwe || - BuiltinID == PPC::BI__builtin_divweu || - BuiltinID == PPC::BI__builtin_divde || - BuiltinID == PPC::BI__builtin_divdeu; - if (Is64BitBltin && !IsTarget64Bit) + if (isPPC_64Builtin(BuiltinID) && !IsTarget64Bit) return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt) << TheCall->getSourceRange(); - if ((IsBltinExtDiv && !TI.hasFeature("extdiv")) || - (BuiltinID == PPC::BI__builtin_bpermd && !TI.hasFeature("bpermd"))) - return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_only_on_pwr7) - << TheCall->getSourceRange(); - - auto SemaVSXCheck = [&](CallExpr *TheCall) -> bool { - if (!TI.hasFeature("vsx")) - return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_only_on_pwr7) - << TheCall->getSourceRange(); - return false; - }; - switch (BuiltinID) { default: return false; case PPC::BI__builtin_altivec_crypto_vshasigmaw: @@ -3308,11 +3307,22 @@ case PPC::BI__builtin_vsx_xxpermdi: case PPC::BI__builtin_vsx_xxsldwi: return SemaBuiltinVSX(TheCall); + case PPC::BI__builtin_divwe: + case PPC::BI__builtin_divweu: + case PPC::BI__builtin_divde: + case PPC::BI__builtin_divdeu: + return SemaFeatureCheck(*this, TheCall, "extdiv", + diag::err_ppc_builtin_only_on_pwr7); + case PPC::BI__builtin_bpermd: + return SemaFeatureCheck(*this, TheCall, "bpermd", + diag::err_ppc_builtin_only_on_pwr7); case PPC::BI__builtin_unpack_vector_int128: - return SemaVSXCheck(TheCall) || + return SemaFeatureCheck(*this, TheCall, "vsx", + diag::err_ppc_builtin_only_on_pwr7) || SemaBuiltinConstantArgRange(TheCall, 1, 0, 1); case PPC::BI__builtin_pack_vector_int128: - return SemaVSXCheck(TheCall); + return SemaFeatureCheck(*this, TheCall, "vsx", + diag::err_ppc_builtin_only_on_pwr7); case PPC::BI__builtin_altivec_vgnb: return SemaBuiltinConstantArgRange(TheCall, 1, 2, 7); case PPC::BI__builtin_altivec_vec_replace_elt: