Skip to content

Commit bc3a15f

Browse files
committed
[CSOptimizer] Disable CGFloat -> Double conversion for unary operators
Some of the unary operators, i.e. prefix `-`, don't have CGFloat variants and expect generic `FloatingPoint` overload to match CGFloat type. Let's not attempt `CGFloat` -> `Double` conversion for unary operators because it always leads to a worse solutions vs. generic overloads.
1 parent 860ae08 commit bc3a15f

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ static void determineBestChoicesInContext(
490490
OnParam = 0x01,
491491
Literal = 0x02,
492492
ExactOnly = 0x04,
493+
DisableCGFloatDoubleConversion = 0x08,
493494
};
494495

495496
using MatchOptions = OptionSet<MatchFlag>;
@@ -518,13 +519,20 @@ static void determineBestChoicesInContext(
518519
return a->getDesugaredType()->isEqual(b->getDesugaredType());
519520
};
520521

522+
auto isCGFloatDoubleConversionSupported = [&options]() {
523+
// CGFloat <-> Double conversion is supposed only while
524+
// match argument candidates to parameters.
525+
return options.contains(MatchFlag::OnParam) &&
526+
!options.contains(MatchFlag::DisableCGFloatDoubleConversion);
527+
};
528+
521529
// Allow CGFloat -> Double widening conversions between
522530
// candidate argument types and parameter types. This would
523531
// make sure that Double is always preferred over CGFloat
524532
// when using literals and ranking supported disjunction
525533
// choices. Narrowing conversion (Double -> CGFloat) should
526534
// be delayed as much as possible.
527-
if (options.contains(MatchFlag::OnParam)) {
535+
if (isCGFloatDoubleConversionSupported()) {
528536
if (candidateType->isCGFloat() && paramType->isDouble()) {
529537
return options.contains(MatchFlag::Literal) ? 0.2 : 0.9;
530538
}
@@ -854,6 +862,16 @@ static void determineBestChoicesInContext(
854862
if (favorExactMatchesOnly)
855863
options |= MatchFlag::ExactOnly;
856864

865+
// Disable CGFloat -> Double conversion for unary operators.
866+
//
867+
// Some of the unary operators, i.e. prefix `-`, don't have
868+
// CGFloat variants and expect generic `FloatingPoint` overload
869+
// to match CGFloat type. Let's not attempt `CGFloat` -> `Double`
870+
// conversion for unary operators because it always leads
871+
// to a worse solutions vs. generic overloads.
872+
if (n == 1 && decl->isOperator())
873+
options |= MatchFlag::DisableCGFloatDoubleConversion;
874+
857875
auto candidateScore = scoreCandidateMatch(
858876
genericSig, candidateType, paramType, options);
859877

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1
2+
3+
// REQUIRES: OS=macosx,no_asan
4+
// REQUIRES: objc_interop
5+
6+
import Foundation
7+
import CoreGraphics
8+
import simd
9+
10+
func test(
11+
a: CGFloat,
12+
b: CGFloat
13+
) -> CGFloat {
14+
exp(-a * b) *
15+
(a * -sin(a * b) * a + ((a * b + a) / b) * cos(a * b) * a) +
16+
exp(-a * b) *
17+
(-b) *
18+
(a * cos(a * b) + ((a * b + a) / b) * sin(a * b))
19+
}

0 commit comments

Comments
 (0)