Hopefully fix 3-way comparisons.  This unfortunately adds yet another
hack, and it's even more disgusting than a PyInstance_Check() call.
If the tp_compare slot is the slot used for overrides in Python,
it's always called.

Add some tests that show what should work too.
diff --git a/Objects/object.c b/Objects/object.c
index c56c3be..668bd4f 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -455,11 +455,25 @@
 	/* Comparisons involving instances are given to instance_compare,
 	   which has the same return conventions as this function. */
 
+	f = v->ob_type->tp_compare;
 	if (PyInstance_Check(v))
-		return (*v->ob_type->tp_compare)(v, w);
+		return (*f)(v, w);
 	if (PyInstance_Check(w))
 		return (*w->ob_type->tp_compare)(v, w);
 
+	/* If both have the same (non-NULL) tp_compare, use it. */
+	if (f != NULL && f == w->ob_type->tp_compare) {
+		c = (*f)(v, w);
+		if (c < 0 && PyErr_Occurred())
+			return -1;
+		return c < 0 ? -1 : c > 0 ? 1 : 0;
+	}
+
+	/* If either tp_compare is _PyObject_SlotCompare, that's safe. */
+	if (f == _PyObject_SlotCompare ||
+	    w->ob_type->tp_compare == _PyObject_SlotCompare)
+		return _PyObject_SlotCompare(v, w);
+
 	/* Try coercion; if it fails, give up */
 	c = PyNumber_CoerceEx(&v, &w);
 	if (c < 0)
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 792a9f3..26ddabe 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2761,17 +2761,18 @@
 	return 2;
 }
 
-static int
-slot_tp_compare(PyObject *self, PyObject *other)
+/* This slot is published for the benefit of try_3way_compare in object.c */
+int
+_PyObject_SlotCompare(PyObject *self, PyObject *other)
 {
 	int c;
 
-	if (self->ob_type->tp_compare == slot_tp_compare) {
+	if (self->ob_type->tp_compare == _PyObject_SlotCompare) {
 		c = half_compare(self, other);
 		if (c <= 1)
 			return c;
 	}
-	if (other->ob_type->tp_compare == slot_tp_compare) {
+	if (other->ob_type->tp_compare == _PyObject_SlotCompare) {
 		c = half_compare(other, self);
 		if (c < -1)
 			return -2;
@@ -3190,7 +3191,7 @@
 	    PyDict_GetItemString(dict, "__repr__"))
 		type->tp_print = NULL;
 
-	TPSLOT("__cmp__", tp_compare, slot_tp_compare);
+	TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare);
 	TPSLOT("__repr__", tp_repr, slot_tp_repr);
 	TPSLOT("__hash__", tp_hash, slot_tp_hash);
 	TPSLOT("__call__", tp_call, slot_tp_call);