User account creation filtered due to spam.

Bug 25130 - [4.1/4.2 Regression] miscompilation in GCSE
Summary: [4.1/4.2 Regression] miscompilation in GCSE
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.1.0
: P1 normal
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: alias, wrong-code
Depends on:
Blocks:
 
Reported: 2005-11-28 01:24 UTC by snyder
Modified: 2011-12-02 13:03 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build: i686-pc-linux-gnu
Known to work: 4.0.0
Known to fail: 4.1.0, 4.2.0
Last reconfirmed: 2005-12-17 11:27:18


Attachments
Smaller test case (493 bytes, text/plain)
2005-12-17 15:09 UTC, Steven Bosscher
Details
Make hash_rtx and exp_equiv_p take MEM_ATTRS into accoutn (671 bytes, patch)
2005-12-27 00:58 UTC, Steven Bosscher
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description snyder 2005-11-28 01:24:46 UTC


hi -

The current gcc in the 4.1 branch (svn rev 107578) miscompiles the following
source with -O3 -fno-strict-aliasing:

---------------------------------------------------------------------------
// g++ -O3  -g -fno-strict-aliasing -o x x.cc 

inline void* operator new(unsigned, void* __p) throw() { return __p; }
extern "C" int printf (...);

struct _Deque_base
{
  _Deque_base()
  {
    _M_impl._M_start_cur = new int;
    _M_impl._M_finish_cur = _M_impl._M_start_cur;
    printf ("");
  }

  ~_Deque_base() {
    printf ("", _M_impl._M_start_node);
  }

  struct _Deque_impl
  {
    int* _M_start_cur;
    int _M_start_node;
    int* _M_finish_cur;
  };
  _Deque_impl _M_impl;
};

struct deque : public _Deque_base {};

struct ClusterContainerStandard
{
  deque _clusters;
  virtual void add_cluster() { }
};

int main( )
{
  {
    ClusterContainerStandard box;
  }
  printf ("aaa\n");

  {
    deque clusters;
    if (clusters._M_impl._M_start_cur)
    {
      ::new(static_cast<void*>(clusters._M_impl._M_finish_cur)) int(0);
      ++clusters._M_impl._M_finish_cur;
    }
    printf ("%p %p\n",
            clusters._M_impl._M_start_cur, clusters._M_impl._M_finish_cur);
  }
  return 0;
}
---------------------------------------------------------------------------

I expect the two pointer values printed by this program to differ by 4.
Instead, they are identical:

$ g++ -o x -O3 -fno-strict-aliasing x.cc
$ ./x
aaa
0x804a018 0x804a018
$


Here is the relevant excerpt from the generated code, starting just
after the printf("aaa\n") call:

       	movl	$4, (%esp)
	call	_Znwj             ; new int
	movl	%eax, -24(%ebp)   ; assign to start_cur
	movl	%eax, -16(%ebp)   ; assign to finish_cur
	movl	$.LC0, (%esp)
	call	printf            ; empty printf
.LEHE0:
	movl	-24(%ebp), %eax   ; test start_cur
	testl	%eax, %eax
	je	.L12
	movl	-16(%ebp), %eax   ; test finish_cur --- part of the new()
	testl	%eax, %eax
	je	.L6
	movl	$0, (%eax)        ; *finish_cur = 0
	movl	-16(%ebp), %eax   ; (a redundant move)  [1]
.L6:
	addl	$4, -16(%ebp)     ; ++finish_cur
.L4:
	movl	%eax, 8(%esp)     ; OOPS --- here we're using the value [2]
                                  ; of finish_cur before the increment!
	movl	-24(%ebp), %eax
	movl	$.LC2, (%esp)
	movl	%eax, 4(%esp)
.LEHB1:
	call	printf


Looking at the RTL dumps, the problem first seems to appear after the
loop2_done pass.  Here's an excerpt from that file, starting
at the insn corresponding to [1] above and continuing to [2].
Note that after the increment, there's a branch around an insn
that reloads the value of finish_cur from memory before the
printf call --- without that jump, the program would work correctly.
That jump is not present in the previous RTL dump, loop2_unswitch.


(insn 122 56 57 2 (set (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ])
        (mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
                (const_int -8 [0xfffffff8])) [0 <variable>._M_impl._M_start_node+0 S4 A32])) 34 {*movsi_1} (nil)
    (nil))
;; End of basic block 2, registers live:
 (nil)

;; Start of basic block 3, registers live: (nil)
(code_label 57 122 58 3 6 "" [1 uses])

(note 58 57 59 3 [bb 3] NOTE_INSN_BASIC_BLOCK)

(note 59 58 60 3 ("x.cc") 48)

(insn 60 59 128 3 x.cc:48 (parallel [
            (set (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                        (const_int -8 [0xfffffff8])) [0 clusters.D.1787._M_impl._M_finish_cur+0 S4 A32])
                (plus:SI (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                            (const_int -8 [0xfffffff8])) [0 clusters.D.1787._M_impl._M_finish_cur+0 S4 A32])
                    (const_int 4 [0x4])))
            (clobber (reg:CC 17 flags))
        ]) 148 {*addsi_1} (nil)
    (nil))

(jump_insn 128 60 129 3 (set (pc)
        (label_ref 61)) -1 (nil)
    (nil))
;; End of basic block 3, registers live:
 (nil)

(barrier 129 128 127)

;; Start of basic block 4, registers live: (nil)
(code_label 127 129 126 4 12 "" [1 uses])

(note 126 127 121 4 [bb 4] NOTE_INSN_BASIC_BLOCK)

(insn 121 126 61 4 (set (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ])
        (mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
                (const_int -8 [0xfffffff8])) [0 <variable>._M_impl._M_start_node+0 S4 A32])) 34 {*movsi_1} (nil)
    (nil))
;; End of basic block 4, registers live:
 (nil)

;; Start of basic block 5, registers live: (nil)
(code_label 61 121 62 5 4 "" [1 uses])

(note 62 61 63 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(note 63 62 65 5 ("x.cc") 51)

(insn 65 63 66 5 x.cc:51 (set (mem:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 8 [0x8])) [0 S4 A32])
        (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ])) 34 {*movsi_1} (nil)
    (nil))

Environment:
System: Linux karma 2.6.14.2sss #1 PREEMPT Mon Nov 21 10:03:24 EST 2005 i686 i686 i386 GNU/Linux
Architecture: i686

	<machine, os, target, libraries (multiple lines)>
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: /home/sss/gcc/gcc/configure --prefix=/usr/local/gcc --enable-threads=posix --enable-long-long --enable-languages=c,c++,fortran

How-To-Repeat:

See above.
Comment 1 snyder 2005-11-28 01:24:46 UTC
Fix:
	<how to correct or work around the problem, if known (multiple lines)>
Comment 2 Andrew Pinski 2005-11-28 02:00:05 UTC
Loop optimizers don't do anything to this testcase as there are no loops.  -fno-gcse fixes it so I am going to assume it is GCSE bug.  Anyways confirmed.
Comment 3 Jim Wilson 2005-11-29 06:10:20 UTC
This is indeed a gcse problem.  It is a problem with the load motion support.

There are some similarities to PR 24804 here.  We have multiple overlapping objects on the stack, that have mems with different MEM_EXPR fields, that are being treated as the same object because they have the same hash code.  This results in some new RTL being emitted by gcse that has mems with incorrect MEM_EXPR fields.  This doesn't cause the failure though, and seems to be harmless for this testcase.  This is potentially a problem for other testcases though.

The problem happens shortly before the printf call.  We have before gcse
(insn 60 58 61 3 (parallel [
            (set (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                        (const_int -8 [0xfffffffffffffff8])) [0 clusters.D.1787\._M_impl._M_finish_cur+0 S4 A32])
                (plus:SI (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                            (const_int -8 [0xfffffffffffffff8])) [0 clusters.D.\1787._M_impl._M_finish_cur+0 S4 A32])
                    (const_int 4 [0x4])))
            (clobber (reg:CC 17 flags))
        ]) 208 {*addsi_1} (nil)
    (nil))
;; End of basic block 3, registers live:
 (nil)
                                                                                
;; Start of basic block 4, registers live: (nil)
(code_label 61 60 62 4 4 "" [1 uses])
                                                                                
(note 62 61 64 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
                                                                                
(insn 64 62 65 4 (set (reg:SI 72 [ clusters.D.1787._M_impl._M_finish_cur ])
        (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                (const_int -8 [0xfffffffffffffff8])) [0 clusters.D.1787._M_impl\._M_finish_cur+0 S4 A32])) 40 {*movsi_1} (nil)
    (nil))

and after gcse we have
(insn 60 58 124 3 (parallel [
            (set (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                        (const_int -8 [0xfffffffffffffff8])) [0 clusters.D.1787\._M_impl._M_finish_cur+0 S4 A32])
                (plus:SI (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                            (const_int -8 [0xfffffffffffffff8])) [0 clusters.D.\1787._M_impl._M_finish_cur+0 S4 A32])
                    (const_int 4 [0x4])))
            (clobber (reg:CC 17 flags))
        ]) 208 {*addsi_1} (nil)
    (nil))
                                                                                
(jump_insn 124 60 125 3 (set (pc)
        (label_ref 61)) -1 (nil)
    (nil))
;; End of basic block 3, registers live:
 (nil)
                                                                                
(barrier 125 124 127)
                                                                                
;; Start of basic block 4, registers live: (nil)
(code_label 127 125 126 4 12 "" [1 uses])
                                                                                
(note 126 127 121 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
                                                                                
(insn 121 126 61 4 (set (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ])
        (mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
                (const_int -8 [0xfffffffffffffff8])) [0 <variable>._M_impl._M_s\tart_node+0 S4 A32])) 40 {*movsi_1} (nil)
    (nil))
;; End of basic block 4, registers live:
 (nil)
                                                                                
;; Start of basic block 5, registers live: (nil)
(code_label 61 121 62 5 4 "" [1 uses])
                                                                                
(note 62 61 65 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
                                                                                
(insn 65 62 66 5 (set (mem:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 8 [0x8])) [0 S4 A32])
        (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ])) 40 {*movsi_1} (n\il)
    (nil))

For some reason, gcse thought that insn 64 was redundant, and deleted it, adding a new basic block with a load as compensation code.  This results in reg 79 having the wrong value when we go from the increment to the printf.

I haven't pinpointed an exact cause of the problem.  The gcse algorithmics are complicated.  I think the underlying failure is that we are adding mems to the expression table, and adding their load/store insns to the ldst_table.  When we find a load/store we can't handle, we remove it from the ldst_table.  However, we never remove entries from the expression table.  Since there are still mems in the expression table, gcse still tries to optimize them.  And this results in bad code, because some load/store insns needs fixups when their mems are optimized, and these fixups do not happen because the load/store insns are no longer in the ldst_table.  The fixups are supposed to be emitted in update_ld_motion_stores.
Comment 4 Steven Bosscher 2005-12-16 23:58:25 UTC
Re. comment #3, I can reproduce the bug with -fno-gcse-lm too, so this may be unrelated to load motion.  I also tried with -O -fgcse and I'm seeing the bug then, too.  Finally, I tried with CPROP1, CPROP2 and load pre commented out, and it still fails.  So it may be normal PRE breaking things.

Comment 5 Steven Bosscher 2005-12-17 11:27:18 UTC
Looking into this.
Comment 6 Steven Bosscher 2005-12-17 11:31:25 UTC
Also seen on powerpc
Comment 7 Steven Bosscher 2005-12-17 15:09:33 UTC
Created attachment 10519 [details]
Smaller test case

Fails for me when compiled with:
"g++ -O -fgcse t.C -fno-exceptions -fno-tree-dominator-opts"
Comment 8 Steven Bosscher 2005-12-17 15:14:03 UTC
It looks like we're missing a memory modification.  Yes, making this a load PRE problem after all, despite it failing for me even with -fno-gcse-lm, but oh well.

I have these expressions in the table:
Expression hash table (11 buckets, 3 entries)
Index 0 (hash value 7)
  (mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
        (const_int -8 [0xfffffff8])) [0 <variable>._M_impl._M_start_node+0 S4 A32])
Index 1 (hash value 10)
  (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
        (const_int -16 [0xfffffff0])) [0 clusters.D.1846._M_impl._M_start_cur+0 S4 A32])
Index 2 (hash value 3)
  (mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
        (const_int -12 [0xfffffff4])) [0 <variable>._M_impl._M_start_node+0 S4 A32])

The second and third expressions don't do much.  For the first expression we apply load PRE.  But the local data flow sets look wrong.  For TRANSP I have,

transp
 0
  000
 1
  111
 2
  000
 3
  111
 4
  000

and block 3 for me looks like this:

;; Start of basic block 3, registers live: (nil)
(code_label 57 94 58 3 8 "" [1 uses])

(note 58 57 59 3 [bb 3] NOTE_INSN_BASIC_BLOCK)

(note 59 58 60 3 ("t.C") 55)

(insn 60 59 96 3 t.C:55 (parallel [
            (set (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                        (const_int -8 [0xfffffff8])) [0 clusters.D.1846._M_impl._M_finish_cur+0 S4 A32])
                (plus:SI (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
                            (const_int -8 [0xfffffff8])) [0 clusters.D.1846._M_impl._M_finish_cur+0 S4 A32])
                    (const_int 4 [0x4])))
            (clobber (reg:CC 17 flags))
        ]) 148 {*addsi_1} (nil)
    (nil))

(jump_insn 96 60 97 3 (set (pc)
        (label_ref 61)) -1 (nil)
    (nil))
;; End of basic block 3, registers live:
 (nil)

Looks to me that insn 60 should cause expression 1 to not be in TRANSP for this basic block.
Comment 9 Steven Bosscher 2005-12-17 18:23:57 UTC
Breakpoint 7, compute_transp (x=0x4021557c, indx=0, bmap=0x894e1b8, set_p=0) at gcse.c:2500
2500                    rtx list_entry = canon_modify_mem_list[bb_index];
(gdb) p debug_rtx(x)
(mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
        (const_int -8 [0xfffffff8])) [0 <variable>._M_impl._M_start_node+0 S4 A32])
$33 = void
(gdb) next
2502                    while (list_entry)
(gdb)
2509                        dest = XEXP (list_entry, 0);
(gdb)
2510                        list_entry = XEXP (list_entry, 1);
(gdb)
2511                        dest_addr = XEXP (list_entry, 0);
(gdb)
2513                        if (canon_true_dependence (dest, GET_MODE (dest), dest_addr,
(gdb)
2522                        list_entry = XEXP (list_entry, 1);
(gdb) p debug_rtx(x)
(mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
        (const_int -8 [0xfffffff8])) [0 <variable>._M_impl._M_start_node+0 S4 A32])
$34 = void
(gdb) p debug_rtx(dest)
(mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
        (const_int -8 [0xfffffff8])) [0 clusters.D.1846._M_impl._M_finish_cur+0 S4 A32])
$35 = void
(gdb) 

so (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame) (const_int -8 [0xfffffff8]))) and 
(mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame) (const_int -8 [0xfffffff8]))) don't conflict...  But frame is not changed in the function, so surely this is wrong?

(Maybe this is obvious to people with better RTL-fu than me, so don't be too harsh on me ;-)
Comment 10 Steven Bosscher 2005-12-18 00:49:47 UTC
At -O1 (i.e. for my test case) CSE1 turns this...

(insn 24 22 25 0 (parallel [
            (set (reg/f:SI 67)
                (plus:SI (reg/f:SI 20 frame)
                    (const_int -16 [0xfffffff0])))
            (clobber (reg:CC 17 flags))
        ]) 148 {*addsi_1} (nil)
    (nil))

(insn 25 24 27 0 (parallel [
            (set (reg/f:SI 61 [ this.1 ])
                (plus:SI (reg/f:SI 67)
                    (const_int 4 [0x4])))
            (clobber (reg:CC 17 flags))
        ]) 148 {*addsi_1} (nil)
    (nil))

(insn 27 25 28 0 (set (reg:SI 68 [ <variable>._M_impl._M_start_node ])
        (mem/s/j:SI (plus:SI (reg/f:SI 61 [ this.1 ])
                (const_int 4 [0x4])) [0 <variable>._M_impl._M_start_node+0 S4 A32])) 34 {*movsi_1} (nil)
    (nil))


...into this...

(insn 27 22 28 0 (set (reg:SI 68 [ <variable>._M_impl._M_start_node ])
        (mem/s/j:SI (plus:SI (reg/f:SI 20 frame)
                (const_int -8 [0xfffffff8])) [0 <variable>._M_impl._M_start_node+0 S4 A32])) 34 {*movsi_1} (nil)
    (nil))

Comment 11 Steven Bosscher 2005-12-18 01:38:25 UTC
Punt for now.
http://gcc.gnu.org/ml/gcc/2005-12/msg00504.html
Comment 12 Mark Mitchell 2005-12-19 18:32:58 UTC
Serious wrong code problem: P1.
Comment 13 Steven Bosscher 2005-12-21 15:28:21 UTC
Subject: Bug 25130

Author: steven
Date: Wed Dec 21 15:28:16 2005
New Revision: 108906

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=108906
Log:
patch for PR rtl-optimization/25130

gcc/
        * postreload-gcse.c (record_last_set_info): Notice stack pointer
        changes in push insns without REG_INC notes.

testsuite/
        * gcc.dg/pr25130.c: New test.


Added:
    trunk/gcc/testsuite/gcc.dg/pr25130.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/postreload-gcse.c
    trunk/gcc/testsuite/ChangeLog

Comment 14 Steven Bosscher 2005-12-21 15:32:12 UTC
Subject: Bug 25130

Author: steven
Date: Wed Dec 21 15:32:09 2005
New Revision: 108907

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=108907
Log:
patch for PR rtl-optimization/25130, gcc 4.1 edition.

gcc/
        * postreload-gcse.c (record_last_set_info): Notice stack pointer
        changes in push insns without REG_INC notes.

testsuite/
        * gcc.dg/pr25130.c: New test.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/gcc.dg/pr25130.c
Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/postreload-gcse.c
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog

Comment 15 Steven Bosscher 2005-12-21 15:45:09 UTC
That's what you get for working on different GCSEs at the same time.

Those commits were for Bug 25196 :-(
Comment 16 Steven Bosscher 2005-12-27 00:58:49 UTC
Created attachment 10557 [details]
Make hash_rtx and exp_equiv_p take MEM_ATTRS into accoutn

The test cases don't fail with GCC 4.2 anymore, but with GCC 4.1 they both still fail.  I think the right thing to do is to make the expressions not look the same to the dataflow equations -- after all they _are_ not the same.

But with this patch I'm unsure what will happen with e.g. loads from different fields of a union for which the MEM address looks the same.  The MEM_ATTRS will be different, so with my patch we won't see them as equivalent loads, I think.  But I haven't actually tested that.  I haven't even tested the patch yet really, but it does make the wrong-code problem go away for me.
Comment 17 Steven Bosscher 2006-01-01 17:37:13 UTC
I posted a patch that addresses the gcse.c part of the problem.
Comment 18 Steven Bosscher 2006-01-03 06:20:30 UTC
Subject: Bug 25130

Author: steven
Date: Tue Jan  3 06:20:21 2006
New Revision: 109264

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109264
Log:
	* fold-const.c (operand_equal_p): Accept a NULL operand 0 for
	COMPONENT_REFs.
	* emit-rtl.c (mem_attrs_htab_eq): Use iterative_hash_expr for
	hashing trees instead of a pointer hash.
	(mem_attrs_htab_eq): Do a deep compare instead of a pointer
	compare for MEM_EXPR.

	PR rtl-optimization/25130
	* cse.c (exp_equiv_p): Compare MEM_ATTRS instead of MEM_ALIAS_SET
	when comparing MEMs for GCSE

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cse.c
    trunk/gcc/emit-rtl.c
    trunk/gcc/fold-const.c

Comment 19 Steven Bosscher 2006-01-03 22:37:51 UTC
Subject: Bug 25130

Author: steven
Date: Tue Jan  3 22:37:46 2006
New Revision: 109292

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109292
Log:
2006-01-03  Steven Bosscher  <stevenb.gcc@gmail.com>

	* fold-const.c (operand_equal_p): Accept a NULL operand 0 for
	COMPONENT_REFs.
	* emit-rtl.c (mem_attrs_htab_eq): Use iterative_hash_expr for
	hashing trees instead of a pointer hash.
	(mem_attrs_htab_eq): Do a deep compare instead of a pointer
	compare for MEM_EXPR.

	PR rtl-optimization/25130
	* cse.c (exp_equiv_p): Compare MEM_ATTRS instead of
	* MEM_ALIAS_SET
	when comparing MEMs for GCSE

Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/cse.c
    branches/gcc-4_1-branch/gcc/emit-rtl.c
    branches/gcc-4_1-branch/gcc/fold-const.c

Comment 20 Steven Bosscher 2006-01-03 22:39:33 UTC
One part of the problem is fixed, and the test cases now pass.

There is still the RTL alias analysis bug mentioned in the thread on gcc@ starting here: http://gcc.gnu.org/ml/gcc/2006-01/msg00008.html.  But that is an issue that deserves its own PR.
Comment 21 Bernd Schmidt 2010-06-28 17:50:11 UTC
The patch that was committed (especially the cse.c exp_equiv_p part) seems like a big hammer, and it does cause missed optimization opportunities.

Reverting it on gcc-4.1-branch, and instead applying the patch for PR41033, also gives a compiler that correctly compiles this testcase.

PR41033 adds a test for flag_strict_aliasing to nonverlapping_component_refs_p, which corrects the return value for canon_true_dependence mentioned in comment #9.

Steven, are you certain that this patch is necessary in light of this?
Comment 22 Bernd Schmidt 2010-06-29 22:41:31 UTC
Closing this again.  The partial revert was approved and committed as r161534.
Comment 23 Jakub Jelinek 2011-06-13 12:47:14 UTC
(In reply to comment #21)
> The patch that was committed (especially the cse.c exp_equiv_p part) seems like
> a big hammer, and it does cause missed optimization opportunities.
> 
> Reverting it on gcc-4.1-branch, and instead applying the patch for PR41033,
> also gives a compiler that correctly compiles this testcase.
> 
> PR41033 adds a test for flag_strict_aliasing to nonverlapping_component_refs_p,
> which corrects the return value for canon_true_dependence mentioned in comment
> #9.
> 
> Steven, are you certain that this patch is necessary in light of this?

As PR49390 shows, yes.
Comment 24 Steven Bosscher 2011-12-02 13:03:13 UTC
Fixed by Jakub's patch for PR49390.