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));
}

Reply via email to