Hi Joel, A few comments below:
+/* If X is a positive CONST_DOUBLE with a value that is the reciprocal of a + power of 2 (i.e 1/2^n) return the number of float bits. e.g. for x==(1/2^n) + return log2 (n). Otherwise return 0. */ +int +aarch64_fpconst_pow2_recip (rtx x) +{ + REAL_VALUE_TYPE r0; + + if (!CONST_DOUBLE_P (x)) + return 0; + + r0 = *CONST_DOUBLE_REAL_VALUE (x); + if (exact_real_inverse (DFmode, &r0) + && !REAL_VALUE_NEGATIVE (r0)) + { + if (exact_real_truncate (DFmode, &r0)) Truncate to double? That doesn't do anything... + { + HOST_WIDE_INT value = real_to_integer (&r0); + value = value & 0xffffffff; + if ((value != 0) && ( (value & (value - 1)) == 0)) + { + int ret = exact_log2 (value); + gcc_assert (IN_RANGE (ret, 0, 31)); + return ret; + } Wouldn't it be easier to just do exact_log2 (real_to_integer (&r0)) and then check the range is in 1..31? --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -6016,6 +6016,40 @@ [(set_attr "type" "f_cvtf2i")] ) +(define_insn "*aarch64_<su_optab>cvtf_<fcvt_target>_<GPF:mode>2_mult" + [(set (match_operand:GPF 0 "register_operand" "=w,w") + (mult:GPF (FLOATUORS:GPF + (match_operand:<FCVT_TARGET> 1 "register_operand" "w,?r")) + (match_operand 2 "aarch64_fp_pow2_recip""Dt,Dt")))] We should add a comment before both define_insn similar to the other conversions, explaining what they do and why there are 2 separate patterns (the default versions of the conversions appear to be missing a comment too). Wilco