mirror of git://gcc.gnu.org/git/gcc.git
re PR c/24414 (Old-style asms don't clobber memory)
gcc/
2016-06-06 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR c/24414
* cfgexpand.c (expand_asm_loc): Remove handling for ADDR_EXPR.
Implicitly clobber memory for basic asm with non-empty assembler
string. Use targetm.md_asm_adjust also here.
* compare-elim.c (arithmetic_flags_clobber_p): Use asm_noperands here.
* final.c (final_scan_insn): Handle basic asm in PARALLEL block.
* gimple.c (gimple_asm_clobbers_memory_p): Handle basic asm with
non-empty assembler string.
* ira.c (compute_regs_asm_clobbered): Use asm_noperands here.
* recog.c (asm_noperands): Handle basic asm in PARALLEL block.
(decode_asm_operands): Handle basic asm in PARALLEL block.
(extract_insn): Handle basic asm in PARALLEL block.
* doc/extend.texi: Mention new behavior of basic asm.
* config/ia64/ia64 (rtx_needs_barrier): Handle ASM_INPUT here.
* config/pa/pa.c (branch_to_delay_slot_p, branch_needs_nop_p,
branch_needs_nop_p): Use asm_noperands.
gcc/testsuite/
2016-06-06 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR c/24414
* gcc.target/i386/pr24414.c: New test.
From-SVN: r237133
This commit is contained in:
parent
690f24b775
commit
93671519e2
|
|
@ -1,3 +1,22 @@
|
||||||
|
2016-06-06 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
PR c/24414
|
||||||
|
* cfgexpand.c (expand_asm_loc): Remove handling for ADDR_EXPR.
|
||||||
|
Implicitly clobber memory for basic asm with non-empty assembler
|
||||||
|
string. Use targetm.md_asm_adjust also here.
|
||||||
|
* compare-elim.c (arithmetic_flags_clobber_p): Use asm_noperands here.
|
||||||
|
* final.c (final_scan_insn): Handle basic asm in PARALLEL block.
|
||||||
|
* gimple.c (gimple_asm_clobbers_memory_p): Handle basic asm with
|
||||||
|
non-empty assembler string.
|
||||||
|
* ira.c (compute_regs_asm_clobbered): Use asm_noperands here.
|
||||||
|
* recog.c (asm_noperands): Handle basic asm in PARALLEL block.
|
||||||
|
(decode_asm_operands): Handle basic asm in PARALLEL block.
|
||||||
|
(extract_insn): Handle basic asm in PARALLEL block.
|
||||||
|
* doc/extend.texi: Mention new behavior of basic asm.
|
||||||
|
* config/ia64/ia64 (rtx_needs_barrier): Handle ASM_INPUT here.
|
||||||
|
* config/pa/pa.c (branch_to_delay_slot_p, branch_needs_nop_p,
|
||||||
|
branch_needs_nop_p): Use asm_noperands.
|
||||||
|
|
||||||
2016-06-06 Jose E. Marchesi <jose.marchesi@oracle.com>
|
2016-06-06 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||||
|
|
||||||
* config/sparc/sparc.md (cpu): Add niagara7 cpu type.
|
* config/sparc/sparc.md (cpu): Add niagara7 cpu type.
|
||||||
|
|
|
||||||
|
|
@ -2674,15 +2674,40 @@ expand_asm_loc (tree string, int vol, location_t locus)
|
||||||
{
|
{
|
||||||
rtx body;
|
rtx body;
|
||||||
|
|
||||||
if (TREE_CODE (string) == ADDR_EXPR)
|
|
||||||
string = TREE_OPERAND (string, 0);
|
|
||||||
|
|
||||||
body = gen_rtx_ASM_INPUT_loc (VOIDmode,
|
body = gen_rtx_ASM_INPUT_loc (VOIDmode,
|
||||||
ggc_strdup (TREE_STRING_POINTER (string)),
|
ggc_strdup (TREE_STRING_POINTER (string)),
|
||||||
locus);
|
locus);
|
||||||
|
|
||||||
MEM_VOLATILE_P (body) = vol;
|
MEM_VOLATILE_P (body) = vol;
|
||||||
|
|
||||||
|
/* Non-empty basic ASM implicitly clobbers memory. */
|
||||||
|
if (TREE_STRING_LENGTH (string) != 0)
|
||||||
|
{
|
||||||
|
rtx asm_op, clob;
|
||||||
|
unsigned i, nclobbers;
|
||||||
|
auto_vec<rtx> input_rvec, output_rvec;
|
||||||
|
auto_vec<const char *> constraints;
|
||||||
|
auto_vec<rtx> clobber_rvec;
|
||||||
|
HARD_REG_SET clobbered_regs;
|
||||||
|
CLEAR_HARD_REG_SET (clobbered_regs);
|
||||||
|
|
||||||
|
clob = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
|
||||||
|
clobber_rvec.safe_push (clob);
|
||||||
|
|
||||||
|
if (targetm.md_asm_adjust)
|
||||||
|
targetm.md_asm_adjust (output_rvec, input_rvec,
|
||||||
|
constraints, clobber_rvec,
|
||||||
|
clobbered_regs);
|
||||||
|
|
||||||
|
asm_op = body;
|
||||||
|
nclobbers = clobber_rvec.length ();
|
||||||
|
body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + nclobbers));
|
||||||
|
|
||||||
|
XVECEXP (body, 0, 0) = asm_op;
|
||||||
|
for (i = 0; i < nclobbers; i++)
|
||||||
|
XVECEXP (body, 0, i + 1) = gen_rtx_CLOBBER (VOIDmode, clobber_rvec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
emit_insn (body);
|
emit_insn (body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ arithmetic_flags_clobber_p (rtx_insn *insn)
|
||||||
if (!NONJUMP_INSN_P (insn))
|
if (!NONJUMP_INSN_P (insn))
|
||||||
return false;
|
return false;
|
||||||
pat = PATTERN (insn);
|
pat = PATTERN (insn);
|
||||||
if (extract_asm_operands (pat))
|
if (asm_noperands (pat) >= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) == 2)
|
if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) == 2)
|
||||||
|
|
|
||||||
|
|
@ -6558,6 +6558,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
|
||||||
case USE:
|
case USE:
|
||||||
case CALL:
|
case CALL:
|
||||||
case ASM_OPERANDS:
|
case ASM_OPERANDS:
|
||||||
|
case ASM_INPUT:
|
||||||
need_barrier |= rtx_needs_barrier (pat, flags, pred);
|
need_barrier |= rtx_needs_barrier (pat, flags, pred);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6442,7 +6442,7 @@ branch_to_delay_slot_p (rtx_insn *insn)
|
||||||
the branch is followed by an asm. */
|
the branch is followed by an asm. */
|
||||||
if (!insn
|
if (!insn
|
||||||
|| GET_CODE (PATTERN (insn)) == ASM_INPUT
|
|| GET_CODE (PATTERN (insn)) == ASM_INPUT
|
||||||
|| extract_asm_operands (PATTERN (insn)) != NULL_RTX
|
|| asm_noperands (PATTERN (insn)) >= 0
|
||||||
|| get_attr_length (insn) > 0)
|
|| get_attr_length (insn) > 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -6473,7 +6473,7 @@ branch_needs_nop_p (rtx_insn *insn)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT
|
if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT
|
||||||
|| extract_asm_operands (PATTERN (insn)) != NULL_RTX)
|
|| asm_noperands (PATTERN (insn)) >= 0)
|
||||||
&& get_attr_length (insn) > 0)
|
&& get_attr_length (insn) > 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -6497,7 +6497,7 @@ use_skip_p (rtx_insn *insn)
|
||||||
/* We can't rely on the length of asms, so we can't skip asms. */
|
/* We can't rely on the length of asms, so we can't skip asms. */
|
||||||
if (!insn
|
if (!insn
|
||||||
|| GET_CODE (PATTERN (insn)) == ASM_INPUT
|
|| GET_CODE (PATTERN (insn)) == ASM_INPUT
|
||||||
|| extract_asm_operands (PATTERN (insn)) != NULL_RTX)
|
|| asm_noperands (PATTERN (insn)) >= 0)
|
||||||
break;
|
break;
|
||||||
if (get_attr_length (insn) == 4
|
if (get_attr_length (insn) == 4
|
||||||
&& jump_insn == next_active_insn (insn))
|
&& jump_insn == next_active_insn (insn))
|
||||||
|
|
|
||||||
|
|
@ -7581,7 +7581,7 @@ means there is no way to communicate to the compiler what is happening
|
||||||
inside them. GCC has no visibility of symbols in the @code{asm} and may
|
inside them. GCC has no visibility of symbols in the @code{asm} and may
|
||||||
discard them as unreferenced. It also does not know about side effects of
|
discard them as unreferenced. It also does not know about side effects of
|
||||||
the assembler code, such as modifications to memory or registers. Unlike
|
the assembler code, such as modifications to memory or registers. Unlike
|
||||||
some compilers, GCC assumes that no changes to either memory or registers
|
some compilers, GCC assumes that no changes to general purpose registers
|
||||||
occur. This assumption may change in a future release.
|
occur. This assumption may change in a future release.
|
||||||
|
|
||||||
To avoid complications from future changes to the semantics and the
|
To avoid complications from future changes to the semantics and the
|
||||||
|
|
@ -7605,6 +7605,10 @@ all basic @code{asm} blocks use the assembler dialect specified by the
|
||||||
Basic @code{asm} provides no
|
Basic @code{asm} provides no
|
||||||
mechanism to provide different assembler strings for different dialects.
|
mechanism to provide different assembler strings for different dialects.
|
||||||
|
|
||||||
|
For basic @code{asm} with non-empty assembler string GCC assumes
|
||||||
|
the assembler block does not change any general purpose registers,
|
||||||
|
but it may read or write any globally accessible variable.
|
||||||
|
|
||||||
Here is an example of basic @code{asm} for i386:
|
Here is an example of basic @code{asm} for i386:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
|
|
|
||||||
|
|
@ -2566,6 +2566,10 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
|
||||||
(*debug_hooks->source_line) (last_linenum, last_filename,
|
(*debug_hooks->source_line) (last_linenum, last_filename,
|
||||||
last_discriminator, is_stmt);
|
last_discriminator, is_stmt);
|
||||||
|
|
||||||
|
if (GET_CODE (body) == PARALLEL
|
||||||
|
&& GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
|
||||||
|
body = XVECEXP (body, 0, 0);
|
||||||
|
|
||||||
if (GET_CODE (body) == ASM_INPUT)
|
if (GET_CODE (body) == ASM_INPUT)
|
||||||
{
|
{
|
||||||
const char *string = XSTR (body, 0);
|
const char *string = XSTR (body, 0);
|
||||||
|
|
|
||||||
|
|
@ -2583,6 +2583,10 @@ gimple_asm_clobbers_memory_p (const gasm *stmt)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Non-empty basic ASM implicitly clobbers memory. */
|
||||||
|
if (gimple_asm_input_p (stmt) && strlen (gimple_asm_string (stmt)) != 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2233,7 +2233,7 @@ compute_regs_asm_clobbered (void)
|
||||||
{
|
{
|
||||||
df_ref def;
|
df_ref def;
|
||||||
|
|
||||||
if (NONDEBUG_INSN_P (insn) && extract_asm_operands (PATTERN (insn)))
|
if (NONDEBUG_INSN_P (insn) && asm_noperands (PATTERN (insn)) >= 0)
|
||||||
FOR_EACH_INSN_DEF (def, insn)
|
FOR_EACH_INSN_DEF (def, insn)
|
||||||
{
|
{
|
||||||
unsigned int dregno = DF_REF_REGNO (def);
|
unsigned int dregno = DF_REF_REGNO (def);
|
||||||
|
|
|
||||||
32
gcc/recog.c
32
gcc/recog.c
|
|
@ -1470,22 +1470,34 @@ extract_asm_operands (rtx body)
|
||||||
|
|
||||||
/* If BODY is an insn body that uses ASM_OPERANDS,
|
/* If BODY is an insn body that uses ASM_OPERANDS,
|
||||||
return the number of operands (both input and output) in the insn.
|
return the number of operands (both input and output) in the insn.
|
||||||
|
If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
|
||||||
|
return 0.
|
||||||
Otherwise return -1. */
|
Otherwise return -1. */
|
||||||
|
|
||||||
int
|
int
|
||||||
asm_noperands (const_rtx body)
|
asm_noperands (const_rtx body)
|
||||||
{
|
{
|
||||||
rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body));
|
rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body));
|
||||||
int n_sets = 0;
|
int i, n_sets = 0;
|
||||||
|
|
||||||
if (asm_op == NULL)
|
if (asm_op == NULL)
|
||||||
return -1;
|
{
|
||||||
|
if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2
|
||||||
|
&& GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
|
||||||
|
{
|
||||||
|
/* body is [(asm_input ...) (clobber (reg ...))...]. */
|
||||||
|
for (i = XVECLEN (body, 0) - 1; i > 0; i--)
|
||||||
|
if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (GET_CODE (body) == SET)
|
if (GET_CODE (body) == SET)
|
||||||
n_sets = 1;
|
n_sets = 1;
|
||||||
else if (GET_CODE (body) == PARALLEL)
|
else if (GET_CODE (body) == PARALLEL)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
|
if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
|
||||||
{
|
{
|
||||||
/* Multiple output operands, or 1 output plus some clobbers:
|
/* Multiple output operands, or 1 output plus some clobbers:
|
||||||
|
|
@ -1540,9 +1552,12 @@ asm_noperands (const_rtx body)
|
||||||
the locations of the operands within the insn into the vector OPERAND_LOCS,
|
the locations of the operands within the insn into the vector OPERAND_LOCS,
|
||||||
and the constraints for the operands into CONSTRAINTS.
|
and the constraints for the operands into CONSTRAINTS.
|
||||||
Write the modes of the operands into MODES.
|
Write the modes of the operands into MODES.
|
||||||
|
Write the location info into LOC.
|
||||||
Return the assembler-template.
|
Return the assembler-template.
|
||||||
|
If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
|
||||||
|
return the basic assembly string.
|
||||||
|
|
||||||
If MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
|
If LOC, MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
|
||||||
we don't store that info. */
|
we don't store that info. */
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|
@ -1603,6 +1618,12 @@ decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
|
||||||
}
|
}
|
||||||
nbase = i;
|
nbase = i;
|
||||||
}
|
}
|
||||||
|
else if (GET_CODE (asmop) == ASM_INPUT)
|
||||||
|
{
|
||||||
|
if (loc)
|
||||||
|
*loc = ASM_INPUT_SOURCE_LOCATION (asmop);
|
||||||
|
return XSTR (asmop, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2245,7 +2266,8 @@ extract_insn (rtx_insn *insn)
|
||||||
case PARALLEL:
|
case PARALLEL:
|
||||||
if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
|
if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
|
||||||
&& GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
|
&& GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
|
||||||
|| GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
|
|| GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS
|
||||||
|
|| GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
|
||||||
goto asm_insn;
|
goto asm_insn;
|
||||||
else
|
else
|
||||||
goto normal_insn;
|
goto normal_insn;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2016-06-06 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
PR c/24414
|
||||||
|
* gcc.target/i386/pr24414.c: New test.
|
||||||
|
|
||||||
2016-06-06 Jose E. Marchesi <jose.marchesi@oracle.com>
|
2016-06-06 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||||
|
|
||||||
* gcc.target/sparc/vis4misc.c: New file.
|
* gcc.target/sparc/vis4misc.c: New file.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-O2" } */
|
||||||
|
int test;
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int x = test;
|
||||||
|
asm ("movl $1,test");
|
||||||
|
if (x + test != 1)
|
||||||
|
__builtin_trap ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue