Noticed this when looking into PR 15779 int b[2]; int f() { return &b[0] == &b[1]; //should be zero } It does dect if b[1] was say c[0].
And the reason why it can dect that &b == &c is always false comes from: /* If this is an equality comparison of the address of two non-weak, unaliased symbols neither of which are extern (since we do not have access to attributes for externs), then we know the result. */
This seems to work for me now: .globl f .type f, @function f: pushl %ebp xorl %eax, %eax movl %esp, %ebp popl %ebp ret Andrew, can you confirm? W.
I mean that it is not on the tree level but it is done on the rtl level though.
*** Bug 19641 has been marked as a duplicate of this bug. ***
Could we, in general, fold &a[i] TRUTHOP &a[j] to i TRUTHOP j? I guess the only special case would be for sizeof(a[i]) == 0 -- but that is not allowed by the standard? I'll be wading through fold tomorrow and look where to add this transformation.
(In reply to comment #5) > Could we, in general, fold &a[i] TRUTHOP &a[j] to i TRUTHOP j? I guess the > only special case would be for sizeof(a[i]) == 0 -- but that is not allowed > by the standard? I'll be wading through fold tomorrow and look where to add > this transformation. sizeof(a[i]) can be zero for other languages besides C++ (C for an example). I gave you an hint where this can be fixed by the coment :).
Subject: Re: fold misses that two ADDR_EXPR of an arrary obvious not equal On 26 Jan 2005, pinskia at gcc dot gnu dot org wrote: > (In reply to comment #5) > > Could we, in general, fold &a[i] TRUTHOP &a[j] to i TRUTHOP j? I guess the > > only special case would be for sizeof(a[i]) == 0 -- but that is not allowed > > by the standard? I'll be wading through fold tomorrow and look where to add > > this transformation. > sizeof(a[i]) can be zero for other languages besides C++ (C for an example). > I gave you an hint where this can be fixed by the coment :). Apart from this, the following should fix it (while bootstrapping I'll search for truthcode_p() and a way to test the type size): Index: fold-const.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v retrieving revision 1.497 diff -u -r1.497 fold-const.c --- fold-const.c 23 Jan 2005 15:05:29 -0000 1.497 +++ fold-const.c 26 Jan 2005 14:53:38 -0000 @@ -8245,6 +8245,15 @@ ? code == EQ_EXPR : code != EQ_EXPR, type); + /* If this is a comparison of two ADDR_EXPRs of the same object + and the objects size is not zero, then we can fold this to + a comparison of the two offsets. */ + if ((code == EQ_EXPR || code == NE_EXPR /* FIXME: rest */) + && TREE_CODE (arg0) == ADDR_EXPR + && TREE_CODE (arg1) == ADDR_EXPR + && operand_equal_p (arg0, arg1, 0)) + return fold (build2 (code, type, TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0))); + if (FLOAT_TYPE_P (TREE_TYPE (arg0))) { tree targ0 = strip_float_extensions (arg0);
Ok - I guess it's ARRAY_REFs that are not folded ;) So the summary could be "fold misses that two ARRAY_REFs with different offset of the same arrary are obviously not equal". But I'm not allowed to change that.
Umm, no. We fold the ARRAY_REF comparison to PLUS_EXPR(ADDR_EXPR, INTEGER_CST) == PLUS_EXPR(ADDR_EXPR, INTEGER_CST) oh well ;) So I guess transforming &a + i truth_op &a + j to i truth_op j is always correct, as &a - &a == 0. For &b[1] == b though, we'll have to do more checks for this. Patch attached, bootstrap and testing in progress.
Created attachment 8074 [details] patch 2005-Jan-26 Richard Guenther <richard.guenther@uni-tuebingen.de> * fold-const.c (fold): fold comparisons between &a[i] and &a[j] or the equivalent zero-offset &a.
Hmm, it seems it causes stage1/xgcc -Bstage1/ -B/usr/local/i686-pc-linux-gnu/bin/ -c -O2 -g -fomit-frame-pointer -DIN_GCC -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long -Wno-variadic-macros -Wold-style-definition -Werror -fno-common -DHAVE_CONFIG_H -I. -I. -I/home/rguenth/src/gcc/gcc4.0/gcc -I/home/rguenth/src/gcc/gcc4.0/gcc/. -I/home/rguenth/src/gcc/gcc4.0/gcc/../include -I/home/rguenth/src/gcc/gcc4.0/gcc/../libcpp/include /home/rguenth/src/gcc/gcc4.0/gcc/ggc-page.c -o ggc-page.o /home/rguenth/src/gcc/gcc4.0/gcc/ggc-page.c: In function 'ggc_pch_read': /home/rguenth/src/gcc/gcc4.0/gcc/ggc-page.c:2304: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. #0 0x081da08c in tsi_stmt (i={ptr = 0x0, container = 0x40798d50}) at /home/rguenth/src/gcc/gcc4.0/gcc/tree-iterator.h:93 #1 0x081da5a6 in bsi_stmt (i= {tsi = {ptr = 0x0, container = 0x40798d50}, bb = 0x401d4360}) at /home/rguenth/src/gcc/gcc4.0/gcc/tree-flow-inline.h:572 #2 0x081cb6b4 in stmt_after_ip_original_pos (cand=0x88104f8, stmt=0x40832a00) at /home/rguenth/src/gcc/gcc4.0/gcc/tree-ssa-loop-ivopts.c:613 #3 0x081cb751 in stmt_after_increment (loop=<incomplete type>, cand=0x88104f8, stmt=0x40832a00) at /home/rguenth/src/gcc/gcc4.0/gcc/tree-ssa-loop-ivopts.c:635 no time to investigate - maybe an unrelated problem (didn't check if bootstrap succeeds without patch).
Fails without the patch, too, with the same error.
Bootstrapping and testing completed successfully, but for the testcase int g(void) { struct { int b[2]; } x; return &x.b[0] == &x.b[1]; } we have lowered the comparison to <eq_expr 0x40148264 type <integer_type 0x40149510 int public SI size <integer_cst 0x40141408 constant invariant 32> unit size <integer_cst 0x40141198 constant invariant 4> align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0x401413c0 -2147483648> max <integer_cst 0x401413d8 2147483647> pointer_to_this <pointer_type 0x401569b4>> invariant arg 0 <nop_expr 0x40146300 type <pointer_type 0x401569b4 type <integer_type 0x40149510 int> public unsigned SI size <integer_cst 0x40141408 32> unit size <integer_cst 0x40141198 4> align 32 symtab 0 alias set -1> invariant arg 0 <addr_expr 0x40146280 type <pointer_type 0x401b521c> invariant arg 0 <component_ref 0x4014d078 type <array_type 0x401b5000> arg 0 <var_decl 0x401b51b0 x> arg 1 <field_decl 0x401b506c b>>>> arg 1 <plus_expr 0x40148240 type <pointer_type 0x401569b4> invariant arg 0 <nop_expr 0x40146340 type <pointer_type 0x401569b4> invariant arg 0 <addr_expr 0x40146320 type <pointer_type 0x401b521c> invariant arg 0 <component_ref 0x4014d0a0 type <array_type 0x401b5000> arg 0 <var_decl 0x401b51b0 x> arg 1 <field_decl 0x401b506c b>>>> arg 1 <integer_cst 0x40141d50 constant invariant 4>>> and what confuses is the extra(?) nop_exprs - can I somehow avoid adding another path for this case?
Subject: Bug 15791 CVSROOT: /cvs/gcc Module name: gcc Changes by: sayle@gcc.gnu.org 2005-01-29 19:25:17 Modified files: gcc : ChangeLog fold-const.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg/tree-ssa: pr15791-1.c pr15791-2.c pr15791-3.c pr15791-4.c pr15791-5.c gcc/testsuite/g++.dg/tree-ssa: pr15791-1.C pr15791-2.C pr15791-3.C pr15791-4.C pr15791-5.C Log message: 2005-01-29 Richard Guenther <richard.guenther@uni-tuebingen.de> PR tree-optimization/15791 * fold-const.c (extract_array_ref): New function. (fold): Fold comparisons between &a[i] and &a[j] or semantically equivalent trees. * gcc.dg/tree-ssa/pr15791-1.c: New testcase. * gcc.dg/tree-ssa/pr15791-2.c: Likewise. * gcc.dg/tree-ssa/pr15791-3.c: Likewise. * gcc.dg/tree-ssa/pr15791-4.c: Likewise. * gcc.dg/tree-ssa/pr15791-5.c: Likewise. * g++.dg/tree-ssa/pr15791-1.C: Likewise. * g++.dg/tree-ssa/pr15791-2.C: Likewise. * g++.dg/tree-ssa/pr15791-3.C: Likewise. * g++.dg/tree-ssa/pr15791-4.C: Likewise. * g++.dg/tree-ssa/pr15791-5.C: Likewise. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.7325&r2=2.7326 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fold-const.c.diff?cvsroot=gcc&r1=1.498&r2=1.499 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4957&r2=1.4958 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr15791-1.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr15791-2.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr15791-3.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr15791-4.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr15791-5.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/tree-ssa/pr15791-1.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/tree-ssa/pr15791-2.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/tree-ssa/pr15791-3.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/tree-ssa/pr15791-4.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/tree-ssa/pr15791-5.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed.