This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/69984] New: [4.9/5/6] Signed comparison instruction emitted for unsigned variable comparison
- From: "edmar at freescale dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 26 Feb 2016 22:50:29 +0000
- Subject: [Bug tree-optimization/69984] New: [4.9/5/6] Signed comparison instruction emitted for unsigned variable comparison
- Auto-submitted: auto-generated
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;
}