rtl: ICE with thread_local and inline asm [PR104777]

In r270550, Jakub fixed classify_insn to handle asm goto: if the asm can
jump to a label, the insn should be a JUMP_INSN.

However, as the following testcase shows, non-null ASM_OPERANDS_LABEL_VEC
doesn't guarantee that the rtx has any actual labels it can branch to.
Here, the rtvec has 0 elements because expand_asm_stmt created it:

  rtvec labelvec = rtvec_alloc (nlabels); // nlabels == 0

This causes an ICE in update_br_prob_note: BRANCH_EDGE (bb) crashes
because there's no branch edge.  I think we can fix this by checking
that there is at least one label the asm can jump to before wrapping
the ASM_OPERANDS in a JUMP_INSN.

	PR rtl-optimization/104777

gcc/ChangeLog:

	* rtl.cc (classify_insn): For ASM_OPERANDS, return JUMP_INSN only if
	ASM_OPERANDS_LABEL_VEC has at least one element.

gcc/testsuite/ChangeLog:

	* gcc.dg/torture/tls/pr104777.c: New test.
This commit is contained in:
Marek Polacek 2022-03-07 16:15:46 -05:00
parent 23ed4df521
commit e1133c0205
2 changed files with 32 additions and 2 deletions

View File

@ -765,7 +765,7 @@ classify_insn (rtx x)
return CALL_INSN;
if (ANY_RETURN_P (x))
return JUMP_INSN;
if (GET_CODE (x) == ASM_OPERANDS && ASM_OPERANDS_LABEL_VEC (x))
if (GET_CODE (x) == ASM_OPERANDS && ASM_OPERANDS_LABEL_LENGTH (x))
return JUMP_INSN;
if (GET_CODE (x) == SET)
{
@ -794,7 +794,7 @@ classify_insn (rtx x)
if (has_return_p)
return JUMP_INSN;
if (GET_CODE (XVECEXP (x, 0, 0)) == ASM_OPERANDS
&& ASM_OPERANDS_LABEL_VEC (XVECEXP (x, 0, 0)))
&& ASM_OPERANDS_LABEL_LENGTH (XVECEXP (x, 0, 0)))
return JUMP_INSN;
}
#ifdef GENERATOR_FILE

View File

@ -0,0 +1,30 @@
/* PR rtl-optimization/104777 */
/* { dg-do compile } */
/* { dg-require-effective-target tls } */
int savestate_r;
int savestate_ssb;
extern void abort();
__thread int loop;
void f (void)
{
int savestate_r0_5;
int savestate_r1_6;
__asm__("" : "=m" (savestate_ssb), "=r" (savestate_r));
savestate_r0_5 = savestate_r;
if (savestate_r0_5 == 0)
{
__asm__ __volatile__("" : : "m" (loop));
abort ();
}
__asm__("" : "=m" (savestate_ssb), "=r" (savestate_r));
savestate_r1_6 = savestate_r;
if (savestate_r1_6 != 0)
return;
__asm__ __volatile__("" : : "m" (loop));
abort ();
}