Hi! First: please be gentle: I don't speak RTL. ;-) And second: it's been some time.
On 2013-12-04T16:06:48+0000, Tejas Belagod <tbela...@arm.com> wrote: > gcc/ > * rtlanal.c (set_noop_p): Return nonzero in case of redundant vec_select > for overlapping register lanes. This got committed to trunk in r205712. > --- a/gcc/rtlanal.c > +++ b/gcc/rtlanal.c > @@ -1180,6 +1180,26 @@ set_noop_p (const_rtx set) > dst = SUBREG_REG (dst); > } > > + /* It is a NOOP if destination overlaps with selected src vector > + elements. */ > + if (GET_CODE (src) == VEC_SELECT > + && REG_P (XEXP (src, 0)) && REG_P (dst) > + && HARD_REGISTER_P (XEXP (src, 0)) > + && HARD_REGISTER_P (dst)) > + { > + int i; > + rtx par = XEXP (src, 1); > + rtx src0 = XEXP (src, 0); > + int c0 = INTVAL (XVECEXP (par, 0, 0)); > + HOST_WIDE_INT offset = GET_MODE_UNIT_SIZE (GET_MODE (src0)) * c0; > + > + for (i = 1; i < XVECLEN (par, 0); i++) > + if (INTVAL (XVECEXP (par, 0, i)) != c0 + i) > + return 0; > + return simplify_subreg_regno (REGNO (src0), GET_MODE (src0), > + offset, GET_MODE (dst)) == (int)REGNO (dst); > + } > + > return (REG_P (src) && REG_P (dst) > && REGNO (src) == REGNO (dst)); > } In <https://gcc.gnu.org/PR94279> "[amdgcn] internal compiler error: RTL check: expected code 'const_int', have 'reg' in rtx_to_poly_int64, at rtl.h:2379", we recently found that that it's wrong to expect constant selectors, at least in the current code and its usage context. (Thanks, Richard Biener for the guidance!) Not too many actually, but of course, this code has seen some changes since 2013-12-04 (for example, r261530 "Use poly_int rtx accessors instead of hwi accessors"), and also the context may have changed that it's being used in -- so, I'm not sure whether the original code (as quoted above) is actually buggy already, but it already does contain the pattern that 'INTVAL' is used on something without making sure that we're actually dealing with a constant selector. (Has that maybe have been an impossible scenario back then?) Anyway. Attached is a WIP patch "[rtl] Harden 'set_noop_p' for non-constant selectors [PR94279]". Richard Biener said that "A patch like along that line is pre-approved", but given my illiterateness with what I'm deal with here, I'd like that reviewed properly, please. :-) If approving this patch, please respond with "Reviewed-by: NAME <EMAIL>" so that your effort will be recorded in the commit log, see <https://gcc.gnu.org/wiki/Reviewed-by>. I'll schedule x86_64-pc-linux-gnu and powerpc64le-unknown-linux-gnu bootstrap testing. What other testing does this need? (Asking as this seems to have been added for aarch64, which I'm not set up to test.) So far, I've only confirmed that it does solve the RTL checking issue with libgomp AMD GCN offloading testing. Then, should this also be backported to release branches? GCC 9: same patch as for master branch. GCC 8: pre poly_int, so only need to guard 'INTVAL' (by 'CONST_INT_P', right?). Or, is that not worth it, given that nobody found this to be a problem until now (as far as I know), and/or it's maybe really specific to (or, exposed by) AMD GCN's vector instructions? (For AMD GCN offloading, we only care about master branch.) Grüße Thomas ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter
>From 3546ac8ef47cf67570834e5a70614907bef40304 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge <tho...@codesourcery.com> Date: Wed, 22 Apr 2020 16:58:44 +0200 Subject: [PATCH] [rtl] Harden 'set_noop_p' for non-constant selectors [PR94279] --- gcc/rtlanal.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index c7ab86e228b1..0ebde7622db6 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1631,12 +1631,18 @@ set_noop_p (const_rtx set) int i; rtx par = XEXP (src, 1); rtx src0 = XEXP (src, 0); - poly_int64 c0 = rtx_to_poly_int64 (XVECEXP (par, 0, 0)); + poly_int64 c0; + if (!poly_int_rtx_p (XVECEXP (par, 0, 0), &c0)) + return 0; poly_int64 offset = GET_MODE_UNIT_SIZE (GET_MODE (src0)) * c0; for (i = 1; i < XVECLEN (par, 0); i++) - if (maybe_ne (rtx_to_poly_int64 (XVECEXP (par, 0, i)), c0 + i)) - return 0; + { + poly_int64 c0i; + if (!poly_int_rtx_p (XVECEXP (par, 0, i), &c0i) + || maybe_ne (c0i, c0 + i)) + return 0; + } return REG_CAN_CHANGE_MODE_P (REGNO (dst), GET_MODE (src0), GET_MODE (dst)) && simplify_subreg_regno (REGNO (src0), GET_MODE (src0), -- 2.25.1