This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/69984] New: [4.9/5/6] Signed comparison instruction emitted for unsigned variable comparison


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69984

            Bug ID: 69984
           Summary: [4.9/5/6] Signed comparison instruction emitted for
                    unsigned variable comparison
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: edmar at freescale dot com
  Target Milestone: ---

This test case has only unsigned variables and constants:

extern void bar1 (void);
extern void bar2 (void);
void foo (unsigned short int A, unsigned short int B, unsigned long D)
{
  unsigned long C;
  unsigned long E = 0x0FFFEFFEUL;

  C = A * B;

  if (C <= D)
    bar1 ();
  if (C <= E)
    bar2 ();
}

Yet, gcc generates signed comparison instruction (jle) for test C<=E:


        .file   "ucmp.c"
        .text
        .p2align 4,,15
        .globl  foo
        .type   foo, @function
foo:
.LFB0:
        .cfi_startproc
        pushq   %rbx
        .cfi_def_cfa_offset 16
        .cfi_offset 3, -16
        movzwl  %si, %esi
        movzwl  %di, %ebx
        imull   %esi, %ebx
        movslq  %ebx, %rax
        cmpq    %rdx, %rax
        jbe     .L6
.L2:
        cmpl    $268431358, %ebx
        jle     .L7
        popq    %rbx
        .cfi_remember_state
        .cfi_def_cfa_offset 8
        ret
        .p2align 4,,10
        .p2align 3
.L7:
        .cfi_restore_state
        popq    %rbx
        .cfi_remember_state
        .cfi_def_cfa_offset 8
        jmp     bar2
        .p2align 4,,10
        .p2align 3
.L6:
        .cfi_restore_state
        call    bar1
        jmp     .L2
        .cfi_endproc
.LFE0:
        .size   foo, .-foo
        .ident  "GCC: (GNU) 6.0.0 20160226 (Fri Feb 26 14:08:27 CST 2016       
 build.sh rev=1286 s=FCtrunk Nx86_64)"
        .section        .note.GNU-stack,"",@progbits




-fsanitize=<sub-options> silently corrects the code:
(I tried with *each of*: undefined, signed-integer-overflow, bounds,
unreachable, return, address. Any one will correct the code)
ex:
...
        imull   %esi, %ebx
        jo      .L8
.L2:
        movslq  %ebx, %rbx
        cmpq    %rbp, %rbx
        jbe     .L9
.L4:
        cmpq    $268431358, %rbx
        jbe     .L10
...



and also -fno-tree-vrp:
...
        imull   %ebx, %edi
        movslq  %edi, %rbx
        cmpq    %rdx, %rbx
        jbe     .L6
.L2:
        cmpq    $268431358, %rbx
        jbe     .L7
...



With PowerPC target I can trace this all the way back to 4.9.2 (Did not try
4.9.[01]). 4.8.3 generates correct code.



Test compiled with:
gcc -O3 -S ucmp.c




gcc configured with:

gcc -v
Using built-in specs.
COLLECT_GCC=/local/edmar/bug_area/opt/freescale/gcc-6.0.x-Nx86_64-linux/x86_64-linux/bin/gcc
COLLECT_LTO_WRAPPER=/local/edmar/bug_area/opt/freescale/gcc-6.0.x-Nx86_64-linux/x86_64-linux/bin/../libexec/gcc/x86_64-pc-linux/6.0.0/lto-wrapper
Target: x86_64-pc-linux
Configured with: ../src_gcc/configure
--prefix=/local/edmar/bug_area//opt/freescale/gcc-6.0.x-Nx86_64-linux/x86_64-linux
--target=x86_64-pc-linux --build=x86_64-pc-linux --enable-checking
--disable-decimal-float --enable-interfaces=c,c++ --with-cpu=generic
--enable-tls --enable-build-with-cxx --enable-languages=c,c++
--with-gmp=/local/edmar/bug_area//opt/freescale/Nx86_64/linux_host_libs/usr/64
--with-target-gmp=/local/edmar/bug_area//opt/freescale/Nx86_64/linux_host_libs/tgmp/64
--disable-target-multilib
--with-mpfr=/local/edmar/bug_area//opt/freescale/Nx86_64/linux_host_libs/usr/64
--with-mpc=/local/edmar/bug_area//opt/freescale/Nx86_64/linux_host_libs/usr/64
--with-ppl=/local/edmar/bug_area//opt/freescale/Nx86_64/linux_host_libs/usr/64
--with-isl=/local/edmar/bug_area//opt/freescale/Nx86_64/linux_host_libs/usr/64
--with-cloog=/local/edmar/bug_area//opt/freescale/Nx86_64/linux_host_libs/usr/64
--enable-cloog-backend=isl
Thread model: posix
gcc version 6.0.0 20160226 (Fri Feb 26 14:08:27 CST 2016         build.sh
rev=1286 s=FCtrunk Nx86_64) (GCC) 



ucmp.c.084t.oaccdevlow:
;; Function foo (foo, funcdef_no=0, decl_uid=1760, cgraph_uid=0,
symbol_order=1)

foo (short unsigned int A, short unsigned int B, long unsigned int D)
{
  long unsigned int C;
  int _4;
  int _6;
  int _7;
  long unsigned int E.0_12;

  <bb 2>:
  _4 = (int) A_3(D);
  _6 = (int) B_5(D);
  _7 = _4 * _6;
  C_8 = (long unsigned int) _7;
  if (C_8 <= D_9(D))
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  bar1 ();

  <bb 4>:
  E.0_12 = E;
  if (C_8 <= E.0_12)
    goto <bb 5>;
  else
    goto <bb 6>;

  <bb 5>:
  bar2 ();

  <bb 6>:
  return;

}


ucmp.c.086t.ccp2:
;; Function foo (foo, funcdef_no=0, decl_uid=1760, cgraph_uid=0,
symbol_order=1)

foo (short unsigned int A, short unsigned int B, long unsigned int D)
{
  long unsigned int C;
  int _4;
  int _6;
  int _7;

  <bb 2>:
  _4 = (int) A_3(D);
  _6 = (int) B_5(D);
  _7 = _4 * _6;
  C_8 = (long unsigned int) _7;
  if (C_8 <= D_9(D))
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  bar1 ();

  <bb 4>:
  if (C_8 <= 268431358)
    goto <bb 5>;
  else
    goto <bb 6>;

  <bb 5>:
  bar2 ();

  <bb 6>:
  return;

}



ucmp.c.096t.vrp1:
;; Function foo (foo, funcdef_no=0, decl_uid=1760, cgraph_uid=0,
symbol_order=1)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2 3 4 5 6
;; 2 succs { 3 4 }
;; 3 succs { 4 }
;; 4 succs { 5 6 }
;; 5 succs { 6 }
;; 6 succs { 1 }

SSA replacement table
N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j

C_12 -> { C_8 }
C_14 -> { C_8 }
Incremental SSA update started at block: 2
Number of blocks in CFG: 8
Number of blocks to update: 4 ( 50%)



Value ranges after VRP:

.MEM_1: VARYING
.MEM_2: VARYING
A_3(D): VARYING
_4: [0, 65535]
B_5(D): VARYING
_6: [0, 65535]
_7: [0, +INF(OVF)]
C_8: [0, +INF]
D_9(D): VARYING
C_12: [0, D_9(D)]  EQUIVALENCES: { C_8 } (1 elements)
C_14: [D_9(D) + 1, +INF]  EQUIVALENCES: { C_8 } (1 elements)


Removing basic block 7
foo (short unsigned int A, short unsigned int B, long unsigned int D)
{
  long unsigned int C;
  int _4;
  int _6;
  int _7;

  <bb 2>:
  _4 = (int) A_3(D);
  _6 = (int) B_5(D);
  _7 = _4 * _6;
  C_8 = (long unsigned int) _7;
  if (C_8 <= D_9(D))
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  bar1 ();

  <bb 4>:
  if (_7 <= 268431358)
    goto <bb 5>;
  else
    goto <bb 6>;

  <bb 5>:
  bar2 ();

  <bb 6>:
  return;

}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]