https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83964

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |carll at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I guess this regressed with r253238 when these builtins were introduced.
I actually see multiple issues with these builtins:
1) as written above, lrintsfsi2 condition is TARGET_SF_FPR && TARGET_FPRND,
ditto lrintsfdi2 and lrintdfdi2 condition is TARGET_DF_FPR && TARGET_FPRND.
The builtins def file says just RS6000_BTM_HARD_FLOAT as the requirement, which
isn't enough, we also need TARGET_FPRND and for one of the builtins
TARGET_SF_FPR, for the other TARGET_DF_FPR.  Changing
BU_FP_MISC_1 to require even (RS6000_BTM_HARD_FLOAT | RS6000_BTM_CELL)
doesn't work, then the builtin is refused on all CPUs but -mcpu=cell.
So, do we need to introduce two new RS6000_BTM_* values for these two builtins
and arrange for the right tests for them to be done?
2) with -mcpu=power6 or -mcpu=power7
long
f1 (float x)
{
  return __builtin_fctid (x);
}

long
f2 (double x)
{
  return __builtin_fctid (x);
}

int
f3 (float x)
{
  return __builtin_fctiw (x);
}

int
f4 (double x)
{
  return __builtin_fctiw (x);
}
ICEs in LRA instead:
pr83964.c: In function ‘f3’:
pr83964.c:24:1: error: unable to generate reloads for:
 }
 ^
(insn 7 6 8 2 (set (reg:SI 124)
        (unspec:SI [
                (reg:DF 121 [ _1 ])
            ] UNSPEC_FCTIW)) "pr83964.c":23 419 {lrintsfsi2}
     (expr_list:REG_DEAD (reg:DF 121 [ _1 ])
        (nil)))
during RTL pass: reload
pr83964.c:24:1: internal compiler error: in curr_insn_transform, at
lra-constraints.c:3884
0xdc05c5 _fatal_insn(char const*, rtx_def const*, char const*, int, char
const*)

Either the rs6000 builtins expansion code for __builtin_fctiw float_truncate
the operand so that it is SFmode rather than DFmode, or it shouldn't use
lrintsf* code, but some other for an expander that adds the float_truncate.

What is the point of these builtins, i.e. what is the advantage of them over a
C cast from float or double to int or long?

Reply via email to