From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26100 invoked by alias); 3 Jun 2005 14:34:23 -0000 Mailing-List: contact java-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: java-prs-owner@gcc.gnu.org Received: (qmail 26073 invoked by uid 48); 3 Jun 2005 14:34:22 -0000 Date: Fri, 03 Jun 2005 14:34:00 -0000 Message-ID: <20050603143422.26069.qmail@sourceware.org> From: "dnovillo at gcc dot gnu dot org" To: java-prs@gcc.gnu.org In-Reply-To: <20050601015434.21855.tromey@gcc.gnu.org> References: <20050601015434.21855.tromey@gcc.gnu.org> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug tree-optimization/21855] array bounds checking elimination X-Bugzilla-Reason: CC X-SW-Source: 2005-q2/txt/msg00689.txt.bz2 List-Id: ------- Additional Comments From dnovillo at gcc dot gnu dot org 2005-06-03 14:34 ------- Aliasing is getting in the way of range propagation here. We don't realize that args.length does not change during the loop, which means that we don't eliminate the redundant load and fail to see the equivalence between the ranges. Analysis from an IRC discussion: tromey: so, this is how we get ourselves tied up in a knot. This is the IL inside the loop body (21855): :; D.671_6 = args_5->length; if (i_2 >= D.671_6) goto ; else goto ; [ ... ] i.4_13 = (unsigned int) i_12; D.680_14 = args_5->length; D.681_15 = (unsigned int) D.680_14; if (i.4_13 < D.681_15) goto ; else goto ; :; D.682_27 = _Jv_ThrowBadArrayIndex (i_12); the first if() controls the iteration of the loop. the second if () is the redundancy we want to remove. when we get to this point, i_12 has the range we want, namely [-INF, D.671_6 - 1]. Two things go wrong: 1- The cast to unsigned int is an euphemism for ABS_EXPR here. VRP doesn't see that and sets i.4_13's range to VARYING. That's trivial to fix. 2- We load from 'args_5->length' inside the loop even though the memory has not changed. This is the aliasing problem. If we realized that args_5->length doesn't change, FRE would've removed the redundant load and the inner if would look like: 'if (i.4_13 < D.671_6)' which we would immediately toss away dnovillo: my proposal to solve #2 is to have multiple name tags per pointer (one for each offset that is accessed off that pointer), so that we can say that args_5->length only is modified by args_5->length (or whatever else happens to alias that field) DannyB: not making args point-to call-clobbered vars would suffice here. DannyB: there are System. calls in the loop. Isn't args an incoming pointer? nope. DannyB: bah. yes. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855