From f1b0632aabe6473bf810b5e901d979a4570b7de5 Mon Sep 17 00:00:00 2001 From: Olivier Hainque Date: Fri, 10 Mar 2017 11:16:21 +0000 Subject: [PATCH] tree-switch-conversion (array_value_type): Start by resetting candidate type to it's main variant. 2017-03-10 Olivier Hainque * tree-switch-conversion (array_value_type): Start by resetting candidate type to it's main variant. testsuite/ * gnat.dg/opt64.adb: New test. * gnat.dg/opt64_pkg.ads: New helper. * gnat.dg/opt64_pkg.adb: New helper. From-SVN: r246024 --- gcc/ChangeLog | 5 +++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gnat.dg/opt64.adb | 25 +++++++++++++++++++++++++ gcc/testsuite/gnat.dg/opt64_pkg.adb | 14 ++++++++++++++ gcc/testsuite/gnat.dg/opt64_pkg.ads | 6 ++++++ gcc/tree-switch-conversion.c | 13 ++++++++++--- 6 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/opt64.adb create mode 100644 gcc/testsuite/gnat.dg/opt64_pkg.adb create mode 100644 gcc/testsuite/gnat.dg/opt64_pkg.ads diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b44a7a57c38..5050ca8d822 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2017-03-10 Olivier Hainque + + * tree-switch-conversion (array_value_type): Start by resetting + candidate type to it's main variant. + 2017-03-10 Jakub Jelinek PR rtl-optimization/79909 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bf1c69d7425..b17299b9400 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-03-10 Olivier Hainque + + * gnat.dg/opt64.adb: New test. + * gnat.dg/opt64_pkg.ads: New helper. + * gnat.dg/opt64_pkg.adb: New helper. + 2017-03-10 Jakub Jelinek PR rtl-optimization/79909 diff --git a/gcc/testsuite/gnat.dg/opt64.adb b/gcc/testsuite/gnat.dg/opt64.adb new file mode 100644 index 00000000000..6d287d301a1 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt64.adb @@ -0,0 +1,25 @@ +-- { dg-do run } +-- { dg-options "-O2" } + +-- The issue which prompted the test is a compilation failure. Might +-- as well verify that the generated code performs as expected. + +with opt64_pkg; use opt64_pkg; + +procedure opt64 is + procedure assert (T : boolean) is + begin + if not T then + raise program_error; + end if; + end; +begin + Encode (1); + assert (last_hash = "1"); + Encode (2); + assert (last_hash = "2"); + Encode (3); + assert (last_hash = "3"); + Encode (6); + assert (last_hash = "?"); +end; diff --git a/gcc/testsuite/gnat.dg/opt64_pkg.adb b/gcc/testsuite/gnat.dg/opt64_pkg.adb new file mode 100644 index 00000000000..5235e73b88a --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt64_pkg.adb @@ -0,0 +1,14 @@ +package body Opt64_PKG is + + procedure Encode (X : Integer) is + result : Hash; + begin + case X is + when 1 => result := "1"; + when 2 => result := "2"; + when 3 => result := "3"; + when others => Result := "?"; + end case; + Last_Hash := Result; + end; +end; diff --git a/gcc/testsuite/gnat.dg/opt64_pkg.ads b/gcc/testsuite/gnat.dg/opt64_pkg.ads new file mode 100644 index 00000000000..e4b09fcc026 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt64_pkg.ads @@ -0,0 +1,6 @@ +package Opt64_PKG is + type Hash is new string (1 .. 1); + Last_Hash : Hash; + + procedure Encode (X : Integer); +end; diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index ce1d11dca39..1ccb4bdba1a 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -935,9 +935,9 @@ constructor_contains_same_values_p (vec *vec) return prev; } -/* Return type which should be used for array elements, either TYPE, - or for integral type some smaller integral type that can still hold - all the constants. */ +/* Return type which should be used for array elements, either TYPE's + main variant or, for integral types, some smaller integral type + that can still hold all the constants. */ static tree array_value_type (gswitch *swtch, tree type, int num, @@ -949,6 +949,13 @@ array_value_type (gswitch *swtch, tree type, int num, int sign = 0; tree smaller_type; + /* Types with alignments greater than their size can reach here, e.g. out of + SRA. We couldn't use these as an array component type so get back to the + main variant first, which, for our purposes, is fine for other types as + well. */ + + type = TYPE_MAIN_VARIANT (type); + if (!INTEGRAL_TYPE_P (type)) return type;