CRIS: Add hardware support for __builtin_ctz

Jesper Nilsson jesper.nilsson@axis.com
Wed Sep 5 09:41:00 GMT 2007


On Tue, Sep 04, 2007 at 09:28:13PM +0200, Rask Ingemann Lambertsen wrote:
> On Tue, Sep 04, 2007 at 04:30:48PM +0200, Jesper Nilsson wrote:
> > One question mark still remaining is why the define_expand for
> > ctzsi2 can't use the following:
> > 
> > (define_expand "ctzsi2"
> >   [(set (match_scratch:SI 2)
> >         (match_operand:SI 0 "register_operand"))
> >    (set (match_dup 2)
> >         (unspec:SI [(match_dup 2)] CRIS_UNSPEC_SWAP_BITS))
> >    (set (match_operand:SI 0 "register_operand")
> >         (clz:SI (match_dup 2)))
> >   ]
> >   "TARGET_HAS_LZ && TARGET_HAS_SWAP"
> >   ""
> >   )
> > If the above construction is used, I get an ICE in copy_rtx for the
> > scratch operand...
> 
>    It should be fine, so that's a bug. It's unusual to have a (set (scratch)
> ...) construct, which is probably why it hasn't been caught until now.
>
> What is the ICE, btw? 

Hmm.  Unfortunately, the above code was not the one I got the ICE with.
I must have started to modify it before saving it.  Sorry about that. 

Here's what I reproduced the ICE with:

(define_expand "ctzsi2"
  [(set (match_scratch:SI 2)
        (match_operand:SI 1 "register_operand"))
   (set (match_dup 2)
        (unspec:SI [(match_dup 2)] CRIS_UNSPEC_SWAP_BITS))
   (set (match_operand:SI 0 "register_operand")
        (clz:SI (match_dup 2)))
  ]
  "TARGET_HAS_LZ && TARGET_HAS_SWAP"
  ""
  )

$ cris-elf-gcc -march=v10 ~/builtin_ctz_v8.c
/h/jespern/builtin_ctz_v8.c: In function 'f':
/h/jespern/builtin_ctz_v8.c:11: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
$ gdb /home/jespern/test2/libexec/gcc/cris-elf/4.3.0/cc1
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".

(gdb) run -quiet -v -imultilib v10 -D__arch_v10 -D__CRIS_arch_version=10 /h/jespern/builtin_ctz_v8.c -melf -quiet -dumpbase builtin_ctz_v8.c -march=v10 -auxbase builtin_ctz_v8 -version -o /tmp/ccpectWR.s
Starting program: /home/jespern/test2/libexec/gcc/cris-elf/4.3.0/cc1 -quiet -v -imultilib v10 -D__arch_v10 -D__CRIS_arch_version=10 /h/jespern/builtin_ctz_v8.c -melf -quiet -dumpbase builtin_ctz_v8.c -march=v10 -auxbase builtin_ctz_v8 -version -o /tmp/ccpectWR.s
Failed to read a valid object file image from memory.
ignoring nonexistent directory "/home/jespern/test2/lib/gcc/cris-elf/4.3.0/../../../../cris-elf/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /home/jespern/test2/lib/gcc/cris-elf/4.3.0/include
 /home/jespern/test2/lib/gcc/cris-elf/4.3.0/include-fixed
 /home/jespern/test2/lib/gcc/cris-elf/4.3.0/../../../../cris-elf/include
End of search list.
GNU C (GCC) version 4.3.0 20070904 (experimental) (cris-elf)
        compiled by GNU C version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21), GMP version 4.2.1, MPFR version 2.2.0.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 836e46782236a87a1c37b7d1aa0bc14b

Program received signal SIGSEGV, Segmentation fault.
0x082f2a4c in copy_rtx (orig=0xd2) at ../../gcc.clz/gcc/rtl.c:232
232       switch (code)
(gdb) bt
#0  0x082f2a4c in copy_rtx (orig=0xd2) at ../../gcc.clz/gcc/rtl.c:232
#1  0x08513a0e in gen_ctzsi2 (operand0=0xb7c54ee0, operand1=0xb7c54ed0)
    at ../../gcc.clz/gcc/config/cris/cris.md:2701
#2  0x0829b6ba in expand_unop_direct (mode=SImode, unoptab=0x86f9370,
    op0=0xb7c54ed0, target=0xb7c54ee0, unsignedp=1)
    at ../../gcc.clz/gcc/optabs.c:3035
#3  0x08299659 in expand_unop (mode=SImode, unoptab=0x86f9370, op0=0xb7c54ed0,
    target=0xb7c54ee0, unsignedp=1) at ../../gcc.clz/gcc/optabs.c:3075
#4  0x08108806 in expand_builtin_unop (target_mode=SImode, exp=0xb7c59058,
    target=0xb7c54ee0, subtarget=0xb7c54ee0, op_optab=0x86f9370)
    at ../../gcc.clz/gcc/builtins.c:5104
#5  0x08110b6d in expand_builtin (exp=0xb7c59058, target=0xb7c54ee0,
    subtarget=0xb7c54ee0, mode=SImode, ignore=0)
    at ../../gcc.clz/gcc/builtins.c:6360
#6  0x081b016d in expand_expr_real_1 (exp=<value optimized out>,
    target=0xb7c54ee0, tmode=<value optimized out>, modifier=EXPAND_NORMAL,
    alt_rtl=0xbfb611f8) at ../../gcc.clz/gcc/expr.c:7950
#7  0x081be66c in expand_expr_real (exp=0xb7c59058, target=0xb7c54ee0,
    tmode=SImode, modifier=EXPAND_NORMAL, alt_rtl=0xbfb611f8)
    at ../../gcc.clz/gcc/expr.c:6961
#8  0x081c4b49 in store_expr (exp=0xb7c59058, target=0xb7c54ee0,
    call_param_p=0, nontemporal=0 '\0') at ../../gcc.clz/gcc/expr.c:4538
#9  0x081c67c4 in expand_assignment (to=0xb7cc9000, from=0xb7c59058,
    nontemporal=0 '\0') at ../../gcc.clz/gcc/expr.c:4322
#10 0x081aa33f in expand_expr_real_1 (exp=0xb7cc7ea8,
    target=<value optimized out>, tmode=VOIDmode, modifier=EXPAND_NORMAL,
    alt_rtl=0x0) at ../../gcc.clz/gcc/expr.c:8986
#11 0x081be66c in expand_expr_real (exp=0xb7cc7ea8, target=0xb7c52200,
    tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc.clz/gcc/expr.c:6961
#12 0x08311105 in expand_expr_stmt (exp=0xb7cc7ea8)
    at ../../gcc.clz/gcc/expr.h:514
#13 0x0853a0b8 in expand_gimple_basic_block (bb=0xb7f06528)
    at ../../gcc.clz/gcc/cfgexpand.c:1606
#14 0x0853b10a in tree_expand_cfg () at ../../gcc.clz/gcc/cfgexpand.c:1913
#15 0x082a2a7f in execute_one_pass (pass=0x869ae00)
    at ../../gcc.clz/gcc/passes.c:1108
#16 0x082a2c87 in execute_pass_list (pass=0x869ae00)
    at ../../gcc.clz/gcc/passes.c:1161
#17 0x08384169 in tree_rest_of_compilation (fndecl=0xb7cbc780)
    at ../../gcc.clz/gcc/tree-optimize.c:405
#18 0x084e6fc5 in cgraph_expand_function (node=0xb7cbc800)
    at ../../gcc.clz/gcc/cgraphunit.c:1077
#19 0x084e880d in cgraph_assemble_pending_functions ()
    at ../../gcc.clz/gcc/cgraphunit.c:440
#20 0x084e91e5 in cgraph_finalize_function (decl=0xb7cbc780, nested=0 '\0')
    at ../../gcc.clz/gcc/cgraphunit.c:557
#21 0x08053a7d in finish_function () at ../../gcc.clz/gcc/c-decl.c:6806
#22 0x080c0295 in c_parser_declaration_or_fndef (parser=0xb7cbe090,
    fndef_ok=1 '\001', empty_ok=1 '\001', nested=0 '\0',
    start_attr_ok=1 '\001') at ../../gcc.clz/gcc/c-parser.c:1414
#23 0x080cbd9f in c_parser_external_declaration (parser=0xb7cbe090)
    at ../../gcc.clz/gcc/c-parser.c:1171
#24 0x080cc611 in c_parse_file () at ../../gcc.clz/gcc/c-parser.c:1074
#25 0x080b259a in c_common_parse_file (set_yydebug=0)
    at ../../gcc.clz/gcc/c-opts.c:1280
#26 0x0831e264 in toplev_main (argc=18, argv=0xbfb61884)
    at ../../gcc.clz/gcc/toplev.c:1045
#27 0x080dab82 in main (argc=5, argv=0x7) at ../../gcc.clz/gcc/main.c:35
(gdb) up
#1  0x08513a0e in gen_ctzsi2 (operand0=0xb7c54ee0, operand1=0xb7c54ed0)
    at ../../gcc.clz/gcc/config/cris/cris.md:2701
2701            (unspec:SI [(match_dup 2)] CRIS_UNSPEC_SWAP_BITS))
(gdb) p operand2
$2 = (rtx) 0xd2
(gdb)

>    Note that (match_operand "register_operand") won't match a (scratch ...)
> expression. Thus you probably wouldn't get far even without the ICE in
> copy_rtx.

I'm not quite sure I understand the problem, could you please elaborate?

> > +(define_expand "ctzsi2"
> > +  [(set (match_dup 2)
> > +        (match_operand:SI 1 "register_operand"))
> > +   (set (match_dup 2)
> > +        (unspec:SI [(match_dup 2)] CRIS_UNSPEC_SWAP_BITS))
> > +   (set (match_operand:SI 0 "register_operand")
> > +        (clz:SI (match_dup 2)))]
> > +  "TARGET_HAS_LZ && TARGET_HAS_SWAP"
> > +  "operands[2] = gen_reg_rtx (SImode);"
> > +  )
> 
>    This should result in better code because local-alloc and global-alloc
> will know about the scratch register.

> Rask Ingemann Lambertsen

Thanks!

/^JN - Jesper Nilsson



More information about the Gcc-patches mailing list