3

I'm wondering if it's possible to hint to gcc that a pointer points to an aligned boundary. if I have a function:

void foo ( void * pBuf ) {
    uint64_t *pAligned = pBuf;
    pAligned = ((pBuf + 7) & ~0x7);
    var = *pAligned;   // I want this to be aligned 64 bit access
}

And I know that pBuf is 64 bit aligned, is there any way to tell gcc that pAligned points to a 64 bit boundary? If I do:

uint64_t *pAligned __attribute__((aligned(16)));   

I believe that means that the address of the pointer is 64 bit aligned, but it doesn't tell the compiler that the what it points to is aligned, and therefore the compiler would likely tell it to do an unaligned fetch here. This could slow things down if I'm looping through a large array.

1 Answer 1

4

There are several ways to inform GCC about alignment.

Firstly you can attach align attribute to pointee, rather than pointer:

int foo() {
  int __attribute__((aligned(16))) *p;
  return (unsigned long long)p & 3;
}

Or you can use (relatively new) builtin:

int bar(int *p) {
  int *pa = __builtin_assume_aligned(p, 16);
  return (unsigned long long)pa & 3;
}

Both variants optimize to return 0 due to alignment.

Unfortunately the following does not seem to work:

typedef int __attribute__((aligned(16))) *aligned_ptr;

int baz(aligned_ptr p) {
  return (unsigned long long)p & 3;
}

and this one does not either

typedef int aligned_int __attribute__((aligned (16)));

int braz(aligned_int *p) {
  return (unsigned long long)p & 3;
}

even though docs suggest the opposite.

Sign up to request clarification or add additional context in comments.

4 Comments

Now that you mention it, the first example sounds soo obvious... Not sure how I missed that. Thanks. I am surprised that the typedef doesn't work though. It might have been handy in some other parts of my code.
@John Right, GCC even claims to support it in docs but I couldn't get it to work with my GCC 5.4.
I suppose in the last two cases, you're attempting to align a parameter, and the parameter is not known at compile time, thus gcc would have no way to force the parameter to be aligned. It might be able to generate a warning if you tried to pass in a parameter that wasn't guarenteed to be aligned, but outside of that, if someone pushed 0xabcd0001 onto the stack, then the pointer would indeed be odd. The code inside, however, likely makes the assumption of alignment, and memory access would likely cause an unaligned exception...
@John Well, it's the same situation as in ex. 2 (__builtin_assume_aligned) - compiler can not guarantee anything but trusts the user, in the name of performance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.