Testcase, compile at -O2: void abort (void); void exit (int); int t = 100; int main () { int a[] = { 0, 1, 2 }; int *i = &a[sizeof(a)/sizeof(*a)]; i --; while (i > a) i[0] = 1+t, i--; if (a[1] != 1+t) abort (); exit (0); }
Confirmed. In final cleanup we have main () { int a[3]; int D.1620; <bb 2>: a[0] = 0; D.1620 = t + 1; a[2] = D.1620; a[1] = D.1620; if (D.1620 != 1) goto <L3>; else goto <L4>; <L3>:; abort (); <L4>:; exit (0); } !?
Starting with DOM we have <bb 2>: # SFT.3_3 = V_MUST_DEF <SFT.3_2>; a[0] = 0; # SFT.2_5 = V_MUST_DEF <SFT.2_4>; a[1] = 1; # SFT.1_7 = V_MUST_DEF <SFT.1_6>; a[2] = 2; ... <L2>:; # VUSE <SFT.2_5>; D.1621_14 = a[1]; t.0_15 = t.0_11; D.1620_16 = t.0_15 + 1; if (D.1621_14 != D.1620_16) goto <L3>; else goto <L4>; which is wrong.
(In reply to comment #2) > Starting with DOM we have No, DOM is not related to the problem. Before alias2: # SFT.3_31 = PHI <SFT.3_22(3), SFT.3_3(2)>; # SFT.2_30 = PHI <SFT.2_21(3), SFT.2_5(2)>; # SFT.1_29 = PHI <SFT.1_20(3), SFT.1_7(2)>; # i_28 = PHI <i_13(3), &a[2](2)>; <L0>:; # VUSE <t_10>; t.0_11 = t; D.1536_12 = t.0_11 + 1; # SFT.1_20 = V_MAY_DEF <SFT.1_29>; # SFT.2_21 = V_MAY_DEF <SFT.2_30>; # SFT.3_22 = V_MAY_DEF <SFT.3_31>; *i_28 = D.1536_12; i_13 = i_28 - 4B; if (&a < i_13) goto <L0>; else goto <L2>; After alias2: # SFT.3_31 = PHI <SFT.3_31(3), SFT.3_3(2)>; # SFT.2_30 = PHI <SFT.2_30(3), SFT.2_5(2)>; # SFT.1_29 = PHI <SFT.1_20(3), SFT.1_7(2)>; # i_28 = PHI <i_13(3), &a[2](2)>; <L0>:; # VUSE <t_10>; t.0_11 = t; D.1536_12 = t.0_11 + 1; # SFT.1_20 = V_MAY_DEF <SFT.1_29>; *i_28 = D.1536_12; i_13 = i_28 - 4B; if (&a < i_13) goto <L0>; else goto <L2>;
The points-to-set for i is wrong. The difference before the two aliasing passes are iD.1615_8 = &aD.1614[3]; iD.1615_9 = iD.1615_8 - 4B; goto <bb 4> (<L1>); # SUCC: 4 (fallthru) # BLOCK 3 # PRED: 4 (true) <L0>:; # VUSE <tD.1611_10>; t.0D.1619_11 = tD.1611; *iD.1615_1 = t.0D.1619_11; iD.1615_12 = iD.1615_1 - 4B; # SUCC: 4 (fallthru) # BLOCK 4 # PRED: 2 (fallthru) 3 (fallthru) # iD.1615_1 = PHI <iD.1615_9(2), iD.1615_12(3)>; <L1>:; if (&aD.1614 < iD.1615_1) goto <L0>; else goto <L2>; # SUCC: 3 (true) 5 (false) vs. # BLOCK 3 # PRED: 3 (true,exec) 2 (fallthru,exec) # SFT.3D.1626_29 = PHI <SFT.3D.1626_20(3), SFT.3D.1626_3(2)>; # SFT.2D.1625_28 = PHI <SFT.2D.1625_19(3), SFT.2D.1625_5(2)>; # SFT.1D.1624_27 = PHI <SFT.1D.1624_18(3), SFT.1D.1624_7(2)>; # iD.1615_26 = PHI <iD.1615_12(3), &aD.1614[2](2)>; <L0>:; # VUSE <tD.1611_10>; t.0D.1619_11 = tD.1611; # SFT.1D.1624_18 = V_MAY_DEF <SFT.1D.1624_27>; # SFT.2D.1625_19 = V_MAY_DEF <SFT.2D.1625_28>; # SFT.3D.1626_20 = V_MAY_DEF <SFT.3D.1626_29>; *iD.1615_26 = t.0D.1619_11; iD.1615_12 = iD.1615_26 - 4B; if (&aD.1614 < iD.1615_12) goto <L0>; else goto <L2>; # SUCC: 3 (true,exec) 4 (loop_exit,false,exec) so do we miss it because it's a PHI argument or because in the first case we point one after the last element of the array and in the second case to the last element? Danny, does this ring a bell?
Subject: Re: [4.2/4.3 Regression] Wrong code with arrays > > so do we miss it because it's a PHI argument or because in the first case > we point one after the last element of the array and in the second case to > the last element? > > Danny, does this ring a bell? /* In languages like C, you can access one past the end of an array. You aren't allowed to dereference it, so we can ignore this constraint. When we handle pointer subtraction, we may have to do something cute here. */ > > > -- > > rguenth at gcc dot gnu dot org changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > CC| |dberlin at gcc dot gnu dot > | |org > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29716 > > ------- You are receiving this mail because: ------- > You are on the CC list for the bug, or are watching someone who is. >
Appears to be fixed by: 2006-12-12 Daniel Berlin <dberlin@dberlin.org> * tree-ssa-structalias.c (handle_ptr_arith): Return false when we can't handle the pointer arithmetic.