diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2024-07-16 15:31:17 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2024-07-16 15:31:17 +0100 |
commit | 851ec9960b084ad37556ec627e6931e985e41a24 (patch) | |
tree | 227b7f771643fd825b5c449a1e7880fd3e36b428 | |
parent | 9f9faebb8ebfc0103461641cc49ba0b21877b2b1 (diff) | |
download | gcc-851ec9960b084ad37556ec627e6931e985e41a24.zip gcc-851ec9960b084ad37556ec627e6931e985e41a24.tar.gz gcc-851ec9960b084ad37556ec627e6931e985e41a24.tar.bz2 |
recog: restrict paradoxical mode punning in insn_propagation [PR115901]
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.
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.
-rw-r--r-- | gcc/recog.cc | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr115901.c | 14 |
2 files changed, 22 insertions, 0 deletions
diff --git a/gcc/recog.cc b/gcc/recog.cc index 7710c55..54b3171 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 0000000..244af85 --- /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); +} |