diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp index f360d70cc0843..0ea6c331fe1a8 100644 --- a/lib/Sema/DerivedConformanceEquatableHashable.cpp +++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp @@ -838,7 +838,7 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) { for (auto elt : enumDecl->getAllElements()) { // case .(let a0, let a1, ...): SmallVector payloadVars; - SmallVector mixExpressions; + SmallVector combineExprs; auto payloadPattern = enumElementPayloadSubpattern(elt, 'a', hashValueDecl, payloadVars); @@ -863,7 +863,7 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) { /*implicit*/ true); auto assignExpr = new (C) AssignExpr(resultRef, SourceLoc(), ordinalExpr, /*implicit*/ true); - mixExpressions.emplace_back(ASTNode(assignExpr)); + combineExprs.emplace_back(ASTNode(assignExpr)); } if (!hasNoAssociatedValues) { @@ -873,18 +873,14 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) { auto payloadVarRef = new (C) DeclRefExpr(payloadVar, DeclNameLoc(), /*implicit*/ true); // result = _combineHashValues(result, .hashValue) - auto mixExpr = combineHashValuesAssignmentExpr(C, resultVar, - payloadVarRef); - mixExpressions.emplace_back(ASTNode(mixExpr)); + auto combineExpr = combineHashValuesAssignmentExpr(C, resultVar, + payloadVarRef); + combineExprs.emplace_back(ASTNode(combineExpr)); } - - // result = _mixInt(result) - auto assignExpr = mixIntAssignmentExpr(C, resultVar); - mixExpressions.emplace_back(ASTNode(assignExpr)); } auto hasBoundDecls = !payloadVars.empty(); - auto body = BraceStmt::create(C, SourceLoc(), mixExpressions, SourceLoc()); + auto body = BraceStmt::create(C, SourceLoc(), combineExprs, SourceLoc()); cases.push_back(CaseStmt::create(C, SourceLoc(), labelItem, hasBoundDecls, SourceLoc(), body)); } @@ -963,16 +959,12 @@ deriveBodyHashable_struct_hashValue(AbstractFunctionDecl *hashValueDecl) { auto selfPropertyExpr = new (C) DotSyntaxCallExpr(propertyRef, SourceLoc(), selfRef); // result = _combineHashValues(result, .hashValue) - auto mixExpr = combineHashValuesAssignmentExpr(C, resultVar, - selfPropertyExpr); - statements.emplace_back(ASTNode(mixExpr)); + auto combineExpr = combineHashValuesAssignmentExpr(C, resultVar, + selfPropertyExpr); + statements.emplace_back(ASTNode(combineExpr)); } { - // result = _mixInt(result) - auto assignExpr = mixIntAssignmentExpr(C, resultVar); - statements.push_back(assignExpr); - // return result auto resultRef = new (C) DeclRefExpr(resultVar, DeclNameLoc(), /*implicit*/ true, @@ -1021,7 +1013,6 @@ deriveHashable_hashValue(TypeChecker &tc, Decl *parentDecl, // result = _combineHashValues(result, a0.hashValue) // result = _combineHashValues(result, a1.hashValue) // } - // result = _mixInt(result) // return result // } // } @@ -1030,10 +1021,9 @@ deriveHashable_hashValue(TypeChecker &tc, Decl *parentDecl, // var x: Int // var y: String // @derived var hashValue: Int { - // var result: Int = 0 + // var result = 0 // result = _combineHashValues(result, x.hashValue) // result = _combineHashValues(result, y.hashValue) - // result = _mixInt(result) // return result // } // } diff --git a/stdlib/public/core/DoubleWidth.swift.gyb b/stdlib/public/core/DoubleWidth.swift.gyb index 147915a66d337..b7474bbc85635 100644 --- a/stdlib/public/core/DoubleWidth.swift.gyb +++ b/stdlib/public/core/DoubleWidth.swift.gyb @@ -154,7 +154,6 @@ extension DoubleWidth : Hashable { var result = 0 result = _combineHashValues(result, _storage.high.hashValue) result = _combineHashValues(result, _storage.low.hashValue) - result = _mixInt(result) return result } } diff --git a/stdlib/public/core/Hashing.swift b/stdlib/public/core/Hashing.swift index 9034cc52d13c3..02acd8e2b5551 100644 --- a/stdlib/public/core/Hashing.swift +++ b/stdlib/public/core/Hashing.swift @@ -203,7 +203,13 @@ func _squeezeHashValue(_ hashValue: Int, _ upperBound: Int) -> Int { @_transparent public // @testable func _combineHashValues(_ firstValue: Int, _ secondValue: Int) -> Int { - let magic = 0x9e3779b9 as UInt // Based on the golden ratio. + // Use a magic number based on the golden ratio + // (0x1.9e3779b97f4a7c15f39cc0605cedc8341082276bf3a27251f86c6a11d0c18e95p0). +#if arch(i386) || arch(arm) + let magic = 0x9e3779b9 as UInt +#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) + let magic = 0x9e3779b97f4a7c15 as UInt +#endif var x = UInt(bitPattern: firstValue) x ^= UInt(bitPattern: secondValue) &+ magic &+ (x &<< 6) &+ (x &>> 2) return Int(bitPattern: x)