[Bug target/22553] [4.6/4.7/4.8 regression] ICE building libstdc++
olegendo at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Nov 9 21:44:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22553
--- Comment #26 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-11-09 21:44:16 UTC ---
I've tried enabling sched1 on rev 193341 and ran the test suite with
make -k -j4 check
RUNTESTFLAGS="--target_board=sh-sim\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"
I got one failure for -m2a, -m4 -m4a (both, -ml and -mb):
FAIL: gcc.dg/pr42475.c (internal compiler error)
The error is:
sh_tmp.cpp: In function 'baz':
sh_tmp.cpp:25:1: error: unable to find a register to spill in class 'R0_REGS'
}
^
sh_tmp.cpp:25:1: error: this is the insn:
(insn 18 31 42 2 (parallel [
(set (subreg:SF (reg:SI 1 r1 [orig:174 D.1383+4 ] [174]) 0)
(mult:SF (reg:SF 171)
(reg:SF 65 fr1 [orig:170 p.c.z ] [170])))
(use (reg/v:PSI 151 ))
]) sh_tmp.cpp:24 426 {mulsf3_i}
(expr_list:REG_DEAD (reg:SF 171)
(expr_list:REG_DEAD (reg:SF 65 fr1 [orig:170 p.c.z ] [170])
(expr_list:REG_DEAD (reg/v:PSI 151 )
(nil)))))
sh_tmp.cpp:25:1: internal compiler error: in spill_failure, at reload1.c:2124
A GP reg is supposed to receive the result of an FP operation, which the SH
actually can't do. It has to go through FPUL.
The error occurs because sched1 hoists a load of r0 (part of the return value)
before the failing insn:
(insn 31 15 18 2 (set (reg:SI 0 r0)
(const_int 0 [0])) sh_tmp.cpp:25 244 {movsi_ie}
(nil))
(insn 18 31 42 2 (parallel [
(set (subreg:SF (reg:SI 174 [ D.1383+4 ]) 0)
(mult:SF (reg:SF 170 [ p.c.z ])
(reg:SF 171)))
....
The result value transfer from FP reg to GP reg (through FPUL) seems to go a
long way during reload, and one the insns that reload checks has a R0 clobber
(not sure which one, but there are a couple of reload insns with a =&z
constraint).
On option to fix this is to split such insns. The patch below fixes the test
case failure, but I haven't re-tested it completely.
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md (revision 193342)
+++ gcc/config/sh/sh.md (working copy)
@@ -12077,6 +12077,32 @@
[(set_attr "type" "fp")
(set_attr "fp_mode" "single")])
+;; If the output of a floating-point operation is to be stored in a GP reg
+;; the target GP output reg might be propagated as a subreg into floating-
+;; point insns. If we split the operation and the GP reg store
+;; (through FPUL) into separate insns before reload some trouble can be
+;; avoided during reload.
+(define_split
+ [(set (match_operand:SF 0 "fp_arith_reg_operand")
+ (match_operator:SF 1 "float_operator"
+ [(match_operand:SF 2 "fp_arith_reg_operand")
+ (match_operand:SF 3 "fp_arith_reg_operand")]))
+ (use (match_operand:PSI 4 "fpscr_operand"))]
+ "TARGET_SH2E
+ && can_create_pseudo_p () && GET_CODE (operands[0]) == SUBREG
+ && REG_P (SUBREG_REG (operands[0]))
+ && GET_MODE (SUBREG_REG (operands[0])) != SFmode"
+ [(parallel [(set (match_dup 5) (match_dup 6))
+ (use (match_dup 4))])
+ (parallel [(set (match_dup 0) (match_dup 5))
+ (use (match_dup 4))
+ (clobber (reg:SI FPUL_REG))])]
+{
+ operands[5] = gen_reg_rtx (SFmode);
+ operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SFmode, operands[2],
+ operands[3]);
+})
+
;; FMA (fused multiply-add) patterns
(define_expand "fmasf4"
[(set (match_operand:SF 0 "fp_arith_reg_operand" "")
Index: gcc/config/sh/predicates.md
===================================================================
--- gcc/config/sh/predicates.md (revision 193342)
+++ gcc/config/sh/predicates.md (working copy)
@@ -1156,3 +1156,9 @@
return false;
})
+
+(define_predicate "float_operator"
+ (ior (match_operand 0 "binary_float_operator")
+ (match_operand 0 "commutative_float_operator")
+ (match_operand 0 "noncommutative_float_operator")
+ (match_operand 0 "unary_float_operator")))
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c (revision 193342)
+++ gcc/config/sh/sh.c (working copy)
@@ -877,6 +877,7 @@
|| (TARGET_SHMEDIA && !TARGET_PT_FIXED))
flag_no_function_cse = 1;
+#if 0
if (targetm.small_register_classes_for_mode_p (VOIDmode)) \
{
/* Never run scheduling before reload, since that can
@@ -903,6 +904,7 @@
&& !global_options_set.x_flag_schedule_insns)
flag_schedule_insns = 0;
}
+#endif
/* Unwind info is not correct around the CFG unless either a frame
pointer is present or M_A_O_A is set. Fixing this requires rewriting
More information about the Gcc-bugs
mailing list