Anastasia added a comment. > Permitting non-standards-driven "do the best you can" constant-folding > of array bounds is permitted solely as a GNU compatibility feature. We > should not be doing it in any language mode that is attempting to be > conforming. > > From https://reviews.llvm.org/D20090 it appears the intent here was to > permit __constant int globals to be used in array bounds, but the > change in that patch only added half of the functionality necessary to > support that in the constant evaluator. This patch adds the other half > of the functionality and turns off constant folding for array bounds in > OpenCL. > > I couldn't find any spec justification for accepting the kinds of cases > that D20090 <https://reviews.llvm.org/D20090> accepts, so a reference to > where in the OpenCL specification > this is permitted would be useful.
Thanks for fixing this. I agree that the original change was not compliant with the spec. OpenCL indeed doesn't allow constant folding for array bounds. The idea of the change was to allow using expressions that are compile time constant in the array bound because this doesn't result in VLA. Regarding the spec reference, I think we can refer to the section 6.5.3 describing variables in the `__constant` address space: These variables are required to be initialized and the values used to initialize these variables must be a compile time constant. Writing to such a variable results in a compile-time error. I.e. the `__constant` address space variables are semantically similar to `constexpr` in C++. > Note that this change also affects the code generation in one test: > because after 'const int n = 0' we now treat 'n' as a constant > expression with value 0, it's now a null pointer, so '(local int *)n' > forms a null pointer rather than a zero pointer. I am slightly confused about this case because technically the value of 'n' can be overwritten by casting away const. However, I suspect this is compliant C99 behavior? This example: void test(void) { const int x = 0; const int* ptrx = &x; int* ptry = (int*)ptrx; *ptry = 100; int *sp5 = ( int*)x; } shows that the IR produced is indeed supposed to have NULL despite of the fact that the value of initializing variable is not 0 at the time of the last initialization. store i32* null, i32** %4, align 8 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D89520/new/ https://reviews.llvm.org/D89520 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits