https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124037
Bug ID: 124037
Summary: Wrong alignment checking for VMAT_ELEMENTWISE memory
accesses
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: victorldn at gcc dot gnu.org
Target Milestone: ---
For the vectorization of non-contiguous memory accesses such as the
vectorization of loads from a particular struct member, specifically when
vectorizing with unknown bounds (thus using a pointer and not an array) it is
observed that inadequate alignment checking allows for the crossing of a page
boundary within a single vectorized loop iteration. This leads to potential
segmentation faults in the resulting binaries.
Example:
/* { dg-options "-O3" } */
/* { dg-require-effective-target mmap } */
/* { dg-require-effective-target vect_early_break } */
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#define MAX 65536
typedef struct {
uint64_t a;
uint64_t b;
uint32_t flag;
uint32_t pad;
} Data;
int __attribute__ ((noinline))
foo (Data *ptr) {
if (ptr == NULL)
return -1;
int cnt;
for (cnt = 0; cnt < MAX; cnt++) {
if (ptr->flag == 0)
break;
ptr++;
}
return cnt;
}
int main() {
long pgsz = sysconf (_SC_PAGESIZE);
if (pgsz == -1) {
fprintf (stderr, "sysconf failed\n");
return 0;
}
/* Allocate 2 consecutive pages. */
void *mem = mmap (NULL, pgsz * 2, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED) {
fprintf (stderr, "mmap failed\n");
return 0;
}
memset (mem, 1, pgsz);
uint8_t *ptr = (uint8_t*) mem + pgsz;
memset (ptr - 16, 0, 16);
mprotect (ptr, pgsz, PROT_NONE);
Data *data = (Data *) (ptr - 80);
__builtin_printf("%d\n", foo(data));
}