[Bug tree-optimization/48837] [4.4/4.5/4.6/4.6 Regression] Wrong optimization of recursive function calls

2011-05-07 Thread rakdver at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48837

--- Comment #9 from Zdenek Dvorak rakdver at gcc dot gnu.org 2011-05-07 
19:43:21 UTC ---
Author: rakdver
Date: Sat May  7 19:43:18 2011
New Revision: 173534

URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=173534
Log:
PR tree-optimization/48837
* tree-tailcall.c (tree_optimize_tail_calls_1): Do not mark tailcalls
when accumulator transformation is performed.

* gcc.dg/pr48837.c: New testcase.


Added:
trunk/gcc/testsuite/gcc.dg/pr48837.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/testsuite/ChangeLog
trunk/gcc/tree-tailcall.c


[Bug tree-optimization/48837] [4.4/4.5/4.6/4.6 Regression] Wrong optimization of recursive function calls

2011-05-04 Thread rakdver at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48837

--- Comment #8 from Zdenek Dvorak rakdver at gcc dot gnu.org 2011-05-04 
08:33:51 UTC ---
Created attachment 24177
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=24177
Fix for the issue

Indeed, once the accumulator transformation is performed, the other tail calls
in the function are moved to non-tail positions.


[Bug tree-optimization/48837] [4.4/4.5/4.6/4.6 Regression] Wrong optimization of recursive function calls

2011-05-02 Thread steven at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48837

Steven Bosscher steven at gcc dot gnu.org changed:

   What|Removed |Added

   Target Milestone|--- |4.3.6


[Bug tree-optimization/48837] [4.4/4.5/4.6/4.6 Regression] Wrong optimization of recursive function calls

2011-05-01 Thread steven at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48837

Steven Bosscher steven at gcc dot gnu.org changed:

   What|Removed |Added

 CC||steven at gcc dot gnu.org

--- Comment #4 from Steven Bosscher steven at gcc dot gnu.org 2011-05-01 
19:01:45 UTC ---
Works with -fno-optimize-sibling-calls. Looks like this has something to do
with the accumulators optimization in tree-tailcall.c


[Bug tree-optimization/48837] [4.4/4.5/4.6/4.6 Regression] Wrong optimization of recursive function calls

2011-05-01 Thread steven at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48837

--- Comment #5 from Steven Bosscher steven at gcc dot gnu.org 2011-05-01 
19:24:06 UTC ---

Function foo from .143.expand dump:

;; Function int foo(int, int) (_Z3fooii)

int foo(int, int) (int a, int b)
{
  int acc_tmp.13;
  int add_acc.12;
  int D.2091;
  int D.2085;
  int D.2081;

  # BLOCK 2 freq:6950
  # PRED: ENTRY [100.0%]  (fallthru,exec)
  # a_1 = PHI a_2(D)(0)
  # b_7 = PHI b_3(D)(0)
  # add_acc.12_21 = PHI 0(0)
  # SUCC: 3 [100.0%]  (fallthru)

  # BLOCK 3 freq:1
  # PRED: 2 [100.0%]  (fallthru) 5 [100.0%]  (fallthru,dfs_back,exec)
  # a_14 = PHI a_1(2), a_23(5)
  # b_22 = PHI b_7(2), b_25(5)
  # add_acc.12_19 = PHI add_acc.12_21(2), add_acc.12_12(5)
  D.2085_4 = b_22 | a_14;
  if (D.2085_4 != 0)
goto bb 4;
  else
goto bb 5;
  # SUCC: 4 [39.0%]  (true,exec) 5 [61.0%]  (false,exec)

  # BLOCK 4 freq:3900
  # PRED: 3 [39.0%]  (true,exec)
  D.2081_5 = baz (); [tail call]
  acc_tmp.13_10 = D.2081_5 + add_acc.12_19;
  return acc_tmp.13_10;
  # SUCC: EXIT [100.0%]

  # BLOCK 5 freq:3050
  # PRED: 3 [61.0%]  (false,exec)
Invalid sum of incoming frequencies 6100, should be 3050
  D.2091_8 = foo (0, 1);
  add_acc.12_12 = add_acc.12_19 + D.2091_8;
  a_23 = 1;
  b_25 = 0;
  goto bb 3;
  # SUCC: 3 [100.0%]  (fallthru,dfs_back,exec)

}
Invalid sum of incoming frequencies 3900, should be 6950

(Note, someone is not updating the CFG properly, see incorrect profile info.
This is caused by VRP, the mismatch appears first in the .vrp1 dump.)


The PHI nodes in basic block 3 show that the + foo(1,0) part of foo() has
been transformed from a recursive call into a loop inside foo.

We enter the function with a==0 and b==0 so control flow is as follows:

BB2 - BB3 - BB5 (because (a | b) == 0) - 
D.2091_8 = foo(0, 1)// D.2091_8 = 1
add_acc = 0 (from the PHI in BB2) + 1 = 1
- BB3 with a=1 and b=0 - BB4 -
D.2081_5 = baz () [tail call]   // D.2081_5 = 1
acc_tmp.13_10 = 1 + add_acc.12_19 = 1 + 1 = 2
return acc_tmp.13_10// return 2

That looks correct to me, but foo(0,0) returns 1 instead of 2. Both foo(0,1)
and foo(1,0) both return 1 as expected.

I think the problem is in RTL expansion of the tail call in basic block 4,
which doesn't look like a tail call to me. The RTL generated for basic block 4
is this:

;; Generating RTL for gimple basic block 4

;; D.2081_5 = baz (); [tail call]

(call_insn/u/j 13 12 14 4 (set (reg:SI 0 ax)
(call (mem:QI (symbol_ref:DI (_Z3bazv) [flags 0x3]  function_decl
0x7722c100 baz) [0 baz S1 A8])
(const_int 0 [0]))) t.cc:14 -1
 (expr_list:REG_EH_REGION (const_int 0 [0])
(nil))
(nil))

(barrier 14 13 0)

The   acc_tmp.13_10 = D.2081_5 + add_acc.12_19; part is lost.


[Bug tree-optimization/48837] [4.4/4.5/4.6/4.6 Regression] Wrong optimization of recursive function calls

2011-05-01 Thread steven at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48837

--- Comment #6 from Steven Bosscher steven at gcc dot gnu.org 2011-05-01 
19:56:37 UTC ---
In the tail recursion optimization:

Breakpoint 3, gimple_call_set_tail (s=0x77ed3680, tail_p=1 '\001') at
../../trunk/gcc/gimple.h:2241
2241  GIMPLE_CHECK (s, GIMPLE_CALL);
(gdb) bt 2
#0  gimple_call_set_tail (s=0x77ed3680, tail_p=1 '\001') at
../../trunk/gcc/gimple.h:2241
#1  0x00f6d5a3 in optimize_tail_call (t=0x1cd7820, opt_tailcalls=1
'\001') at ../../trunk/gcc/tree-tailcall.c:917
(More stack frames follow...)
(gdb) up
#1  0x00f6d5a3 in optimize_tail_call (t=0x1cd7820, opt_tailcalls=1
'\001') at ../../trunk/gcc/tree-tailcall.c:917
917   gimple_call_set_tail (stmt, true);
(gdb) l
912
913   if (opt_tailcalls)
914 {
915   gimple stmt = gsi_stmt (t-call_gsi);
916
917   gimple_call_set_tail (stmt, true);
918   if (dump_file  (dump_flags  TDF_DETAILS))
919 {
920   fprintf (dump_file, Found tail call );
921   print_gimple_stmt (dump_file, stmt, 0, dump_flags);
(gdb) disp debug_bb_n(5)
3: debug_bb_n (5) = ;; basic block 5, loop depth 0, count 0
;; prev block 4, next block 1
;; pred:   3 [100.0%]  (fallthru,exec)
;; succ:   EXIT [100.0%]
bb 5:
Invalid sum of incoming frequencies 3900, should be 6950
# D.2081_1 = PHI D.2081_5(3)
return D.2081_1;

(struct basic_block_def *) 0x77227548
(gdb) p debug_bb_n(3)
;; basic block 3, loop depth 0, count 0
;; prev block 2, next block 4
;; pred:   2 [39.0%]  (true,exec)
;; succ:   5 [100.0%]  (fallthru,exec)
bb 3:
D.2081_5 = baz (); [tail call]
goto bb 5;

$9 = (struct basic_block_def *) 0x77227478
(gdb) 


So far so good. But now compensation code must be inserted for the
recursive-call-turned-loop:

(gdb)
3: debug_bb_n (5) = ;; basic block 5, loop depth 0, count 0
;; prev block 4, next block 1
;; pred:   3 [100.0%]  (fallthru,exec)
;; succ:   EXIT [100.0%]
bb 5:
Invalid sum of incoming frequencies 3900, should be 6950
# D.2081_1 = PHI D.2081_5(3)
return D.2081_1;

(struct basic_block_def *) 0x77227548
(gdb)
1040adjust_return_value (e-src, m_acc, a_acc);
3: debug_bb_n (5) = ;; basic block 5, loop depth 0, count 0
;; prev block 4, next block 1
;; pred:   3 [100.0%]  (fallthru,exec)
;; succ:   EXIT [100.0%]
bb 5:
Invalid sum of incoming frequencies 3900, should be 6950
# D.2081_1 = PHI D.2081_5(3)
return D.2081_1;

(struct basic_block_def *) 0x77227548
(gdb)
1034  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR-preds)
3: debug_bb_n (5) = ;; basic block 5, loop depth 0, count 0
;; prev block 4, next block 1
;; pred:   3 [100.0%]  (fallthru,exec)
;; succ:   EXIT [100.0%]
bb 5:
Invalid sum of incoming frequencies 3900, should be 6950
# D.2081_1 = PHI D.2081_5(3)
acc_tmp.13_10 = add_acc.12_19 + D.2081_1;
return acc_tmp.13_10;

(struct basic_block_def *) 0x77227548
(gdb)

(I don't see now r127491 can be the cause of this, FWIW.)


[Bug tree-optimization/48837] [4.4/4.5/4.6/4.6 Regression] Wrong optimization of recursive function calls

2011-05-01 Thread steven at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48837

Steven Bosscher steven at gcc dot gnu.org changed:

   What|Removed |Added

 CC||rakdver at kam dot
   ||mff.cuni.cz

--- Comment #7 from Steven Bosscher steven at gcc dot gnu.org 2011-05-01 
20:24:11 UTC ---
Zdenek, this problem is caused by your work to handle addends/multiplicands in
tree-tailcall.c. It looks like an interaction problem between tail-calls and
tail-recursion, where elimination tail recursion turns a tail-call into a
normal call.