Nema, Ashutosh via llvm-dev
2019-Jun-11 05:32 UTC
[llvm-dev] Aliasing rules for const type pointer
Hi, I'm not clear with the aliasing rules for the pointer pointing to const memory. It will be great help if someone clarify my doubts. Consider below test program: int foo(int *A, int *B, const int *C, int len) { for (int i = 0; i < len; i++) A[i] = B[i] + *C; } In this test case the type for "C" is const int * type, it means the pointer is pointing to a memory which is of type constant. My understanding is value at *C can't be modified in the program, so its invariant and possibly can be hoisted. There is a possibility that address pointed by C can alias with the address range pointed by A. But in this case since user has mentioned value pointed by C as constant so I feel aliasing should not be an issue. Please correct if something wrong with this understanding. Regards, Ashutosh -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190611/c3260670/attachment.html>
Tim Northover via llvm-dev
2019-Jun-11 08:26 UTC
[llvm-dev] Aliasing rules for const type pointer
Hi Ashutosh, On Tue, 11 Jun 2019 at 06:32, Nema, Ashutosh via llvm-dev <llvm-dev at lists.llvm.org> wrote:> In this test case the type for “C” is const int * type, it means the pointer is pointing to a memory which is of type constant. > > My understanding is value at *C can’t be modified in the program, so its invariant and possibly can be hoisted.This isn't quite right. In C and C++, const applies to a specific pointer, and only rarely to the underlying memory[*]. A given object is often accessed through both const and non-const pointers througout its lifetime. What const really means on a function like your foo is that the writer of foo has promised not to modify C through that pointer (and even that might only be an approximation since you can cast the const away). It's still possible for the caller to pass the same object in through A or B (as you say later), and depending on foo's contract that may be perfectly legitimate or an API violation. The compiler doesn't know which, so it can't assume they don't alias. Think about memmove for a concrete example which is very close to your foo: the source is a const pointer, but it's explicitly allowed to overlap with the dest. Cheers. Tim. [*] The memory itself is usually const for literal strings, and sometimes global variables declared const. Situations where the compiler knows that an object is immutable where it's actually allocated.
Nema, Ashutosh via llvm-dev
2019-Jun-11 15:10 UTC
[llvm-dev] Aliasing rules for const type pointer
Thanks Tim, I understood the point. Regards, Ashutosh -----Original Message----- From: Tim Northover <t.p.northover at gmail.com> Sent: Tuesday, June 11, 2019 1:57 PM To: Nema, Ashutosh <Ashutosh.Nema at amd.com> Cc: llvm-dev <llvm-dev at lists.llvm.org> Subject: Re: [llvm-dev] Aliasing rules for const type pointer [CAUTION: External Email] Hi Ashutosh, On Tue, 11 Jun 2019 at 06:32, Nema, Ashutosh via llvm-dev <llvm-dev at lists.llvm.org> wrote:> In this test case the type for “C” is const int * type, it means the pointer is pointing to a memory which is of type constant. > > My understanding is value at *C can’t be modified in the program, so its invariant and possibly can be hoisted.This isn't quite right. In C and C++, const applies to a specific pointer, and only rarely to the underlying memory[*]. A given object is often accessed through both const and non-const pointers througout its lifetime. What const really means on a function like your foo is that the writer of foo has promised not to modify C through that pointer (and even that might only be an approximation since you can cast the const away). It's still possible for the caller to pass the same object in through A or B (as you say later), and depending on foo's contract that may be perfectly legitimate or an API violation. The compiler doesn't know which, so it can't assume they don't alias. Think about memmove for a concrete example which is very close to your foo: the source is a const pointer, but it's explicitly allowed to overlap with the dest. Cheers. Tim. [*] The memory itself is usually const for literal strings, and sometimes global variables declared const. Situations where the compiler knows that an object is immutable where it's actually allocated.