Message ID | mpt5xt9nx0r.fsf@arm.com |
---|---|
State | New |
Headers | show |
Series | recog: restrict paradoxical mode punning in insn_propagation [PR115901] | expand |
On 7/13/24 9:15 AM, Richard Sandiford wrote: > In g:44fc801e97a8dc626a4806ff4124439003420b20 I'd extended > insn_propagation to handle simple cases of hard-reg mode punning. > One of the checks was that the new use mode occupied the same > number of registers as the original definition mode. However, > as PR115901 shows, we need to avoid increasing the size of any > registers in the punned "to" expression as well. > > Specifically, the test includes a DImode move from GPR x0 to > a vector register, followed by a V2DI use of the vector register. > The simplification would then create a V2DI spanning x0 and x1, > manufacturing a new, unwanted use of x1. > > Checking for that kind of thing directly seems too cumbersome, > and is not related to the original motivation (which was to improve > handling of shared vector zeros on aarch64). This patch therefore > restricts the paradoxical case to constants. > > Tested on aarch64-linux-gnu & x86_64-linux-gnu. OK to install? > > Richard > > > gcc/ > PR rtl-optimization/115901 > * recog.cc (insn_propagation::apply_to_rvalue_1): Restrict > paradoxical mode punning to cases where "to" is constant. > > gcc/testsuite/ > PR rtl-optimization/115901 > * gcc.dg/torture/pr115901.c: New test. OK jeff
diff --git a/gcc/recog.cc b/gcc/recog.cc index 7710c55b745..54b317126c2 100644 --- a/gcc/recog.cc +++ b/gcc/recog.cc @@ -1082,6 +1082,14 @@ insn_propagation::apply_to_rvalue_1 (rtx *loc) || !REG_CAN_CHANGE_MODE_P (REGNO (x), GET_MODE (from), GET_MODE (x))) return false; + /* If the reference is paradoxical and the replacement + value contains registers, we would need to check that the + simplification below does not increase REG_NREGS for those + registers either. It seems simpler to punt on nonconstant + values instead. */ + if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (from)) + && !CONSTANT_P (to)) + return false; newval = simplify_subreg (GET_MODE (x), to, GET_MODE (from), subreg_lowpart_offset (GET_MODE (x), GET_MODE (from))); diff --git a/gcc/testsuite/gcc.dg/torture/pr115901.c b/gcc/testsuite/gcc.dg/torture/pr115901.c new file mode 100644 index 00000000000..244af857d88 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr115901.c @@ -0,0 +1,14 @@ +/* { dg-additional-options "-ftrivial-auto-var-init=zero" } */ + +int p; +void g(long); +#define vec16 __attribute__((vector_size(16))) + +void l(vec16 long *); +void h() +{ + long inv1; + vec16 long inv = {p, inv1}; + g (p); + l(&inv); +}