This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix type consistency problem in tree-tailcall.c
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 3 Nov 2010 11:26:47 +0100
- Subject: [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;