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
  • [PATCH] D89520: D... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D895... Anastasia Stulova via Phabricator via cfe-commits
    • [PATCH] D895... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D895... Yaxun Liu via Phabricator via cfe-commits
    • [PATCH] D895... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D895... Anastasia Stulova via Phabricator via cfe-commits
    • [PATCH] D895... Anastasia Stulova via Phabricator via cfe-commits
    • [PATCH] D895... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D895... Richard Smith - zygoloid via Phabricator via cfe-commits

Reply via email to