[llvm-dev] [OpenCL] Implicit arithmetic conversion of INT_MIN to int vector type

Bruce Hoult via llvm-dev llvm-dev at lists.llvm.org
Thu Sep 10 04:07:37 PDT 2015


It depends on whether the '-' is part of the syntax of a number, or is an
operator applied afterwards. I believe C says it is an operator and thus it
examines '2147483648', decides it won't fit into 32 bits and chooses a 64
bit type, and only afterwards applies the negation.

Testing with clang 3.4.1 on Ubuntu x86_64:

cat >intmin.cpp <<END
#include <iostream>

int main(){
  auto i = -2147483647;
  auto j = -2147483648;
  std::cout << "sizeof " << i << " = " << sizeof(i) << std::endl;
  std::cout << "sizeof " << j << " = " << sizeof(j) << std::endl;
  return 0;
}
END
clang++ -std=c++11 -o intmin intmin.cpp && ./intmin

sizeof -2147483647 = 4
sizeof -2147483648 = 8

g++ 4.8.4 gives the same result.

You would not notice this with an explicit type instead of 'auto'.

Note that there should be CL_INT_MIN available (cl_platform.h) rather than
defining your own.

On Thu, Sep 10, 2015 at 1:30 PM, Pflanzer, Moritz via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Hello,
>
> I recently came across an OpenCL kernel in which an int vector type was
> subtracted from the INT_MIN constant, e.g.
>
> int2 v2 = INT_MIN - (int2)(0);
>
> INT_MIN was defined as
>
> #define INT_MIN (-2147483648)
>
> Clang in OpenCL modes (-x cl) produces the following error:
>
> vector_conversion.c:12:42: error: can't convert between vector values of
> different size ('long' and 'int2' (vector of 2 'int' values))
>     int2 v_int               = INT_MIN   - (int2)(0); // Only error long
> to int2 conversion is not possible
>                                ~~~~~~~   ^ ~~~~~~~~
> 1 error generated.
>
> According to the OpenCL C standard (§6.2.6 and §6.3) I expected that the
> scalar INT_MIN would be expanded to the vector type and that the operation
> should be possible. The problem seems to be that INT_MIN is internally
> represented as long, though it is still a valid signed integer value, and
> thus long cannot be casted to int and subsequently not to int2.
>
> If on the other hand INT_MIN is defined as
>
> #define INT_MIN (-2147483647 - 1)
>
> it is represented as int, although it is the same number, and clang does
> not produce an error.
>
> More surprisingly, the expression
>
> int2 t                   = (int2)(INT_MIN);
>
> works for both versions of INT_MIN. So in this situation long seems to be
> implicitly casted to int which should not be possible.
>
> Finally, for clang in C mode (-x c) also both version work and no error is
> produced. I attached a test case in which a summarised all my findings. The
> behaviour I observed should be reproducible with
>
> $ clang -x cl -S -emit-llvm -O0 -o - vector_conversion.c
> $ clang -x c -S -emit-llvm -O0 -o - vector_conversion.c
>
> I would be interested in your thoughts about this behaviour, whether it is
> correct that -2147483648 is represented as long or whether the behaviour
> can be considered as bug in the OpenCL frontend of Clang. (Another
> possibility would be that the representation as long is correct but it is
> nevertheless a bug that the subtraction is not possible.)
>
> Regards,
>
> Moritz
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150910/91872909/attachment.html>


More information about the llvm-dev mailing list