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?