This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix type consistency problem in tree-tailcall.c


Hi,

the attached testcase exhibits a regression present at -O2 on the mainline 
with checking enabled:

/home/eric/svn/gcc/gcc/testsuite/gnat.dg/opt8.adb:25:5: error: type mismatch 
in binary expression
natural___XDLU_0__2147483647
const integer
natural___XDLU_0__2147483647
D.2693_51 = R3b_27 + add_acc.25_49;
+===========================GNAT BUG DETECTED==============================+
| 4.6.0 20101102 (experimental) [trunk revision 166172] (i586-suse-linux-gnu) 
GCC error:|
| verify_stmts failed                                                      |
| Error detected 
around /home/eric/svn/gcc/gcc/testsuite/gnat.dg/opt8.adb:25:5|


The problem is that, while the code to discover tail calls knows how to look 
through casts, it doesn't reinstate them when it is building expressions to 
compute the accumulator and multiplicator values.  Hence the attached patch.

Tested on i586-suse-linux, OK for the mainline?


2010-11-03  Eric Botcazou  <ebotcazou@adacore.com>

	* tree-tailcall.c (find_tail_calls): Convert the operands to the type
	of the result before building binary expressions.


2010-11-03  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/opt8.ad[sb]: New test.
	* gnat.dg/opt8_pkg.ads: New helper.


-- 
Eric Botcazou
Index: tree-tailcall.c
===================================================================
--- tree-tailcall.c	(revision 166172)
+++ tree-tailcall.c	(working copy)
@@ -532,20 +532,22 @@ find_tail_calls (basic_block bb, struct
 
       if (tmp_a)
 	{
+	  tree type = TREE_TYPE (tmp_a);
 	  if (a)
-	    a = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp_a), a, tmp_a);
+	    a = fold_build2 (PLUS_EXPR, type, fold_convert (type, a), tmp_a);
 	  else
 	    a = tmp_a;
 	}
       if (tmp_m)
 	{
+	  tree type = TREE_TYPE (tmp_m);
 	  if (m)
-	    m = fold_build2 (MULT_EXPR, TREE_TYPE (tmp_m), m, tmp_m);
+	    m = fold_build2 (MULT_EXPR, type, fold_convert (type, m), tmp_m);
 	  else
 	    m = tmp_m;
 
 	  if (a)
-	    a = fold_build2 (MULT_EXPR, TREE_TYPE (tmp_m), a, tmp_m);
+	    a = fold_build2 (MULT_EXPR, type, fold_convert (type, a), tmp_m);
 	}
     }
 
package Opt8 is

    type Value_Number_Kind is
      (Int_Literal_VN,
       Selected_Address_VN,
       Membership_VN,
       Initial_External_Kappa_VN,
       Aliased_Kappa_VN,
       Phi_As_Kappa_VN,
       Multi_Target_Call_Kappa_VN,
       Final_Value_Of_Seq_Kappa_VN,
       Block_Kappa_VN);

    subtype Kappa_VN is Value_Number_Kind
    range Initial_External_Kappa_VN .. Block_Kappa_VN;

    type Value_Number_Id is new Positive;

    type Kappa_Component_Rec;

    type Kappa_Component_Ptr is access Kappa_Component_Rec;

    type Kappa_Component_Rec is record
        Content_VN : Value_Number_Id;
        Next : Kappa_Component_Ptr;
    end record;

    type Value_Number_Rec(Kind : Value_Number_Kind) is record
        Id: Value_Number_Id;
        case Kind is
            when Int_Literal_VN =>
                Int_Val : Integer;
            when Kappa_VN =>
                Old_Value : Kappa_Component_Rec;
                Possible_New_Values : Kappa_Component_Ptr;
                Use_Default : Boolean;
            when Others =>
                null;
        end case;
    end record;

    type Value_Number is access all Value_Number_Rec;

    function VN_Complexity (Val : Value_Number; N : Natural) return Natural;

end Opt8;
-- { dg-do compile }
-- { dg-options "-O2" }

with Opt8_Pkg;

package body Opt8 is

    function Content_Value (Rec : Kappa_Component_Rec)
        return Value_Number is
    begin
        return Opt8_Pkg.Id_To_VN (Rec.Content_VN);
    end;

    function Possible_Values_Count (V: Kappa_Component_Ptr) return Natural is
        Result : Natural := 0;
        List : Kappa_Component_Ptr := V;
    begin
        while List /= null loop
            Result := Result +1;
            List := List.Next;
        end loop;
        return Result;
    end;

    function VN_Complexity (Val : Value_Number; N : Natural)
        return Natural is
        Result : Natural := 0;
      begin
        case Val.Kind is
            when Membership_VN =>
                Result :=  VN_Complexity(Val, N);
            when Selected_Address_VN =>
                Result :=  VN_Complexity(Val, N) + 1;
            when Kappa_VN =>
                Result := Possible_Values_Count(Val.Possible_New_Values)*3;
                if Val.Use_Default then
                    if Result < N then
                      Result := Result +
                          VN_Complexity(Content_Value (Val.old_Value), N);
                    end if;
                end if;
            when others =>
              Result := 0;
          end case;
        return Result;
    end;

end Opt8;
with Opt8; use Opt8;

package Opt8_Pkg is

    function Id_To_VN (Id: Value_Number_Id) return Value_Number;

end Opt8_Pkg;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]