This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/78354] New: range information lost after unsigned conversion
- From: "msebor at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 15 Nov 2016 00:34:51 +0000
- Subject: [Bug tree-optimization/78354] New: range information lost after unsigned conversion
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78354
Bug ID: 78354
Summary: range information lost after unsigned conversion
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
Assigning a variable whose range is strictly within the bounds of a narrower
unsigned is converted to that type the range is preserved. However, when one
of the bounds of a variable exceeds the corresponding bound of the narrower
type converting it to that narrower type loses both bounds (and the range after
conversion becomes VARYING) even though the other bound is within the
destination type's range and could be preserved. Since such conversions are
common enhancing the VRP engine to recognize this and preserve the bound is
likely to improve generated code.
The following test case demonstrates this using variables of unsigned int and
unsigned short but other types are subject to the same limitation.
$ cat c.c && gcc -O2 -S -Wall -fdump-tree-vrp=/dev/stdout c.c
void f (unsigned x)
{
if (x < 123 || 123456 < x)
x = 123;
unsigned short y = x;
if (y < 123)
__builtin_abort ();
}
;; Function f (f, funcdef_no=0, decl_uid=1795, cgraph_uid=0, symbol_order=0)
;; 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 succs { 1 }
Adding assert for x_3(D) from x_3(D) + 4294967173
Adding assert for x_3(D) from x_3(D) + 4294967173
SSA replacement table
N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j
x_7 -> { x_3(D) }
x_8 -> { x_3(D) }
Incremental SSA update started at block: 2
Number of blocks in CFG: 8
Number of blocks to update: 4 ( 50%)
Value ranges after VRP:
_1: [0, +INF]
x_2: [123, 123456] EQUIVALENCES: { } (0 elements)
x_3(D): VARYING
y_4: [0, +INF]
x_7: ~[123, 123456] EQUIVALENCES: { x_3(D) } (1 elements)
x_8: [123, 123456] EQUIVALENCES: { x_3(D) } (1 elements)
Removing basic block 3
Removing basic block 7
SSA replacement table
N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j
x_9 -> { x_2 }
y_10 -> { y_4 }
Incremental SSA update started at block: 2
Number of blocks in CFG: 7
Number of blocks to update: 3 ( 43%)
f (unsigned int x)
{
short unsigned int y;
unsigned int _1;
<bb 2>:
_1 = x_3(D) + 4294967173;
if (_1 > 123333)
goto <bb 6>;
else
goto <bb 3>;
<bb 3>:
# x_2 = PHI <x_3(D)(2)>
y_4 = (short unsigned int) x_2;
if (y_4 <= 122)
goto <bb 4>;
else
goto <bb 5>;
<bb 4>:
__builtin_abort ();
<bb 5>:
return;
<bb 6>:
# x_9 = PHI <123(2)>
y_10 = (short unsigned int) x_9;
goto <bb 5>;
}
;; Function f (f, funcdef_no=0, decl_uid=1795, cgraph_uid=0, symbol_order=0)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2 3 4 5
;; 2 succs { 5 3 }
;; 3 succs { 4 5 }
;; 4 succs { }
;; 5 succs { 1 }
Adding assert for x_3(D) from x_3(D) + 4294967173
SSA replacement table
N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j
x_2 -> { x_3(D) }
Incremental SSA update started at block: 2
Number of blocks in CFG: 6
Number of blocks to update: 2 ( 33%)
Value ranges after VRP:
_1: [0, +INF]
x_2: [123, 123456] EQUIVALENCES: { x_3(D) } (1 elements)
x_3(D): VARYING
y_4: [0, +INF]
f (unsigned int x)
{
short unsigned int y;
unsigned int _1;
<bb 2>:
_1 = x_3(D) + 4294967173;
if (_1 > 123333)
goto <bb 5>;
else
goto <bb 3>;
<bb 3>:
y_4 = (short unsigned int) x_3(D);
if (y_4 <= 122)
goto <bb 4>;
else
goto <bb 5>;
<bb 4>:
__builtin_abort ();
<bb 5>:
return;
}