On 16/09/16 20:49, Jeff Law wrote:
On 09/12/2016 10:19 AM, Tamar Christina wrote:
Hi All,
+
+      /* Re-interpret the float as an unsigned integer type
+     with equal precision.  */
+ int_arg_type = build_nonstandard_integer_type (TYPE_PRECISION (type), 0);
+      int_arg = fold_build1_loc (loc, INDIRECT_REF, int_arg_type,
+          fold_build1_loc (loc, NOP_EXPR,
+                   build_pointer_type (int_arg_type),
+            fold_build1_loc (loc, ADDR_EXPR,
+                     build_pointer_type (type), arg)));
Doesn't this make ARG addressable? Which in turn means ARG won't be exposed to the gimple/ssa optimizers. Or is it the case that when fpclassify is used its argument is already in memory (and thus addressable?)

I believe that it is the case that when fpclassify is use the argument is already addressable, but I am not 100% certain. I may be able to do this differently so I'll
come back to you on this one.
+                         exp, const1));
+
+      /* Combine the values together.  */
+ specials = fold_build3_loc (loc, COND_EXPR, int_type, zero_check, fp_zero,
+           fold_build3_loc (loc, COND_EXPR, int_type, exp_lsb_set,
+ fold_build3_loc (loc, COND_EXPR, int_type, mantissa_any_set,
+              HONOR_NANS (mode) ? fp_nan : fp_normal,
+              HONOR_INFINITIES (mode) ? fp_infinite : fp_normal),
+            fp_subnormal));
So this implies you're running on generic, not gimple, right? Otherwise you can't generate these kinds of expressions.


Yes this is generic.

diff --git a/gcc/real.h b/gcc/real.h
index 59af580e78f2637be84f71b98b45ec6611053222..36ded57cf4db7c30c935bdb24219a167480f39c8 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -161,6 +161,15 @@ struct real_format
   bool has_signed_zero;
   bool qnan_msb_set;
   bool canonical_nan_lsbs_set;
+
+ /* This flag indicates whether the format can be used in the optimized
+     code paths for the __builtin_fpclassify function and friends.
+ The format has to have the same NaN and INF representation as normal + IEEE floats (e.g. exp must have all bits set), most significant bit must be + sign bit, followed by exp bits of at most 32 bits. Lastly the floating + point number must be representable as an integer. The base of the number
+     also must be base 2.  */
+  bool is_binary_ieee_compatible;
   const char *name;
 };
I think Joseph has already commented on the contents of the initializer and a few more cases were we can use the optimized paths.

However, I do have a general question. There are some targets which have FPUs that are basically IEEE, but don't support certain IEEE features like NaNs, denorms, etc.

Presumably all that's needed is for those targets to define a hook to describe which checks will always be false and you can check the hook's return value. Right?

Yes, that should be enough. Not supporting NAN and Infinities is already supported though, but it's tied to the real format rather than a particular target.

Can you please include some tests to verify you're getting the initial code generation you want? Ideally there'd be execution tests too where you generate one of the special nodes, then call the __builtin and verify that you get the expected results back. The latter in particular are key since it'll allow us to catch problems much earlier across the wide variety of targets GCC supports.

I can add some code generation tests. There are I believe already some execution tests, which test both correct and incorrect output.

I think you already had plans to post an updated patch. Please include the fixes noted above in that update.

Yes I will include your feedback in it. I'm currently waiting for some extra performance numbers.

Thanks,
Tamar

Reply via email to