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/78354] New: range information lost after unsigned conversion


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;

}

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