Bug 36879

Summary: [4.4 Regression] undefined reference to a variable
Product: gcc Reporter: Andrew Pinski <pinskia>
Component: tree-optimizationAssignee: Andrew Pinski <pinskia>
Status: RESOLVED FIXED    
Severity: blocker CC: gcc-bugs, segher
Priority: P3 Keywords: link-failure, patch
Version: 4.4.0   
Target Milestone: 4.4.0   
URL: http://gcc.gnu.org/ml/gcc-patches/2008-07/msg01507.html
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36882
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2008-07-19 21:54:30

Description Andrew Pinski 2008-07-19 21:53:15 UTC
Take the following testcase:
typedef unsigned int u32;
static const u32 deadfish = 0xdeadf155;
static const u32 cfb_tab8_be[] = {
    0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
    0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
    0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
    0xffff0000,0xffff00ff,0xffffff00,0xffffffff
};
static const u32 cfb_tab8_le[] = {
    0x00000000,0xff000000,0x00ff0000,0xffff0000,
    0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
    0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
    0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
};
static const u32 cfb_tab16_be[] = {
    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
};
static const u32 cfb_tab16_le[] = {
    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
};
static const u32 cfb_tab32[] = {
 0x00000000, 0xffffffff
};
const u32 *xxx(int bpp)
{
 const u32 *tab;
if (0) return &deadfish;
 switch (bpp) {
 case 8:
  tab = cfb_tab8_be;
  break;
 case 16:
  tab = cfb_tab16_be;
  break;
 case 32:
 default:
  tab = cfb_tab32;
  break;
 }
 return tab;
}
int main(void)
{
  const u32 *a = xxx(8);
  int b = a[0];
  if (b != cfb_tab8_be[0])
    __builtin_abort ();
  return 0;
}

-- CUT ---
Currently at -O2, we will get an undefined symbol:
/tmp/ccuZc5eC.o:(.data+0x20): undefined reference to `cfb_tab16_be'
collect2: ld returned 1 exit status

This is caused by switch-conversion pass.
Comment 1 Andrew Pinski 2008-07-19 21:54:30 UTC
I have a patch which I am testing right now:
Index: gcc/gcc/tree-switch-conversion.c
===================================================================
--- gcc/gcc/tree-switch-conversion.c    (revision 137991)
+++ gcc/gcc/tree-switch-conversion.c    (working copy)
@@ -474,7 +474,8 @@ build_one_array (tree swtch, int num, tr
   DECL_ARTIFICIAL (decl) = 1;
   TREE_CONSTANT (decl) = 1;
   add_referenced_var (decl);
-  assemble_variable (decl, 0, 0, 0);
+  varpool_mark_needed_node (varpool_node (decl));
+  varpool_finalize_decl (decl);
   mark_sym_for_renaming (decl);
 
   name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL_TREE);

---- CUT ----
There is still a missed optimization but I will test/submit that patch separately.
Comment 2 Andrew Pinski 2008-07-20 17:52:26 UTC
Fixed.
Comment 3 Andrew Pinski 2008-07-20 17:52:33 UTC
Subject: Bug 36879

Author: pinskia
Date: Sun Jul 20 17:51:48 2008
New Revision: 138012

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=138012
Log:
2008-07-20  Andrew Pinski  <andrew_pinski@playstation.sony.com>

        PR tree-opt/36879
        * tree-switch-conversion.c (build_one_array): Call
        varpool_mark_needed_node and varpool_finalize_decl
        instead of assemble_variable.

2008-07-20  Andrew Pinski  <andrew_pinski@playstation.sony.com>

        PR tree-opt/36879
        * gcc.c-torture/execute/20080719-1.c: New testcase.


Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/20080719-1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-switch-conversion.c