diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index d220fdf4dc8a7..e948778495bd4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -211,6 +211,359 @@ static RValue emitBuiltinAlloca(CIRGenFunction &cgf, const CallExpr *e, allocaAddr, builder.getVoidPtrTy(cgf.getCIRAllocaAddressSpace()))); } +static RValue tryEmitFPMathIntrinsic(CIRGenFunction &cgf, const CallExpr *e, + unsigned builtinID) { + switch (builtinID) { + case Builtin::BIacos: + case Builtin::BIacosf: + case Builtin::BIacosl: + case Builtin::BI__builtin_acos: + case Builtin::BI__builtin_acosf: + case Builtin::BI__builtin_acosf16: + case Builtin::BI__builtin_acosl: + case Builtin::BI__builtin_acosf128: + case Builtin::BI__builtin_elementwise_acos: + case Builtin::BIasin: + case Builtin::BIasinf: + case Builtin::BIasinl: + case Builtin::BI__builtin_asin: + case Builtin::BI__builtin_asinf: + case Builtin::BI__builtin_asinf16: + case Builtin::BI__builtin_asinl: + case Builtin::BI__builtin_asinf128: + case Builtin::BI__builtin_elementwise_asin: + case Builtin::BIatan: + case Builtin::BIatanf: + case Builtin::BIatanl: + case Builtin::BI__builtin_atan: + case Builtin::BI__builtin_atanf: + case Builtin::BI__builtin_atanf16: + case Builtin::BI__builtin_atanl: + case Builtin::BI__builtin_atanf128: + case Builtin::BI__builtin_elementwise_atan: + case Builtin::BIatan2: + case Builtin::BIatan2f: + case Builtin::BIatan2l: + case Builtin::BI__builtin_atan2: + case Builtin::BI__builtin_atan2f: + case Builtin::BI__builtin_atan2f16: + case Builtin::BI__builtin_atan2l: + case Builtin::BI__builtin_atan2f128: + case Builtin::BI__builtin_elementwise_atan2: + return RValue::getIgnored(); + case Builtin::BIceil: + case Builtin::BIceilf: + case Builtin::BIceill: + case Builtin::BI__builtin_ceil: + case Builtin::BI__builtin_ceilf: + case Builtin::BI__builtin_ceilf16: + case Builtin::BI__builtin_ceill: + case Builtin::BI__builtin_ceilf128: + assert(!cir::MissingFeatures::fastMathFlags()); + return emitUnaryMaybeConstrainedFPBuiltin(cgf, *e); + case Builtin::BI__builtin_elementwise_ceil: + case Builtin::BIcopysign: + case Builtin::BIcopysignf: + case Builtin::BIcopysignl: + case Builtin::BI__builtin_copysign: + case Builtin::BI__builtin_copysignf: + case Builtin::BI__builtin_copysignf16: + case Builtin::BI__builtin_copysignl: + case Builtin::BI__builtin_copysignf128: + return RValue::getIgnored(); + case Builtin::BIcos: + case Builtin::BIcosf: + case Builtin::BIcosl: + case Builtin::BI__builtin_cos: + case Builtin::BI__builtin_cosf: + case Builtin::BI__builtin_cosf16: + case Builtin::BI__builtin_cosl: + case Builtin::BI__builtin_cosf128: + assert(!cir::MissingFeatures::fastMathFlags()); + return emitUnaryMaybeConstrainedFPBuiltin(cgf, *e); + case Builtin::BI__builtin_elementwise_cos: + case Builtin::BIcosh: + case Builtin::BIcoshf: + case Builtin::BIcoshl: + case Builtin::BI__builtin_cosh: + case Builtin::BI__builtin_coshf: + case Builtin::BI__builtin_coshf16: + case Builtin::BI__builtin_coshl: + case Builtin::BI__builtin_coshf128: + case Builtin::BI__builtin_elementwise_cosh: + return RValue::getIgnored(); + case Builtin::BIexp: + case Builtin::BIexpf: + case Builtin::BIexpl: + case Builtin::BI__builtin_exp: + case Builtin::BI__builtin_expf: + case Builtin::BI__builtin_expf16: + case Builtin::BI__builtin_expl: + case Builtin::BI__builtin_expf128: + assert(!cir::MissingFeatures::fastMathFlags()); + return emitUnaryMaybeConstrainedFPBuiltin(cgf, *e); + case Builtin::BI__builtin_elementwise_exp: + case Builtin::BIexp2: + case Builtin::BIexp2f: + case Builtin::BIexp2l: + case Builtin::BI__builtin_exp2: + case Builtin::BI__builtin_exp2f: + case Builtin::BI__builtin_exp2f16: + case Builtin::BI__builtin_exp2l: + case Builtin::BI__builtin_exp2f128: + case Builtin::BI__builtin_elementwise_exp2: + case Builtin::BI__builtin_exp10: + case Builtin::BI__builtin_exp10f: + case Builtin::BI__builtin_exp10f16: + case Builtin::BI__builtin_exp10l: + case Builtin::BI__builtin_exp10f128: + case Builtin::BI__builtin_elementwise_exp10: + return RValue::getIgnored(); + case Builtin::BIfabs: + case Builtin::BIfabsf: + case Builtin::BIfabsl: + case Builtin::BI__builtin_fabs: + case Builtin::BI__builtin_fabsf: + case Builtin::BI__builtin_fabsf16: + case Builtin::BI__builtin_fabsl: + case Builtin::BI__builtin_fabsf128: + return emitUnaryMaybeConstrainedFPBuiltin(cgf, *e); + case Builtin::BIfloor: + case Builtin::BIfloorf: + case Builtin::BIfloorl: + case Builtin::BI__builtin_floor: + case Builtin::BI__builtin_floorf: + case Builtin::BI__builtin_floorf16: + case Builtin::BI__builtin_floorl: + case Builtin::BI__builtin_floorf128: + case Builtin::BI__builtin_elementwise_floor: + case Builtin::BIfma: + case Builtin::BIfmaf: + case Builtin::BIfmal: + case Builtin::BI__builtin_fma: + case Builtin::BI__builtin_fmaf: + case Builtin::BI__builtin_fmaf16: + case Builtin::BI__builtin_fmal: + case Builtin::BI__builtin_fmaf128: + case Builtin::BI__builtin_elementwise_fma: + case Builtin::BIfmax: + case Builtin::BIfmaxf: + case Builtin::BIfmaxl: + case Builtin::BI__builtin_fmax: + case Builtin::BI__builtin_fmaxf: + case Builtin::BI__builtin_fmaxf16: + case Builtin::BI__builtin_fmaxl: + case Builtin::BI__builtin_fmaxf128: + case Builtin::BIfmin: + case Builtin::BIfminf: + case Builtin::BIfminl: + case Builtin::BI__builtin_fmin: + case Builtin::BI__builtin_fminf: + case Builtin::BI__builtin_fminf16: + case Builtin::BI__builtin_fminl: + case Builtin::BI__builtin_fminf128: + case Builtin::BIfmaximum_num: + case Builtin::BIfmaximum_numf: + case Builtin::BIfmaximum_numl: + case Builtin::BI__builtin_fmaximum_num: + case Builtin::BI__builtin_fmaximum_numf: + case Builtin::BI__builtin_fmaximum_numf16: + case Builtin::BI__builtin_fmaximum_numl: + case Builtin::BI__builtin_fmaximum_numf128: + case Builtin::BIfminimum_num: + case Builtin::BIfminimum_numf: + case Builtin::BIfminimum_numl: + case Builtin::BI__builtin_fminimum_num: + case Builtin::BI__builtin_fminimum_numf: + case Builtin::BI__builtin_fminimum_numf16: + case Builtin::BI__builtin_fminimum_numl: + case Builtin::BI__builtin_fminimum_numf128: + case Builtin::BIfmod: + case Builtin::BIfmodf: + case Builtin::BIfmodl: + case Builtin::BI__builtin_fmod: + case Builtin::BI__builtin_fmodf: + case Builtin::BI__builtin_fmodf16: + case Builtin::BI__builtin_fmodl: + case Builtin::BI__builtin_fmodf128: + case Builtin::BI__builtin_elementwise_fmod: + case Builtin::BIlog: + case Builtin::BIlogf: + case Builtin::BIlogl: + case Builtin::BI__builtin_log: + case Builtin::BI__builtin_logf: + case Builtin::BI__builtin_logf16: + case Builtin::BI__builtin_logl: + case Builtin::BI__builtin_logf128: + case Builtin::BI__builtin_elementwise_log: + case Builtin::BIlog10: + case Builtin::BIlog10f: + case Builtin::BIlog10l: + case Builtin::BI__builtin_log10: + case Builtin::BI__builtin_log10f: + case Builtin::BI__builtin_log10f16: + case Builtin::BI__builtin_log10l: + case Builtin::BI__builtin_log10f128: + case Builtin::BI__builtin_elementwise_log10: + case Builtin::BIlog2: + case Builtin::BIlog2f: + case Builtin::BIlog2l: + case Builtin::BI__builtin_log2: + case Builtin::BI__builtin_log2f: + case Builtin::BI__builtin_log2f16: + case Builtin::BI__builtin_log2l: + case Builtin::BI__builtin_log2f128: + case Builtin::BI__builtin_elementwise_log2: + case Builtin::BInearbyint: + case Builtin::BInearbyintf: + case Builtin::BInearbyintl: + case Builtin::BI__builtin_nearbyint: + case Builtin::BI__builtin_nearbyintf: + case Builtin::BI__builtin_nearbyintl: + case Builtin::BI__builtin_nearbyintf128: + case Builtin::BI__builtin_elementwise_nearbyint: + case Builtin::BIpow: + case Builtin::BIpowf: + case Builtin::BIpowl: + case Builtin::BI__builtin_pow: + case Builtin::BI__builtin_powf: + case Builtin::BI__builtin_powf16: + case Builtin::BI__builtin_powl: + case Builtin::BI__builtin_powf128: + case Builtin::BI__builtin_elementwise_pow: + case Builtin::BIrint: + case Builtin::BIrintf: + case Builtin::BIrintl: + case Builtin::BI__builtin_rint: + case Builtin::BI__builtin_rintf: + case Builtin::BI__builtin_rintf16: + case Builtin::BI__builtin_rintl: + case Builtin::BI__builtin_rintf128: + case Builtin::BI__builtin_elementwise_rint: + case Builtin::BIround: + case Builtin::BIroundf: + case Builtin::BIroundl: + case Builtin::BI__builtin_round: + case Builtin::BI__builtin_roundf: + case Builtin::BI__builtin_roundf16: + case Builtin::BI__builtin_roundl: + case Builtin::BI__builtin_roundf128: + case Builtin::BI__builtin_elementwise_round: + case Builtin::BIroundeven: + case Builtin::BIroundevenf: + case Builtin::BIroundevenl: + case Builtin::BI__builtin_roundeven: + case Builtin::BI__builtin_roundevenf: + case Builtin::BI__builtin_roundevenf16: + case Builtin::BI__builtin_roundevenl: + case Builtin::BI__builtin_roundevenf128: + case Builtin::BI__builtin_elementwise_roundeven: + case Builtin::BIsin: + case Builtin::BIsinf: + case Builtin::BIsinl: + case Builtin::BI__builtin_sin: + case Builtin::BI__builtin_sinf: + case Builtin::BI__builtin_sinf16: + case Builtin::BI__builtin_sinl: + case Builtin::BI__builtin_sinf128: + case Builtin::BI__builtin_elementwise_sin: + case Builtin::BIsinh: + case Builtin::BIsinhf: + case Builtin::BIsinhl: + case Builtin::BI__builtin_sinh: + case Builtin::BI__builtin_sinhf: + case Builtin::BI__builtin_sinhf16: + case Builtin::BI__builtin_sinhl: + case Builtin::BI__builtin_sinhf128: + case Builtin::BI__builtin_elementwise_sinh: + case Builtin::BI__builtin_sincospi: + case Builtin::BI__builtin_sincospif: + case Builtin::BI__builtin_sincospil: + case Builtin::BIsincos: + case Builtin::BIsincosf: + case Builtin::BIsincosl: + case Builtin::BI__builtin_sincos: + case Builtin::BI__builtin_sincosf: + case Builtin::BI__builtin_sincosf16: + case Builtin::BI__builtin_sincosl: + case Builtin::BI__builtin_sincosf128: + case Builtin::BIsqrt: + case Builtin::BIsqrtf: + case Builtin::BIsqrtl: + case Builtin::BI__builtin_sqrt: + case Builtin::BI__builtin_sqrtf: + case Builtin::BI__builtin_sqrtf16: + case Builtin::BI__builtin_sqrtl: + case Builtin::BI__builtin_sqrtf128: + case Builtin::BI__builtin_elementwise_sqrt: + case Builtin::BItan: + case Builtin::BItanf: + case Builtin::BItanl: + case Builtin::BI__builtin_tan: + case Builtin::BI__builtin_tanf: + case Builtin::BI__builtin_tanf16: + case Builtin::BI__builtin_tanl: + case Builtin::BI__builtin_tanf128: + case Builtin::BI__builtin_elementwise_tan: + case Builtin::BItanh: + case Builtin::BItanhf: + case Builtin::BItanhl: + case Builtin::BI__builtin_tanh: + case Builtin::BI__builtin_tanhf: + case Builtin::BI__builtin_tanhf16: + case Builtin::BI__builtin_tanhl: + case Builtin::BI__builtin_tanhf128: + case Builtin::BI__builtin_elementwise_tanh: + case Builtin::BItrunc: + case Builtin::BItruncf: + case Builtin::BItruncl: + case Builtin::BI__builtin_trunc: + case Builtin::BI__builtin_truncf: + case Builtin::BI__builtin_truncf16: + case Builtin::BI__builtin_truncl: + case Builtin::BI__builtin_truncf128: + case Builtin::BI__builtin_elementwise_trunc: + case Builtin::BIlround: + case Builtin::BIlroundf: + case Builtin::BIlroundl: + case Builtin::BI__builtin_lround: + case Builtin::BI__builtin_lroundf: + case Builtin::BI__builtin_lroundl: + case Builtin::BI__builtin_lroundf128: + case Builtin::BIllround: + case Builtin::BIllroundf: + case Builtin::BIllroundl: + case Builtin::BI__builtin_llround: + case Builtin::BI__builtin_llroundf: + case Builtin::BI__builtin_llroundl: + case Builtin::BI__builtin_llroundf128: + case Builtin::BIlrint: + case Builtin::BIlrintf: + case Builtin::BIlrintl: + case Builtin::BI__builtin_lrint: + case Builtin::BI__builtin_lrintf: + case Builtin::BI__builtin_lrintl: + case Builtin::BI__builtin_lrintf128: + case Builtin::BIllrint: + case Builtin::BIllrintf: + case Builtin::BIllrintl: + case Builtin::BI__builtin_llrint: + case Builtin::BI__builtin_llrintf: + case Builtin::BI__builtin_llrintl: + case Builtin::BI__builtin_llrintf128: + case Builtin::BI__builtin_ldexp: + case Builtin::BI__builtin_ldexpf: + case Builtin::BI__builtin_ldexpl: + case Builtin::BI__builtin_ldexpf16: + case Builtin::BI__builtin_ldexpf128: + case Builtin::BI__builtin_elementwise_ldexp: + default: + break; + } + + return RValue::getIgnored(); +} + RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, const CallExpr *e, ReturnValueSlot returnValue) { @@ -244,7 +597,36 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, // likely to get lowered to the renamed library functions. unsigned builtinIDIfNoAsmLabel = fd->hasAttr() ? 0 : builtinID; - assert(!cir::MissingFeatures::builtinCallMathErrno()); + std::optional errnoOverriden; + // ErrnoOverriden is true if math-errno is overriden via the + // '#pragma float_control(precise, on)'. This pragma disables fast-math, + // which implies math-errno. + if (e->hasStoredFPFeatures()) { + FPOptionsOverride op = e->getFPFeatures(); + if (op.hasMathErrnoOverride()) + errnoOverriden = op.getMathErrnoOverride(); + } + // True if 'attribute__((optnone))' is used. This attribute overrides + // fast-math which implies math-errno. + bool optNone = curFuncDecl && curFuncDecl->hasAttr(); + + bool isOptimizationEnabled = cgm.getCodeGenOpts().OptimizationLevel != 0; + + bool generateFPMathIntrinsics = + getContext().BuiltinInfo.shouldGenerateFPMathIntrinsic( + builtinID, cgm.getTriple(), errnoOverriden, getLangOpts().MathErrno, + optNone, isOptimizationEnabled); + + if (generateFPMathIntrinsics) { + // Try to match the builtinID with a floating point math builtin. + RValue rv = tryEmitFPMathIntrinsic(*this, e, builtinIDIfNoAsmLabel); + + // Return the result directly if a math intrinsic was generated. + if (!rv.isIgnored()) { + return rv; + } + } + assert(!cir::MissingFeatures::builtinCall()); switch (builtinIDIfNoAsmLabel) { @@ -267,48 +649,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, emitVAEnd(emitVAListRef(e->getArg(0)).getPointer()); return {}; - case Builtin::BIcos: - case Builtin::BIcosf: - case Builtin::BIcosl: - case Builtin::BI__builtin_cos: - case Builtin::BI__builtin_cosf: - case Builtin::BI__builtin_cosf16: - case Builtin::BI__builtin_cosl: - case Builtin::BI__builtin_cosf128: - assert(!cir::MissingFeatures::fastMathFlags()); - return emitUnaryMaybeConstrainedFPBuiltin(*this, *e); - - case Builtin::BIceil: - case Builtin::BIceilf: - case Builtin::BIceill: - case Builtin::BI__builtin_ceil: - case Builtin::BI__builtin_ceilf: - case Builtin::BI__builtin_ceilf16: - case Builtin::BI__builtin_ceill: - case Builtin::BI__builtin_ceilf128: - assert(!cir::MissingFeatures::fastMathFlags()); - return emitUnaryMaybeConstrainedFPBuiltin(*this, *e); - - case Builtin::BIexp: - case Builtin::BIexpf: - case Builtin::BIexpl: - case Builtin::BI__builtin_exp: - case Builtin::BI__builtin_expf: - case Builtin::BI__builtin_expf16: - case Builtin::BI__builtin_expl: - case Builtin::BI__builtin_expf128: - assert(!cir::MissingFeatures::fastMathFlags()); - return emitUnaryMaybeConstrainedFPBuiltin(*this, *e); - - case Builtin::BIfabs: - case Builtin::BIfabsf: - case Builtin::BIfabsl: - case Builtin::BI__builtin_fabs: - case Builtin::BI__builtin_fabsf: - case Builtin::BI__builtin_fabsf16: - case Builtin::BI__builtin_fabsl: - case Builtin::BI__builtin_fabsf128: - return emitUnaryMaybeConstrainedFPBuiltin(*this, *e); case Builtin::BI__assume: case Builtin::BI__builtin_assume: {