Code in optabs.c for directly expanding some operations checks the number of operands in the expander/named pattern against the expected number of operands. If they do not match an ICE is triggered. /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS) as its operands. Return the instruction pattern on success, and emit any necessary set-up code. Return null and emit no code on failure. */ rtx_insn * maybe_gen_insn (enum insn_code icode, unsigned int nops, struct expand_operand *ops) { gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args); [ ... ] On a target with recip or rsqrt patterns written in the expected way we'll trigger the ICE because those patterns expose the recip as a division with 1.0 as an operand, thus creating a second, unexpected operand This showed up testing v850e3v5. It looks like some targets hide things a bit behind an unspec, possibly to avoid this problem. This patch does something very similar for the v850: (define_expand "rsqrtsf2" [(set (match_operand:SF 0 "register_operand" "=") (unspec:SF [(match_operand:SF 1 "register_operand" "")] UNSPEC_RSQRT))] We then generate a more normal looking pattern from the expander which matches: (define_insn "rsqrtsf2_insn" [(set (match_operand:SF 0 "register_operand" "=r") (div:SF (match_operand:SF 1 "const_float_1_operand" "") (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))] While looking at this I noticed that const_float_1_operand would essentially reject everything. It had a toplevel check that the operand was a CONST_INT. But in the body of the predicate it would reject anything that was not a CONST_DOUBLE. The right code is CONST_DOUBLE. So this patch also fixes const_float_1_operand. This fixes a handful of ICEs when testing for v850e3v5 (pr41963, pr46728-9. It also results in many recipf instructions being generated for newlib v850e3v5 multilib whereas none were generated before. There's no uses of rsqrt in newlib, but they do show up in the gcc testsuite. Installing on the trunk, Jeff