diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2021-04-16 12:38:02 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2021-04-16 12:38:02 +0100 |
commit | 49e651990a6966936a0273138dd56ac394e57b16 (patch) | |
tree | 2f7562704a3604487afaa778caac2d52e1e6f1b0 /gcc/builtins.c | |
parent | b4d6af55fe55c0eab87ab875bfd0346677e12236 (diff) | |
download | gcc-49e651990a6966936a0273138dd56ac394e57b16.zip gcc-49e651990a6966936a0273138dd56ac394e57b16.tar.gz gcc-49e651990a6966936a0273138dd56ac394e57b16.tar.bz2 |
Mark untyped calls and handle them specially [PR98689]
This patch fixes a regression introduced by the rtl-ssa patches.
It was seen on HPPA but it might be latent elsewhere.
The problem is that the traditional way of expanding an untyped_call
is to emit sequences like:
(call (mem (symbol_ref "foo")))
(set (reg pseudo1) (reg result1))
...
(set (reg pseudon) (reg resultn))
The ABI specifies that result1..resultn are clobbered by the call but
nothing in the RTL indicates that result1..resultn are the results
of the call. Normally, using a clobbered value gives undefined results,
but in this case the results are well-defined and matter for correctness.
This seems like a niche case, so I think it would be better to mark
it explicitly rather than try to detect it heuristically.
Note that in expand_builtin_apply we already have an rtx_insn *,
so it doesn't matter whether we call emit_call_insn or emit_insn.
Calling emit_insn seems more natural now that the gen_* call
has been split out. It also matches later code in the function.
gcc/
PR rtl-optimization/98689
* reg-notes.def (UNTYPED_CALL): New note.
* combine.c (distribute_notes): Handle it.
* emit-rtl.c (try_split): Likewise.
* rtlanal.c (rtx_properties::try_to_add_insn): Likewise. Assume
that calls with the note implicitly set all return value registers.
* builtins.c (expand_builtin_apply): Add a REG_UNTYPED_CALL
to untyped_calls.
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 196dda3..d30c4eb6 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2490,8 +2490,12 @@ expand_builtin_apply (rtx function, rtx arguments, rtx argsize) if (targetm.have_untyped_call ()) { rtx mem = gen_rtx_MEM (FUNCTION_MODE, function); - emit_call_insn (targetm.gen_untyped_call (mem, result, - result_vector (1, result))); + rtx_insn *seq = targetm.gen_untyped_call (mem, result, + result_vector (1, result)); + for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn)) + if (CALL_P (insn)) + add_reg_note (insn, REG_UNTYPED_CALL, NULL_RTX); + emit_insn (seq); } else if (targetm.have_call_value ()) { |