Bug 111154 - vect-cost-model=dynamic triggers false warning on array operation
Summary: vect-cost-model=dynamic triggers false warning on array operation
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 13.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wstringop-overflow
  Show dependency treegraph
 
Reported: 2023-08-25 11:19 UTC by Tomas Chang
Modified: 2024-03-01 12:33 UTC (History)
2 users (show)

See Also:
Host:
Target: aarch64
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-08-25 00:00:00


Attachments
Test case of vect-cost-model (983 bytes, application/x-xz)
2023-08-25 11:19 UTC, Tomas Chang
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tomas Chang 2023-08-25 11:19:21 UTC
Created attachment 55792 [details]
Test case of vect-cost-model

I have a program, which operates on an array, which size is defined by a macro.

When compiling this code, GCC always reports following warnings:
```
test.c:35:18: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   35 |         desta[i] = src[i];
      |         ~~~~~~~~~^~~~~~~~
test.c:7:16: note: at offset 8 into destination object 'desta' of size 8
    7 | static uint8_t desta[ARRAY_SIZE];
      |                ^~~~~
test.c:35:18: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   35 |         desta[i] = src[i];
      |         ~~~~~~~~~^~~~~~~~
test.c:7:16: note: at offset 9 into destination object 'desta' of size 8
    7 | static uint8_t desta[ARRAY_SIZE];
      |                ^~~~~
test.c:35:18: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   35 |         desta[i] = src[i];
      |         ~~~~~~~~~^~~~~~~~
```
After digging on this issue, I found that this warning is triggered by 
`-fvect-cost-model=dynamic`, in -O3
`-fvect-cost-model=very-cheap` won't trigger this warning.

Attached is the test case program, just run
`make bugs`
to produce this false warning

This source code file has 3 functions, each function has a for-loop to operate the array.
The upper bound of the for-loop is determined by a global static variable, which will be set by another function.

If I remove 1 function which operate on the array, this warning won't show up.
It seems that this issue is related to loop-vectorization, if there are enough loops, loop-vectorization will be triggered, and the array's bound is an variable, which cannot be determined directly by GCC, in this case, GCC vectorize the loop, accessed regions outside of the array.
Comment 1 Tomas Chang 2023-08-25 11:33:35 UTC
Forgot to mention, this bug can only be produced in 'AARCH64' platform.

Native compile the attached test case in "aarch64" machine,
or cross-compile the source code using aarch64 toolchain, can trigger it.
Comment 2 Richard Biener 2023-08-25 12:03:56 UTC
Confirmed.  Reproduces with -O3 -march=armv8.3-a and

unsigned char desta[8];
void copya(unsigned char *src, int size)
{
  for (int i = 0; i < size; i++)
    desta[i] = src[i];
}

we end up with a peeled epilogue:

  if (_12 == niters_vector_mult_vf.6_39)
    goto <bb 26>; [12.50%]
  else
    goto <bb 6>; [87.50%]

  <bb 6> [local count: 73583527]:
  _96 = MEM[(unsigned char *)src_8(D) + 8B];
  desta[_36] = _96;
  if (size_7(D) > 9)
    goto <bb 7>; [85.71%]
  else
    goto <bb 27>; [14.29%]

  <bb 27> [local count: 10511932]:
  goto <bb 21>; [100.00%]

  <bb 7> [local count: 63071596]:
  _103 = MEM[(unsigned char *)src_8(D) + 9B];
  desta[9] = _103;
  if (size_7(D) != 10)
    goto <bb 8>; [85.71%]
  else
    goto <bb 28>; [14.29%]

  <bb 28> [local count: 9010228]:
  goto <bb 21>; [100.00%]

  <bb 8> [local count: 54061368]:
  _110 = MEM[(unsigned char *)src_8(D) + 10B];
  desta[10] = _110;
  if (size_7(D) != 11)
    goto <bb 9>; [85.71%]
  else
    goto <bb 29>; [14.29%]
...
Comment 3 Tomas Chang 2023-08-28 04:28:48 UTC
(In reply to Richard Biener from comment #2)
> Confirmed.  Reproduces with -O3 -march=armv8.3-a and
> 
> unsigned char desta[8];
> void copya(unsigned char *src, int size)
> {
>   for (int i = 0; i < size; i++)
>     desta[i] = src[i];
> }
> 
> we end up with a peeled epilogue:
> 
>   if (_12 == niters_vector_mult_vf.6_39)
>     goto <bb 26>; [12.50%]
>   else
>     goto <bb 6>; [87.50%]
> 
>   <bb 6> [local count: 73583527]:
>   _96 = MEM[(unsigned char *)src_8(D) + 8B];
>   desta[_36] = _96;
>   if (size_7(D) > 9)
>     goto <bb 7>; [85.71%]
>   else
>     goto <bb 27>; [14.29%]
> 
>   <bb 27> [local count: 10511932]:
>   goto <bb 21>; [100.00%]
> 
>   <bb 7> [local count: 63071596]:
>   _103 = MEM[(unsigned char *)src_8(D) + 9B];
>   desta[9] = _103;
>   if (size_7(D) != 10)
>     goto <bb 8>; [85.71%]
>   else
>     goto <bb 28>; [14.29%]
> 
>   <bb 28> [local count: 9010228]:
>   goto <bb 21>; [100.00%]
> 
>   <bb 8> [local count: 54061368]:
>   _110 = MEM[(unsigned char *)src_8(D) + 10B];
>   desta[10] = _110;
>   if (size_7(D) != 11)
>     goto <bb 9>; [85.71%]
>   else
>     goto <bb 29>; [14.29%]
> ...

Thanks for confirming this bug so quickly!
Does this issue affect the actually generated code ?

Are there any clues about how to fix this issue ?
If there are patches that can fix, I can help test the patch.