[Bug c/107785] New: Integer comparison result compile with -O3

2022-11-21 Thread mugglewei at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107785

Bug ID: 107785
   Summary: Integer comparison result compile with -O3
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: mugglewei at gmail dot com
  Target Milestone: ---

I have a ring buffer, in a loop put integer value and get position in the ring. 
-
#include 
#include 
#include 

#define IDX_IN_POW_OF_2_RING(idx, capacity) ((idx) & ((capacity) - 1))

// #define pos_t unsigned int  // it's ok
#define pos_t int

int main()
{
pos_t capacity = 1 << 10;
pos_t k = 16;
// pos_t pos = 0x7fff0fff;  // it's ok
pos_t pos = 0x7fffdfff;

fprintf(stderr, "capacity = 0x%08x, pos = 0x%08x\n", capacity, pos);
pos_t idx_in_ring = IDX_IN_POW_OF_2_RING(pos, capacity);
pos_t last_idx_in_ring = idx_in_ring;
pos_t loop_cnt = capacity * k;
for (pos_t i = 0; i < loop_cnt; ++i)
{
idx_in_ring = IDX_IN_POW_OF_2_RING(++pos, capacity);
assert(idx_in_ring >= 0);
assert(idx_in_ring < capacity);
if (last_idx_in_ring == capacity - 1)
{
assert(idx_in_ring == 0);
}
else
{
assert(idx_in_ring == last_idx_in_ring + 1);
}
last_idx_in_ring = idx_in_ring;

if (i % capacity == 0)
{
fprintf(stderr, "%d < %d is %s, pos = 0x%08x\n",
(int)i, (int)(loop_cnt),
(int)i < (int)(loop_cnt) ? "true" : "false",
pos);
usleep(100 * 1000);
}
}
fprintf(stderr, "bye\n");

return 0;
}
-

Under normal circumstances, like compile with -O0, it will print like:
###
capacity = 0x0400, pos = 0x7fffdfff
0 < 16384 is true, pos = 0x7fffe000
1024 < 16384 is true, pos = 0x7fffe400
2048 < 16384 is true, pos = 0x7fffe800
3072 < 16384 is true, pos = 0x7fffec00
4096 < 16384 is true, pos = 0x7000
5120 < 16384 is true, pos = 0x7400
6144 < 16384 is true, pos = 0x7800
7168 < 16384 is true, pos = 0x7c00
8192 < 16384 is true, pos = 0x8000
9216 < 16384 is true, pos = 0x8400
10240 < 16384 is true, pos = 0x8800
11264 < 16384 is true, pos = 0x8c00
12288 < 16384 is true, pos = 0x80001000
13312 < 16384 is true, pos = 0x80001400
14336 < 16384 is true, pos = 0x80001800
15360 < 16384 is true, pos = 0x80001c00
bye

But when compile with -O3, incorrect integer comparison result in loop, i <
loop_cnt always return true, and will print infinitely. 
I found when I use `#define pos_t unsigned int` replace `#define pos_t int`, Or
ensure pos always positive integer, the comparison result is correct. But why
the type of pos will effect integer comparison?

[Bug c/107785] Integer comparison result compile with -O3

2022-11-21 Thread mugglewei at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107785

--- Comment #3 from Muggle Wei  ---
(In reply to Andrew Pinski from comment #2)
> Unsigned integer types are defined to be wrapping types which is why it
> works with that.

Thanks for the reply, I had thought that integer overflow would only affect
itself. 
So because of integer overflow, it leads to undefined behavior, which affects
the conditional judgment in the subsequent code?

[Bug c/107785] Integer comparison result compile with -O3

2022-11-21 Thread mugglewei at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107785

--- Comment #4 from Muggle Wei  ---
(In reply to Andrew Pinski from comment #2)
> Unsigned integer types are defined to be wrapping types which is why it
> works with that.

Indeed! It was my fault, appreciate for your answer!

[Bug c/107785] Integer comparison result compile with -O3

2022-11-21 Thread mugglewei at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107785

Muggle Wei  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #5 from Muggle Wei  ---
It's my fault, sorry!