[PATCH] D89520: Don't permit array bound constant folding in OpenCL.

Anastasia Stulova via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 16 04:58:53 PDT 2020


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



More information about the cfe-commits mailing list