Hello!
As explained in the PR [1], alpha constructs a strange REG_EQUAL note
for the TFmode xfloating compare call. A recent mainline change that
tries to invalidate any buried refs trips on this note and segfaults
on null expr_list terminator:
(gdb) p debug_rtx (insn)
(insn 65 64 66 2 (set (reg:DI 148)
(reg:DI 0 $0)) ../../../gcc-svn/trunk/libgcc/libgcc2.c:1882 226 {*movdi}
(expr_list:REG_DEAD (reg:DI 0 $0)
(expr_list:REG_EQUAL (expr_list:REG_DEP_TRUE (symbol_ref:DI
("_OtsEqlX") [flags 0x41])
(expr_list:REG_DEP_TRUE (reg/v:TF 70 [ x ])
(expr_list:REG_DEP_TRUE (reg/v:TF 70 [ x ])
(nil))))
(nil))))
Proposed patch replaces expr_list sequence inside REG_EQUAL RTX with
an unspec RTX.
2013-05-23 Uros Bizjak <[email protected]>
* config/alpha/alpha.md (unspec): Add UNSPEC_XFLT_COMPARE.
* config/alpha/alpha.c (alpha_emit_xfloating_compare): Construct
REG_EQUAL note as UNSPEC_XFLT_COMPARE unspec.
Patch was bootstrapped and regression tested on alphaev68-linux-gnu.
OK for mainline and release branches?
[1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57379
Uros.
Index: config/alpha/alpha.md
===================================================================
--- config/alpha/alpha.md (revision 199131)
+++ config/alpha/alpha.md (working copy)
@@ -23,6 +23,7 @@
;; Uses of UNSPEC in this file:
(define_c_enum "unspec" [
+ UNSPEC_XFLT_COMPARE
UNSPEC_ARG_HOME
UNSPEC_LDGP1
UNSPEC_INSXH
Index: config/alpha/alpha.c
===================================================================
--- config/alpha/alpha.c (revision 199131)
+++ config/alpha/alpha.c (working copy)
@@ -3067,12 +3067,8 @@ alpha_emit_xfloating_compare (enum rtx_code *pcode
operands[1] = op1;
out = gen_reg_rtx (DImode);
- /* What's actually returned is -1,0,1, not a proper boolean value,
- so use an EXPR_LIST as with a generic libcall instead of a
- comparison type expression. */
- note = gen_rtx_EXPR_LIST (VOIDmode, op1, NULL_RTX);
- note = gen_rtx_EXPR_LIST (VOIDmode, op0, note);
- note = gen_rtx_EXPR_LIST (VOIDmode, func, note);
+ /* What's actually returned is -1,0,1, not a proper boolean value. */
+ note = gen_rtx_UNSPEC (DImode, gen_rtvec (2, op0, op1), UNSPEC_XFLT_COMPARE);
alpha_emit_xfloating_libcall (func, out, operands, 2, note);
return out;