This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the EGCS project.
ICE / incorrect codegen with __builtin_ffs
- To: gcc-bugs@gcc.gnu.org
- Subject: ICE / incorrect codegen with __builtin_ffs
- From: Zack Weinberg <zack@bitmover.com>
- Date: Sat, 24 Jul 1999 10:51:10 -0700
The appended fragment generates incorrect code with the current CVS
mainline: specifically, it produces a call to "__builtin_ffs", which
is not a library function. --enable-checking turns it into an ICE:
$ ./cc1 -O2 sprof.i
load_shobj
sprof.i: In function `load_shobj':
sprof.i:49: builtins.c:1924: Expect tree_list, have call_expr
There are two separate bugs here. One is that expand_builtin should
look up the real name of the library function if it gets past the big
switch, instead of blindly calling expand_call(exp, target, ignore).
The other is that the wrong tree has been handed to
expand_builtin_ffs.
Starting program: ./cc1 -O2 sprof.i
load_shobj
Breakpoint 1, expand_builtin_ffs (arglist=0x82cc264, target=0x0, subtarget=0x0)
at ../../../src/egcs/gcc/builtins.c:1922
1922 if (arglist == 0
(gdb) p arglist
$1 = 0x82cc264
(gdb) pt
<call_expr 0x82cc264
type <integer_type 0x82ca870 int allocated from permanent_obstack
permanent SI
size <integer_cst 0x82caa50 constant permanent 32>
align 32 symtab 0 alias set 2 precision 32
min <integer_cst 0x82ca8d0 constant permanent -2147483648>
max <integer_cst 0x82ca8e8 constant permanent 2147483647>
pointer_to_this <pointer_type 0x82d0ec4>>
allocated from momentary_obstack
side-effects
arg 0 <addr_expr 0x82cc23c
type <pointer_type 0x82dff30 type <function_type 0x82d179c>
allocated from permanent_obstack
unsigned permanent SI size <integer_cst 0x82caa50 32>
align 32 symtab 0 alias set -1>
allocated from momentary_obstack
arg 0 <function_decl 0x82d1f74 __builtin_ffs
type <function_type 0x82d179c>
allocated from permanent_obstack
used permanent public external built-in QI file <built-in> line 0
built-in code 5
(mem/f:QI (symbol_ref:SI ("__builtin_ffs")) 0)
chain <function_decl 0x82d1e8c __builtin_alloca>>>
arg 1 <tree_list 0x82cb440 allocated from function obstack
value <nop_expr 0x82cc250 type <integer_type 0x82ca870 int>
allocated from momentary_obstack
arg 0 <mult_expr 0x82cc224
type <integer_type 0x82cadc4 unsigned int>
allocated from momentary_obstack
arg 0 <component_ref 0x82cc1f4
type <integer_type 0x82cadc4 unsigned int>
allocated from momentary_obstack
arg 0 <indirect_ref 0x82cc1e0
type <record_type 0x82de7b4 shobj>
allocated from momentary_obstack
arg 0 <var_decl 0x82cd724 result>>
arg 1 <field_decl 0x82df26c hashfraction>>
arg 1 <integer_cst 0x82cc20c constant 8>>>>
rtl 2 (nil)
>
I believe the tree expand_builtin_ffs wanted to see was
TREE_OPERAND(,1) of this -- that's a one line fix:
--- builtins.c 1999/07/22 11:04:58 1.1
+++ builtins.c 1999/07/24 17:42:06
@@ -2067,7 +2067,7 @@
break;
case BUILT_IN_FFS:
- target = expand_builtin_ffs (exp, target, subtarget);
+ target = expand_builtin_ffs (arglist, target, subtarget);
if (target)
return target;
break;
With that change applied, we successfully compile both the test case
below and the larger file it was extracted from.
zw
typedef unsigned int size_t;
typedef unsigned int uintptr_t;
typedef unsigned short uint16_t;
struct here_fromstruct
{
struct here_cg_arc_record volatile *here;
uint16_t link;
};
struct link_map;
struct Elf32_Sym;
struct shobj
{
const char *name;
struct link_map *map;
const char *dynstrtab;
const char *soname;
uintptr_t lowpc;
uintptr_t highpc;
unsigned long int kcountsize;
size_t expected_size;
size_t tossize;
size_t fromssize;
size_t fromlimit;
unsigned int hashfraction;
int s_scale;
void *symbol_map;
size_t symbol_mapsize;
const struct Elf32_Sym *symtab;
size_t symtab_size;
const char *strtab;
};
static struct shobj *
load_shobj (const char *name)
{
struct shobj *result;
size_t textsize;
unsigned int log_hashfraction;
textsize = result->highpc - result->lowpc;
result->kcountsize = textsize / 2;
result->hashfraction = 2;
if ((2 & (2 - 1)) == 0)
log_hashfraction = __builtin_ffs (result->hashfraction
* sizeof (struct here_fromstruct)) - 1;
else
log_hashfraction = -1;
return result;
}