diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f0dfc4bb6c7eaba644f50a1e9d90ef3176113663..476d31ed83ad8106c9922deabf35e18842d58b7a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2010-12-16  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* tree-ssa-sccvn.c (vn_reference_lookup_3): Always punt if the call to
+	get_ref_base_and_extent returns -1 as the max size.
+
 2010-12-16  Konrad Eisele  <konrad@gaisler.com>
             Eric Botcazou  <ebotcazou@adacore.com>
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b5c1508e5d76ca1f7e8f60d10f317c85eeee3059..78ed8c6a589f0cf0ed4f758447cd179e243a742f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-12-16  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* gnat.dg/opt13.adb: New test.
+	* gnat.dg/opt13_pkg.ad[sb]: New helper.
+
 2010-12-16  Jakub Jelinek  <jakub@redhat.com>
 
 	PR tree-optimization/43655
diff --git a/gcc/testsuite/gnat.dg/opt13.adb b/gcc/testsuite/gnat.dg/opt13.adb
new file mode 100644
index 0000000000000000000000000000000000000000..9e47957e9e125b8b805052bbc294f64cc3698f44
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt13.adb
@@ -0,0 +1,13 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+with Opt13_Pkg; use Opt13_Pkg;
+
+procedure Opt13 is
+  T : My_Type;
+begin
+  Allocate (T);
+  if N /= 1 then
+    raise Program_Error;
+  end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt13_pkg.adb b/gcc/testsuite/gnat.dg/opt13_pkg.adb
new file mode 100644
index 0000000000000000000000000000000000000000..b596a5c23445d621ef2333d2c20489f057f83cba
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt13_pkg.adb
@@ -0,0 +1,31 @@
+package body Opt13_Pkg is
+
+  subtype Index_Type is Natural range 0 .. 16;
+
+  type Arr is array (Index_Type range <>) of Integer;
+
+  type Rec is record
+    F1, F2, F3 : Float;
+    N : Natural;
+    B1, B2 : Boolean;
+    F4 : Float;
+  end record;
+
+  type Data (D : Index_Type) is record
+    A : Arr (1 .. D);
+    R : Rec;
+  end record;
+
+  Zero : constant Rec := (0.0, 0.0, 0.0, 0, False, False, 0.0);
+
+  procedure Allocate (T : out My_Type) is
+  begin
+    T := new Data (Index_Type'last);
+    T.R := Zero;
+
+    for I in 1 .. T.A'last loop
+      N := 1;
+    end loop;
+  end;
+
+end Opt13_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt13_pkg.ads b/gcc/testsuite/gnat.dg/opt13_pkg.ads
new file mode 100644
index 0000000000000000000000000000000000000000..39567f606d48a9f83dd68fa81c491d9e5538bfda
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt13_pkg.ads
@@ -0,0 +1,15 @@
+package Opt13_Pkg is
+
+    N : Natural := 0;
+
+    type My_Type is private;
+
+    procedure Allocate (T : out My_Type);
+
+private
+
+    type Data;
+
+    type My_Type is access Data;
+
+end Opt13_Pkg;
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 6efb2453d3a577afbbc843d62c471a2860d15246..970f2c0276a1ef6fcf7c8dd0f278927b146b787a 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1339,6 +1339,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
       size2 = TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 2)) * 8;
       if ((unsigned HOST_WIDE_INT)size2 / 8
 	  == TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 2))
+	  && maxsize2 != -1
 	  && operand_equal_p (base, base2, 0)
 	  && offset2 <= offset
 	  && offset2 + size2 >= offset + maxsize)
@@ -1362,7 +1363,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
       HOST_WIDE_INT offset2, size2, maxsize2;
       base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
 				       &offset2, &size2, &maxsize2);
-      if (operand_equal_p (base, base2, 0)
+      if (maxsize2 != -1
+	  && operand_equal_p (base, base2, 0)
 	  && offset2 <= offset
 	  && offset2 + size2 >= offset + maxsize)
 	{
@@ -1383,7 +1385,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
 	       || handled_component_p (gimple_assign_rhs1 (def_stmt))))
     {
       tree base2;
-      HOST_WIDE_INT offset2, size2;
+      HOST_WIDE_INT offset2, size2, maxsize2;
       int i, j;
       VEC (vn_reference_op_s, heap) *rhs = NULL;
       vn_reference_op_t vro;
@@ -1396,8 +1398,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
       base2 = ao_ref_base (&lhs_ref);
       offset2 = lhs_ref.offset;
       size2 = lhs_ref.size;
-      if ((base != base2
-	   && !operand_equal_p (base, base2, 0))
+      maxsize2 = lhs_ref.max_size;
+      if (maxsize2 == -1
+	  || (base != base2 && !operand_equal_p (base, base2, 0))
 	  || offset2 > offset
 	  || offset2 + size2 < offset + maxsize)
 	return (void *)-1;