From: jakub Date: Wed, 15 Oct 2008 06:43:19 +0000 (+0000) Subject: PR tree-optimization/36881 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=54af7f7e3f0f38a4cd5667fda9fd9a68ad554df0;p=thirdparty%2Fgcc.git PR tree-optimization/36881 * tree-switch-conversion.c (check_final_bb): For flag_pic, check that each value doesn't need runtime relocations, for !flag_pic check that each value is just a valid initializer constant. * gcc.dg/tree-ssa/pr36881.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141129 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 84625a1f2b1a..200958413d4c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-10-15 Jakub Jelinek + + PR tree-optimization/36881 + * tree-switch-conversion.c (check_final_bb): For flag_pic, check + that each value doesn't need runtime relocations, for !flag_pic + check that each value is just a valid initializer constant. + 2008-10-14 Richard Sandiford * config/mips/mips.h (reg_class): Remove HI_AND_GR_REGS, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 12090cc227de..731785cb5a9a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-10-15 Jakub Jelinek + + PR tree-optimization/36881 + * gcc.dg/tree-ssa/pr36881.c: New test. + 2008-10-14 Jakub Jelinek PR c++/37819 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr36881.c b/gcc/testsuite/gcc.dg/tree-ssa/pr36881.c new file mode 100644 index 000000000000..742dd9ddb4b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr36881.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/36881 */ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-O2 -fpic -fdump-tree-switchconv-all" } */ + +const char *foo (int i) +{ + const char *p; + switch (i) + { + case 0: + case 6: p = ""; break; + case 1: + case 7: p = "abc"; break; + case 2: + case 8: p = "def"; break; + default: p = "ghi"; break; + } + return p; +} + +/* { dg-final { scan-assembler-not "CSWTCH" } } */ +/* { dg-final { scan-tree-dump "need runtime relocations" "switchconv" } } */ +/* { dg-final { cleanup-tree-dump "switchconv" } } */ diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index e9757454f219..798cf1615694 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -296,12 +296,29 @@ check_final_bb (void) { basic_block bb = gimple_phi_arg_edge (phi, i)->src; - if ((bb == info.switch_bb - || (single_pred_p (bb) && single_pred (bb) == info.switch_bb)) - && !is_gimple_ip_invariant (gimple_phi_arg_def (phi, i))) + if (bb == info.switch_bb + || (single_pred_p (bb) && single_pred (bb) == info.switch_bb)) { - info.reason = " Non-invariant value from a case\n"; - return false; /* Non-invariant argument. */ + tree reloc, val; + + val = gimple_phi_arg_def (phi, i); + if (!is_gimple_ip_invariant (val)) + { + info.reason = " Non-invariant value from a case\n"; + return false; /* Non-invariant argument. */ + } + reloc = initializer_constant_valid_p (val, TREE_TYPE (val)); + if ((flag_pic && reloc != null_pointer_node) + || (!flag_pic && reloc == NULL_TREE)) + { + if (reloc) + info.reason + = " Value from a case would need runtime relocations\n"; + else + info.reason + = " Value from a case is not a valid initializer\n"; + return false; + } } } }