new file mode 100644
@@ -0,0 +1,62 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int
+my_totalorderf (float const *x, float const *y)
+{
+ int xs = __builtin_signbit (*x);
+ int ys = __builtin_signbit (*y);
+ if (!xs != !ys)
+ return xs;
+
+ int xn = __builtin_isnan (*x);
+ int yn = __builtin_isnan (*y);
+ if (!xn != !yn)
+ return !xn == !xs;
+ if (!xn)
+ return *x <= *y;
+
+ unsigned int extended_sign = -!!xs;
+ union { unsigned int i; float f; } xu = {0}, yu = {0};
+ __builtin_memcpy (&xu.f, x, sizeof (float));
+ __builtin_memcpy (&yu.f, y, sizeof (float));
+ return (xu.i ^ extended_sign) <= (yu.i ^ extended_sign);
+}
+
+static float
+positive_NaNf ()
+{
+ float volatile nan = 0.0f / 0.0f;
+ return (__builtin_signbit (nan) ? - nan : nan);
+}
+
+typedef union { float value; unsigned int word[1]; } memory_float;
+
+static memory_float
+construct_memory_SNaNf (float quiet_value)
+{
+ memory_float m;
+ m.value = quiet_value;
+ m.word[0] ^= (unsigned int) 1 << 22;
+ m.word[0] |= (unsigned int) 1;
+ return m;
+}
+
+memory_float x[7] =
+ {
+ { 0 },
+ { 1e-5 },
+ { 1 },
+ { 1e37 },
+ { 1.0f / 0.0f },
+ };
+
+int
+main ()
+{
+ x[5] = construct_memory_SNaNf (positive_NaNf ());
+ x[6] = (memory_float) { positive_NaNf () };
+ if (! my_totalorderf (&x[5].value, &x[6].value))
+ __builtin_abort ();
+ return 0;
+}
@@ -837,6 +837,9 @@ vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2)
TYPE_VECTOR_SUBPARTS (vr2->type)))
return false;
}
+ else if (TYPE_MODE (vr1->type) != TYPE_MODE (vr2->type)
+ && !mode_can_transfer_bits (TYPE_MODE (vr1->type)))
+ return false;
i = 0;
j = 0;
@@ -5814,13 +5817,7 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
if (result
&& !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op)))
{
- /* Avoid the type punning in case the result mode has padding where
- the op we lookup has not. */
- if (TYPE_MODE (TREE_TYPE (result)) != BLKmode
- && maybe_lt (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (result))),
- GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op)))))
- result = NULL_TREE;
- else if (CONSTANT_CLASS_P (result))
+ if (CONSTANT_CLASS_P (result))
result = const_unop (VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
else
{