@@ -2312,8 +2312,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
2312
2312
const unsigned BuiltinIDIfNoAsmLabel =
2313
2313
FD->hasAttr<AsmLabelAttr>() ? 0 : BuiltinID;
2314
2314
2315
- bool ErrnoOverriden = false ;
2316
- // True if math-errno is overriden via the
2315
+ std::optional< bool> ErrnoOverriden;
2316
+ // ErrnoOverriden is true if math-errno is overriden via the
2317
2317
// '#pragma float_control(precise, on)'. This pragma disables fast-math,
2318
2318
// which implies math-errno.
2319
2319
if (E->hasStoredFPFeatures()) {
@@ -2329,8 +2329,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
2329
2329
// using the '#pragma float_control(precise, off)', and
2330
2330
// attribute opt-none hasn't been seen.
2331
2331
bool ErrnoOverridenToFalseWithOpt =
2332
- !ErrnoOverriden && !OptNone &&
2333
- CGM.getCodeGenOpts().OptimizationLevel != 0;
2332
+ ErrnoOverriden.has_value() && !ErrnoOverriden.value() && !OptNone &&
2333
+ CGM.getCodeGenOpts().OptimizationLevel != 0;
2334
2334
2335
2335
// There are LLVM math intrinsics/instructions corresponding to math library
2336
2336
// functions except the LLVM op will never set errno while the math library
@@ -2339,6 +2339,30 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
2339
2339
// LLVM counterparts if the call is marked 'const' (known to never set errno).
2340
2340
// In case FP exceptions are enabled, the experimental versions of the
2341
2341
// intrinsics model those.
2342
+ bool ConstAlways =
2343
+ getContext().BuiltinInfo.isConst(BuiltinID);
2344
+
2345
+ // There's a special case with the fma builtins where they are always const
2346
+ // if the target environment is GNU or the target is OS is Windows and we're
2347
+ // targeting the MSVCRT.dll environment.
2348
+ // FIXME: This list can be become outdated. Need to find a way to get it some
2349
+ // other way.
2350
+ switch (BuiltinID) {
2351
+ case Builtin::BI__builtin_fma:
2352
+ case Builtin::BI__builtin_fmaf:
2353
+ case Builtin::BI__builtin_fmal:
2354
+ case Builtin::BIfma:
2355
+ case Builtin::BIfmaf:
2356
+ case Builtin::BIfmal: {
2357
+ auto &Trip = CGM.getTriple();
2358
+ if (Trip.isGNUEnvironment() || Trip.isOSMSVCRT())
2359
+ ConstAlways = true;
2360
+ break;
2361
+ }
2362
+ default:
2363
+ break;
2364
+ }
2365
+
2342
2366
bool ConstWithoutErrnoAndExceptions =
2343
2367
getContext().BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID);
2344
2368
bool ConstWithoutExceptions =
@@ -2362,14 +2386,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
2362
2386
bool ConstWithoutErrnoOrExceptions =
2363
2387
ConstWithoutErrnoAndExceptions || ConstWithoutExceptions;
2364
2388
bool GenerateIntrinsics =
2365
- FD->hasAttr<ConstAttr>() && !ErrnoOverriden && !OptNone;
2389
+ (ConstAlways && !OptNone) ||
2390
+ (!getLangOpts().MathErrno &&
2391
+ !(ErrnoOverriden.has_value() && ErrnoOverriden.value()) && !OptNone);
2366
2392
if (!GenerateIntrinsics) {
2367
2393
GenerateIntrinsics =
2368
2394
ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
2369
2395
if (!GenerateIntrinsics)
2370
2396
GenerateIntrinsics =
2371
2397
ConstWithoutErrnoOrExceptions &&
2372
- (!getLangOpts().MathErrno && !ErrnoOverriden && !OptNone);
2398
+ (!getLangOpts().MathErrno &&
2399
+ !(ErrnoOverriden.has_value() && ErrnoOverriden.value()) && !OptNone);
2373
2400
if (!GenerateIntrinsics)
2374
2401
GenerateIntrinsics =
2375
2402
ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;
0 commit comments