it seems the code which notices things like assert(x > 0) to help
strength-reduce division to shifts doesn't help if the divide is inside a loop.
 for example:

% cat idiv-assert.c
void fail(void) __attribute__((noreturn));
int bar(int);

int foo(int x) {
  int i;
  int s = 0;

  if (x <= 0) fail();
  for (i = 0; i < x; ++i) {
    s += bar(i/4);
  }
  return s;
}
% gcc -g -O3 -Wall   -c -o idiv-assert.o idiv-assert.c
% objdump -dr idiv-assert.o

idiv-assert.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <foo>:
   0:   41 54                   push   %r12
   2:   41 89 fc                mov    %edi,%r12d
   5:   55                      push   %rbp
   6:   31 ed                   xor    %ebp,%ebp
   8:   53                      push   %rbx
   9:   31 db                   xor    %ebx,%ebx
   b:   85 ff                   test   %edi,%edi
   d:   7e 22                   jle    31 <foo+0x31>
   f:   90                      nop
  10:   8d 7b 03                lea    0x3(%rbx),%edi
  13:   85 db                   test   %ebx,%ebx
  15:   0f 49 fb                cmovns %ebx,%edi
  18:   83 c3 01                add    $0x1,%ebx
  1b:   c1 ff 02                sar    $0x2,%edi
  1e:   e8 00 00 00 00          callq  23 <foo+0x23>
                        1f: R_X86_64_PC32       bar+0xfffffffffffffffc
  23:   01 c5                   add    %eax,%ebp
  25:   41 39 dc                cmp    %ebx,%r12d
  28:   7f e6                   jg     10 <foo+0x10>
  2a:   5b                      pop    %rbx
  2b:   89 e8                   mov    %ebp,%eax
  2d:   5d                      pop    %rbp
  2e:   41 5c                   pop    %r12
  30:   c3                      retq
  31:   e8 00 00 00 00          callq  36 <foo+0x36>
                        32: R_X86_64_PC32       fail+0xfffffffffffffffc
% gcc -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/home/odo/gcc --disable-multilib
--disable-biarch x86_64-unknown-linux-gnu --enable-languages=c
Thread model: posix
gcc version 4.3.0 20070217 (experimental)

note that gcc handles a more trivial case just fine:

if (x <= 0) fail();
return x / 4;

-dean


-- 
           Summary: strength-reduce idiv given assertion numerator is
                    positive
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: pending
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: dean at arctic dot org
 GCC build triplet: x86_64-unknown-linux-gnu
  GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: x86_64-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31521

Reply via email to