Commit aade772d by Jakub Jelinek Committed by Jakub Jelinek

re PR target/80102 (ICE in maybe_record_trace_start, at dwarf2cfi.c:2330)

	PR target/80102
	* reg-notes.def (REG_CFA_NOTE): Define.  Use it for CFA related
	notes.
	* cfgcleanup.c (reg_note_cfa_p): New array.
	(insns_have_identical_cfa_notes): New function.
	(old_insns_match_p): Don't cross-jump in between /f
	and non-/f instructions.  If both i1 and i2 are frame related,
	verify all CFA notes, their order and content.

	* g++.dg/opt/pr80102.C: New test.

From-SVN: r246511
parent e298b56a
2017-03-27 Jakub Jelinek <jakub@redhat.com>
PR target/80102
* reg-notes.def (REG_CFA_NOTE): Define. Use it for CFA related
notes.
* cfgcleanup.c (reg_note_cfa_p): New array.
(insns_have_identical_cfa_notes): New function.
(old_insns_match_p): Don't cross-jump in between /f
and non-/f instructions. If both i1 and i2 are frame related,
verify all CFA notes, their order and content.
2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com> 2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78543 PR target/78543
......
...@@ -1111,6 +1111,48 @@ merge_dir (enum replace_direction a, enum replace_direction b) ...@@ -1111,6 +1111,48 @@ merge_dir (enum replace_direction a, enum replace_direction b)
return dir_none; return dir_none;
} }
/* Array of flags indexed by reg note kind, true if the given
reg note is CFA related. */
static const bool reg_note_cfa_p[] = {
#undef REG_CFA_NOTE
#define DEF_REG_NOTE(NAME) false,
#define REG_CFA_NOTE(NAME) true,
#include "reg-notes.def"
#undef REG_CFA_NOTE
#undef DEF_REG_NOTE
false
};
/* Return true if I1 and I2 have identical CFA notes (the same order
and equivalent content). */
static bool
insns_have_identical_cfa_notes (rtx_insn *i1, rtx_insn *i2)
{
rtx n1, n2;
for (n1 = REG_NOTES (i1), n2 = REG_NOTES (i2); ;
n1 = XEXP (n1, 1), n2 = XEXP (n2, 1))
{
/* Skip over reg notes not related to CFI information. */
while (n1 && !reg_note_cfa_p[REG_NOTE_KIND (n1)])
n1 = XEXP (n1, 1);
while (n2 && !reg_note_cfa_p[REG_NOTE_KIND (n2)])
n2 = XEXP (n2, 1);
if (n1 == NULL_RTX && n2 == NULL_RTX)
return true;
if (n1 == NULL_RTX || n2 == NULL_RTX)
return false;
if (XEXP (n1, 0) == XEXP (n2, 0))
;
else if (XEXP (n1, 0) == NULL_RTX || XEXP (n2, 0) == NULL_RTX)
return false;
else if (!(reload_completed
? rtx_renumbered_equal_p (XEXP (n1, 0), XEXP (n2, 0))
: rtx_equal_p (XEXP (n1, 0), XEXP (n2, 0))))
return false;
}
}
/* Examine I1 and I2 and return: /* Examine I1 and I2 and return:
- dir_forward if I1 can be replaced by I2, or - dir_forward if I1 can be replaced by I2, or
- dir_backward if I2 can be replaced by I1, or - dir_backward if I2 can be replaced by I1, or
...@@ -1149,6 +1191,11 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2) ...@@ -1149,6 +1191,11 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2)
else if (p1 || p2) else if (p1 || p2)
return dir_none; return dir_none;
/* Do not allow cross-jumping between frame related insns and other
insns. */
if (RTX_FRAME_RELATED_P (i1) != RTX_FRAME_RELATED_P (i2))
return dir_none;
p1 = PATTERN (i1); p1 = PATTERN (i1);
p2 = PATTERN (i2); p2 = PATTERN (i2);
...@@ -1207,6 +1254,11 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2) ...@@ -1207,6 +1254,11 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2)
} }
} }
/* If both i1 and i2 are frame related, verify all the CFA notes
in the same order and with the same content. */
if (RTX_FRAME_RELATED_P (i1) && !insns_have_identical_cfa_notes (i1, i2))
return dir_none;
#ifdef STACK_REGS #ifdef STACK_REGS
/* If cross_jump_death_matters is not 0, the insn's mode /* If cross_jump_death_matters is not 0, the insn's mode
indicates whether or not the insn contains any stack-like indicates whether or not the insn contains any stack-like
......
...@@ -20,10 +20,16 @@ along with GCC; see the file COPYING3. If not see ...@@ -20,10 +20,16 @@ along with GCC; see the file COPYING3. If not see
/* This file defines all the codes that may appear on individual /* This file defines all the codes that may appear on individual
EXPR_LIST, INSN_LIST and INT_LIST rtxes in the REG_NOTES chain of an insn. EXPR_LIST, INSN_LIST and INT_LIST rtxes in the REG_NOTES chain of an insn.
The codes are stored in the mode field of the rtx. Source files The codes are stored in the mode field of the rtx. Source files
define DEF_REG_NOTE appropriately before including this file. */ define DEF_REG_NOTE appropriately before including this file.
CFA related notes meant for RTX_FRAME_RELATED_P instructions
should be declared with REG_CFA_NOTE macro instead of REG_NOTE. */
/* Shorthand. */ /* Shorthand. */
#define REG_NOTE(NAME) DEF_REG_NOTE (REG_##NAME) #define REG_NOTE(NAME) DEF_REG_NOTE (REG_##NAME)
#ifndef REG_CFA_NOTE
# define REG_CFA_NOTE(NAME) REG_NOTE (NAME)
#endif
/* REG_DEP_TRUE is used in scheduler dependencies lists to represent a /* REG_DEP_TRUE is used in scheduler dependencies lists to represent a
read-after-write dependency (i.e. a true data dependency). This is read-after-write dependency (i.e. a true data dependency). This is
...@@ -112,7 +118,7 @@ REG_NOTE (BR_PRED) ...@@ -112,7 +118,7 @@ REG_NOTE (BR_PRED)
/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex /* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
for DWARF to interpret what they imply. The attached rtx is used for DWARF to interpret what they imply. The attached rtx is used
instead of intuition. */ instead of intuition. */
REG_NOTE (FRAME_RELATED_EXPR) REG_CFA_NOTE (FRAME_RELATED_EXPR)
/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex /* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
for FRAME_RELATED_EXPR intuition. The insn's first pattern must be for FRAME_RELATED_EXPR intuition. The insn's first pattern must be
...@@ -122,7 +128,7 @@ REG_NOTE (FRAME_RELATED_EXPR) ...@@ -122,7 +128,7 @@ REG_NOTE (FRAME_RELATED_EXPR)
with a base register and a constant offset. In the most complicated with a base register and a constant offset. In the most complicated
cases, this will result in a DW_CFA_def_cfa_expression with the rtx cases, this will result in a DW_CFA_def_cfa_expression with the rtx
expression rendered in a dwarf location expression. */ expression rendered in a dwarf location expression. */
REG_NOTE (CFA_DEF_CFA) REG_CFA_NOTE (CFA_DEF_CFA)
/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex /* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
for FRAME_RELATED_EXPR intuition. This note adjusts the expression for FRAME_RELATED_EXPR intuition. This note adjusts the expression
...@@ -130,57 +136,57 @@ REG_NOTE (CFA_DEF_CFA) ...@@ -130,57 +136,57 @@ REG_NOTE (CFA_DEF_CFA)
expression, relative to the old CFA expression. This rtx must be of expression, relative to the old CFA expression. This rtx must be of
the form (SET new-cfa-reg (PLUS old-cfa-reg const_int)). If the note the form (SET new-cfa-reg (PLUS old-cfa-reg const_int)). If the note
rtx is NULL, we use the first SET of the insn. */ rtx is NULL, we use the first SET of the insn. */
REG_NOTE (CFA_ADJUST_CFA) REG_CFA_NOTE (CFA_ADJUST_CFA)
/* Similar to FRAME_RELATED_EXPR, with the additional information that /* Similar to FRAME_RELATED_EXPR, with the additional information that
this is a save to memory, i.e. will result in DW_CFA_offset or the this is a save to memory, i.e. will result in DW_CFA_offset or the
like. The pattern or the insn should be a simple store relative to like. The pattern or the insn should be a simple store relative to
the CFA. */ the CFA. */
REG_NOTE (CFA_OFFSET) REG_CFA_NOTE (CFA_OFFSET)
/* Similar to FRAME_RELATED_EXPR, with the additional information that this /* Similar to FRAME_RELATED_EXPR, with the additional information that this
is a save to a register, i.e. will result in DW_CFA_register. The insn is a save to a register, i.e. will result in DW_CFA_register. The insn
or the pattern should be simple reg-reg move. */ or the pattern should be simple reg-reg move. */
REG_NOTE (CFA_REGISTER) REG_CFA_NOTE (CFA_REGISTER)
/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex /* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
for FRAME_RELATED_EXPR intuition. This is a save to memory, i.e. will for FRAME_RELATED_EXPR intuition. This is a save to memory, i.e. will
result in a DW_CFA_expression. The pattern or the insn should be a result in a DW_CFA_expression. The pattern or the insn should be a
store of a register to an arbitrary (non-validated) memory address. */ store of a register to an arbitrary (non-validated) memory address. */
REG_NOTE (CFA_EXPRESSION) REG_CFA_NOTE (CFA_EXPRESSION)
/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex /* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
for FRAME_RELATED_EXPR intuition. The DWARF expression computes the value of for FRAME_RELATED_EXPR intuition. The DWARF expression computes the value of
the given register. */ the given register. */
REG_NOTE (CFA_VAL_EXPRESSION) REG_CFA_NOTE (CFA_VAL_EXPRESSION)
/* Attached to insns that are RTX_FRAME_RELATED_P, with the information /* Attached to insns that are RTX_FRAME_RELATED_P, with the information
that this is a restore operation, i.e. will result in DW_CFA_restore that this is a restore operation, i.e. will result in DW_CFA_restore
or the like. Either the attached rtx, or the destination of the insn's or the like. Either the attached rtx, or the destination of the insn's
first pattern is the register to be restored. */ first pattern is the register to be restored. */
REG_NOTE (CFA_RESTORE) REG_CFA_NOTE (CFA_RESTORE)
/* Attached to insns that are RTX_FRAME_RELATED_P, marks insn that sets /* Attached to insns that are RTX_FRAME_RELATED_P, marks insn that sets
vDRAP from DRAP. If vDRAP is a register, vdrap_reg is initalized vDRAP from DRAP. If vDRAP is a register, vdrap_reg is initalized
to the argument, if it is a MEM, it is ignored. */ to the argument, if it is a MEM, it is ignored. */
REG_NOTE (CFA_SET_VDRAP) REG_CFA_NOTE (CFA_SET_VDRAP)
/* Attached to insns that are RTX_FRAME_RELATED_P, indicating a window /* Attached to insns that are RTX_FRAME_RELATED_P, indicating a window
save operation, i.e. will result in a DW_CFA_GNU_window_save. save operation, i.e. will result in a DW_CFA_GNU_window_save.
The argument is ignored. */ The argument is ignored. */
REG_NOTE (CFA_WINDOW_SAVE) REG_CFA_NOTE (CFA_WINDOW_SAVE)
/* Attached to insns that are RTX_FRAME_RELATED_P, marks the insn as /* Attached to insns that are RTX_FRAME_RELATED_P, marks the insn as
requiring that all queued information should be flushed *before* insn, requiring that all queued information should be flushed *before* insn,
regardless of what is visible in the rtl. The argument is ignored. regardless of what is visible in the rtl. The argument is ignored.
This is normally used for a call instruction which is not exposed to This is normally used for a call instruction which is not exposed to
the rest of the compiler as a CALL_INSN. */ the rest of the compiler as a CALL_INSN. */
REG_NOTE (CFA_FLUSH_QUEUE) REG_CFA_NOTE (CFA_FLUSH_QUEUE)
/* Attached to insns that are RTX_FRAME_RELATED_P, toggling the mangling status /* Attached to insns that are RTX_FRAME_RELATED_P, toggling the mangling status
of return address. Currently it's only used by AArch64. The argument is of return address. Currently it's only used by AArch64. The argument is
ignored. */ ignored. */
REG_NOTE (CFA_TOGGLE_RA_MANGLE) REG_CFA_NOTE (CFA_TOGGLE_RA_MANGLE)
/* Indicates what exception region an INSN belongs in. This is used /* Indicates what exception region an INSN belongs in. This is used
to indicate what region to which a call may throw. REGION 0 to indicate what region to which a call may throw. REGION 0
......
2017-03-27 Jakub Jelinek <jakub@redhat.com>
PR target/80102
* g++.dg/opt/pr80102.C: New test.
2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com> 2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78543 PR target/78543
......
// PR target/80102
// { dg-do compile }
// { dg-options "-fnon-call-exceptions -Os" }
// { dg-additional-options "-mminimal-toc" { target { powerpc*-*-* && lp64 } } }
struct B { float a; B (float c) { for (int g; g < c;) ++a; } };
struct D { D (B); };
int
main ()
{
B (1.0);
D e (0.0), f (1.0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment