anchor.diff:                      | _ -> raise (Exception "invalid logic")
   
                   static let pass1 =
  +                    // These do not require seperate versions based on equivalence relations, so defer to helper object
                       match pass0 with
  -                    | null -> GenericSpecializeEquals_Pass1<'a>.Func
  +                    | null -> GenericSpecializeEquals_StandardTypes<'a>.Func
                       | f -> f
   
                   static let pass2 =
                       match pass1 with
  -                    | null -> GenericSpecializeEquals_Pass3<'a>.Func
  +                    | null ->
  +                        // if we are using the ER comparer, and we are a standard f# record or value type with compiler generated
  +                        // equality operators, then we can avoid the boxing of IStructuralEquatable and just call the
  +                        // IEquatable<'a>.Equals method.
  +                        match typeof<'relation> with
  +                        | r when r.Equals typeof<EquivalenceRelation> ->
  +                            if hasFSharpCompilerGeneratedEquality<'a> () then
  +                                let equals = typeof<IEquatable<'a>>.GetMethod ("Equals", [|typeof<'a>|])
  +                                let ec = Expression.Parameter typeof<IEqualityComparer>
  +                                let a = Expression.Parameter typeof<'a>
  +                                let b = Expression.Parameter typeof<'a>
  +                                let lambda = Expression.Lambda<_> (Expression.Call (a, equals, b), ec, a, b)
  +                                lambda.Compile ()
  +                            else null
  +                        | r when r.Equals typeof<PartialEquivalenceRelation> -> null
  +                        | _ -> raise (Exception "invalid logic")
                       | f -> f
   
                   static let pass3 =
  +                    // These do not require seperate versions based on equivalence relations, so defer to helper object
                       match pass2 with
  +                    | null -> GenericSpecializeEquals_EqualityInterfaces<'a>.Func
  +                    | f -> f
  +
  +                static let pass4 =
  +                    match pass3 with
                       | null ->
  +                        // and if none of that works, then just fall back to default behavious of GenericEqualityObj
                           match typeof<'relation> with
                           | r when r.Equals typeof<PartialEquivalenceRelation> -> Func<_,_,_,_>(fun (comp:IEqualityComparer) x y -> GenericEqualityObj false comp ((box x), (box y)))
                           | r when r.Equals typeof<EquivalenceRelation>        -> Func<_,_,_,_>(fun (comp:IEqualityComparer) x y -> GenericEqualityObj true  comp ((box x), (box y)))
                           | _ -> raise (Exception "invalid logic")                    
                       | f -> f
                               
  -                static member Func = pass3
  +                static member Func = pass4
   
               /// Implements generic equality between two values, with PER semantics for NaN (so equality on two NaN values returns false)
               //
  
positive.code:                     | t when t.Equals typeof<nativeint>  -> generalize (Func<_,_,_,_>(fun _ (x:nativeint) y -> (# "ceq" x y : bool #)))
                      | t when t.Equals typeof<unativeint> -> generalize (Func<_,_,_,_>(fun _ (x:unativeint)y -> (# "ceq" x y : bool #)))
                      | t when t.Equals typeof<char>       -> generalize (Func<_,_,_,_>(fun _ (x:char)      y -> (# "ceq" x y : bool #)))
                      | t when t.Equals typeof<string>     -> generalize (Func<_,_,_,_>(fun _ (x:string)    y -> System.String.Equals(x,y)))
                      | t when t.Equals typeof<decimal>    -> generalize (Func<_,_,_,_>(fun _ (x:decimal)   y -> System.Decimal.op_Equality(x,y)))
                      | _ -> null
                              
                  static member Func = _func
  
              type GenericSpecializeEquals_Pass3<'a>() =
                  static let _func =
                      match typeof<'a> with
                      | t when t.IsArray || typeof<System.Array>.IsAssignableFrom t ->
  
negative.code:                     | t when t.IsArray || typeof<System.Array>.IsAssignableFrom t ->
                          // I could do something here, but I doubt it would have any real performance impact
                          null
  
                      | t when t.IsValueType && typeof<IStructuralEquatable>.IsAssignableFrom t ->
                          let equals = typeof<IStructuralEquatable>.GetMethod ("GetHashCode", [|typeof<IEqualityComparer>|])
                          let ec = Expression.Parameter typeof<IEqualityComparer>
                          let a = Expression.Parameter typeof<'a>
                          let lambda = Expression.Lambda<_> (Expression.Call (a, equals, ec), ec, a)
                          lambda.Compile ()
  
                      | t when typeof<IStructuralEquatable>.IsAssignableFrom t ->
                          (Func<_,_,_>(fun ec (a:'a) ->
  