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/80006] New: loss of range information after widening conversion


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

            Bug ID: 80006
           Summary: loss of range information after widening 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: ---

This bug is the cause of bug 79356 (discussed here:
https://gcc.gnu.org/ml/gcc-patches/2017-02/msg00684.html).

When the following test case is compiled for some targets (such as powerpc64)
it emits a diagnostic for the call to ff in f as expected.  This is thanks the
range of the x variable is correctly represented as the anti-range ~[-3, 7],
which means that valid (i.e., non-negative) argument to the allocation function
is greater greater than 7 (negative argument are considered invalid).

However, the same warning is not issued for the call to gg, or even for ff on
on other targets (such as x86_64).  The reason is that VRP appears to "lose"
the range of the signed char variable x when it's converted to int.  On x86_64,
this conversion from signed char to int is for some reason performed even in
function f, so the test program triggers no warnings.  On powerpc64, the
conversion is not done in f but it is done in g where it is explicit.

In summary, it seems as though there are two problems:
1) the spurious signed char to int conversion on x86_64 inserted (very early on
-- as can be seen in the tree-original dump)
2) the loss of range info when converting a signed char variable to signed int.

$ cat t.c && /build/powerpc64le-linux-gnu/gcc-trunk/gcc/xgcc -B
/build/powerpc64le-linux-gnu/gcc-trunk/gcc -O2 -S -Wall -Wextra -Wpedantic
-Walloc-size-larger-than=7 -fdump-tree-vrp=/dev/stdout t.c
void* f (signed char x)
{
  extern void* ff (signed char) __attribute__ ((alloc_size (1)));

  if (-3 <= x && x <= 7)
    x = -4;

  return ff (x);
}

void* g (signed char x)
{
  extern void* gg (int) __attribute__ ((alloc_size (1)));

  if (-3 <= x && x <= 7)
    x = -4;

  return gg (x);
}



;; Function f (f, funcdef_no=0, decl_uid=2492, 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
;; 2 succs { 3 4 }
;; 3 succs { 4 }
;; 4 succs { 1 }
Adding assert for x_4(D) from (unsigned char) x_4(D) + 3
Adding assert for x_4(D) from (unsigned char) x_4(D) + 3

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

x_8 -> { x_4(D) }
x_9 -> { x_4(D) }
Incremental SSA update started at block: 2
Number of blocks in CFG: 6
Number of blocks to update: 4 ( 67%)



Value ranges after VRP:

x.0_1: [0, +INF]
_2: [0, +INF]
x_3: ~[-3, 7]  EQUIVALENCES: { } (0 elements)
x_4(D): VARYING
_7: VARYING
x_8: [-3, 7]  EQUIVALENCES: { x_4(D) } (1 elements)
x_9: ~[-3, 7]  EQUIVALENCES: { x_4(D) } (1 elements)


Removing basic block 3
f (signed char x)
{
  unsigned char x.0_1;
  unsigned char _2;
  void * _7;

  <bb 2> [100.00%]:
  x.0_1 = (unsigned char) x_4(D);
  _2 = x.0_1 + 3;
  if (_2 <= 10)
    goto <bb 4>; [54.00%]
  else
    goto <bb 3>; [46.00%]

  <bb 3> [46.00%]:

  <bb 4> [100.00%]:
  # x_3 = PHI <x_4(D)(3), -4(2)>
  _7 = ff (x_3);
  return _7;

}



;; Function f (f, funcdef_no=0, decl_uid=2492, 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
;; 2 succs { 3 4 }
;; 3 succs { 4 }
;; 4 succs { 1 }
Adding assert for x_4(D) from (unsigned char) x_4(D) + 3
Adding assert for x_4(D) from (unsigned char) x_4(D) + 3

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

x_8 -> { x_4(D) }
x_9 -> { x_4(D) }
Incremental SSA update started at block: 2
Number of blocks in CFG: 6
Number of blocks to update: 4 ( 67%)



Value ranges after VRP:

x.0_1: [0, +INF]
_2: [0, +INF]
x_3: ~[-3, 7]  EQUIVALENCES: { } (0 elements)
x_4(D): VARYING
_7: VARYING
x_8: [-3, 7]  EQUIVALENCES: { x_4(D) } (1 elements)
x_9: ~[-3, 7]  EQUIVALENCES: { x_4(D) } (1 elements)


Removing basic block 3
f (signed char x)
{
  unsigned char x.0_1;
  unsigned char _2;
  void * _7;

  <bb 2> [100.00%]:
  x.0_1 = (unsigned char) x_4(D);
  _2 = x.0_1 + 3;
  if (_2 <= 10)
    goto <bb 4>; [54.00%]
  else
    goto <bb 3>; [46.00%]

  <bb 3> [46.00%]:

  <bb 4> [100.00%]:
  # x_3 = PHI <x_4(D)(3), -4(2)>
  _7 = ff (x_3);
  return _7;

}


t.c: In function ‘f’:
t.c:8:10: warning: argument 1 range [8, 127] exceeds maximum object size 7
[-Walloc-size-larger-than=]
   return ff (x);
          ^~~~~~
t.c:3:16: note: in a call to allocation function ‘ff’ declared here
   extern void* ff (signed char) __attribute__ ((alloc_size (1)));
                ^~

;; Function g (g, funcdef_no=1, decl_uid=2498, cgraph_uid=1, symbol_order=1)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2 3 4
;; 2 succs { 3 4 }
;; 3 succs { 4 }
;; 4 succs { 1 }
Adding assert for x_5(D) from (unsigned char) x_5(D) + 3
Adding assert for x_5(D) from (unsigned char) x_5(D) + 3

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

x_9 -> { x_5(D) }
x_10 -> { x_5(D) }
Incremental SSA update started at block: 2
Number of blocks in CFG: 6
Number of blocks to update: 4 ( 67%)



Value ranges after VRP:

x.1_1: [0, +INF]
_2: [0, +INF]
_3: [-128, 127]
x_4: ~[-3, 7]  EQUIVALENCES: { } (0 elements)
x_5(D): VARYING
_8: VARYING
x_9: [-3, 7]  EQUIVALENCES: { x_5(D) } (1 elements)
x_10: ~[-3, 7]  EQUIVALENCES: { x_5(D) } (1 elements)


Removing basic block 3
g (signed char x)
{
  unsigned char x.1_1;
  unsigned char _2;
  int _3;
  void * _8;

  <bb 2> [100.00%]:
  x.1_1 = (unsigned char) x_5(D);
  _2 = x.1_1 + 3;
  if (_2 <= 10)
    goto <bb 4>; [54.00%]
  else
    goto <bb 3>; [46.00%]

  <bb 3> [46.00%]:

  <bb 4> [100.00%]:
  # x_4 = PHI <x_5(D)(3), -4(2)>
  _3 = (int) x_4;
  _8 = gg (_3);
  return _8;

}



;; Function g (g, funcdef_no=1, decl_uid=2498, cgraph_uid=1, symbol_order=1)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2 3 4
;; 2 succs { 4 3 }
;; 3 succs { 4 }
;; 4 succs { 1 }
Adding assert for x_5(D) from (unsigned char) x_5(D) + 3

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

x_4 -> { x_5(D) }
Incremental SSA update started at block: 2
Number of blocks in CFG: 5
Number of blocks to update: 2 ( 40%)



Value ranges after VRP:

x.1_1: [0, +INF]
_2: [0, +INF]
x_4: ~[-3, 7]  EQUIVALENCES: { x_5(D) } (1 elements)
x_5(D): VARYING
_8: VARYING
_9: [-128, 127]
prephitmp_10: [-128, 127]


g (signed char x)
{
  unsigned char x.1_1;
  unsigned char _2;
  void * _8;
  int _9;
  int prephitmp_10;

  <bb 2> [100.00%]:
  x.1_1 = (unsigned char) x_5(D);
  _2 = x.1_1 + 3;
  if (_2 <= 10)
    goto <bb 4>; [54.00%]
  else
    goto <bb 3>; [46.00%]

  <bb 3> [46.00%]:
  _9 = (int) x_5(D);

  <bb 4> [100.00%]:
  # prephitmp_10 = PHI <_9(3), -4(2)>
  _8 = gg (prephitmp_10);
  return _8;

}

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