Clarification between <type> and <ty> for alloca instruction

Hi,

This is quite a simple question so hopefully it's easy to answer.

I was looking at the documentation for the alloca instruction (
http://llvm.org/docs/LangRef.html#alloca-instruction ) and something is
unclear to me. The given syntax is...

<result> = alloca <type>[, <ty> <NumElements>][, align <alignment>]
; yields {type*}:result

And the documentation states "The ‘alloca‘ instruction allocates
sizeof(<type>)*NumElements bytes of memory on the runtime stack".

It is not stated how the "<ty>" type is used as we are told the type of
result is type* and sizeof(<type>)*NumElements is the amount of memory
so from my perspective it looks like <ty> is never used which would seem
to make stating i32 twice in the following example redundant

%ptr = alloca i32, i32 4

My guess is that if <NumElements> is specified then the amount of memory
actually allocated would be sizeof(<ty>)*NumElements (instead of
sizeof(<type>)*NumElements) but the pointer type of result is <type>. Is
that correct?

If not could someone please clarify this?

Thanks,
Dan Liew.

Hi Dan,

It is not stated how the "<ty>" type is used as we are told the type of
result is type* and sizeof(<type>)*NumElements is the amount of memory
so from my perspective it looks like <ty> is never used which would seem
to make stating i32 twice in the following example redundant

%ptr = alloca i32, i32 4

My guess is that if <NumElements> is specified then the amount of memory
actually allocated would be sizeof(<ty>)*NumElements (instead of
sizeof(<type>)*NumElements) but the pointer type of result is <type>. Is
that correct?

It doesn't really affect the output at all. If NumElements doesn't
overflow <ty> then the semantics don't depend on it at all.

In C-like code it's sort of the difference between these two functions:

    void ty_is_i16(unsigned short NumElements) {
        int arr[NumElements];
        use_array(arr);
    }

    void ty_is_i32(unsigned int NumElements) {
        int arr[NumElements];
        use_array(arr);
    }

you might compile them to

    define void @ty_is_i16(i16 %NumElements) {
        %arr = alloca i32, i16 %NumElements
        call void @use_array(i32* %arr)
        ret void
    }

    define void @ty_is_i32(i32 %NumElements) {
        %arr = alloca i32, i32 %NumElements
        call void @use_array(i32* %arr)
        ret void
    }

Of course, if NumElements *does* overflow they're different:
    alloca i32, i8 257
will allocate 1 i32, but
    alloca i32, i32 257
will allocate 257 of them.

It's mostly there because when NumElements is a run-time value (as in
the C examples) it has to have *some* type in LLVM IR.

Cheers.

Tim.

Thanks for the reply.

Please see my inline responses.

Hi Dan,

It is not stated how the "<ty>" type is used as we are told the
type of result is type* and sizeof(<type>)*NumElements is the
amount of memory so from my perspective it looks like <ty> is
never used which would seem to make stating i32 twice in the
following example redundant

%ptr = alloca i32, i32 4

My guess is that if <NumElements> is specified then the amount of
memory actually allocated would be sizeof(<ty>)*NumElements
(instead of sizeof(<type>)*NumElements) but the pointer type of
result is <type>. Is that correct?

Ah so my guess is completely wrong. <ty> refers to the type of
NumElements.

It doesn't really affect the output at all. If NumElements doesn't
overflow <ty> then the semantics don't depend on it at all.

In C-like code it's sort of the difference between these two
functions:

void ty_is_i16(unsigned short NumElements) { int arr[NumElements];
use_array(arr); }

void ty_is_i32(unsigned int NumElements) { int arr[NumElements];
use_array(arr); }

you might compile them to

define void @ty_is_i16(i16 %NumElements) { %arr = alloca i32, i16
%NumElements call void @use_array(i32* %arr) ret void }

define void @ty_is_i32(i32 %NumElements) { %arr = alloca i32, i32
%NumElements call void @use_array(i32* %arr) ret void }

Huh... I've obviously being playing with C++ too long because my
instinct immediately told me that dynamically sized arrays on the
stack are't allowed but apparently that's fine for C99 (g++ also seems
fine with this is you don't specify -pedantic)

Of course, if NumElements *does* overflow they're different: alloca
i32, i8 257 will allocate 1 i32, but alloca i32, i32 257 will
allocate 257 of them.

Interesting thanks for clarifying. Now you've raised another question.
I'm interested to know how you know that this is how overflow behaves
for this particular instruction. I can imagine several different
behaviours (I'm assuming NumElements is unsigned but that doesn't seem
to be specified)

- wrap around overflow. In which case 257 = 255 + 2 so result would be 2
- Saturation overflow. In which case the result is 255
- Your stated result of 1. I'm not sure why this would happen.

Thanks,
Dan.

I've obviously being playing with C++ too long because my
instinct immediately told me that dynamically sized arrays on the
stack are't allowed but apparently that's fine for C99 (g++ also seems
fine with this is you don't specify -pedantic)

It's all fun and games until someone decides to evaluate sizeof(arr). :wink:

I think a more limited form is coming to C++11, by the way.

Interesting thanks for clarifying. Now you've raised another question.
I'm interested to know how you know that this is how overflow behaves
for this particular instruction. I can imagine several different
behaviours (I'm assuming NumElements is unsigned but that doesn't seem
to be specified)

- wrap around overflow. In which case 257 = 255 + 2 so result would be 2

This is what happens (wraparound/truncation/whatever). But I think 256
-> 0, 257 -> 1.

Cheers.

Tim.

Oops yes you're completely right. I didn't think about that through
very well ( I was doing % 255 in my head instead of % 256).

Do you think it would be wise to document the meaning of <ty> for the
alloca instruction or do you think that it is clear enough and that it
is my unfamiliarity with LLVM IR that caused my confusion?

Thanks,
Dan.

Do you think it would be wise to document the meaning of <ty> for the
alloca instruction or do you think that it is clear enough and that it
is my unfamiliarity with LLVM IR that caused my confusion?

Personally I'd say it's clear enough, but others may disagree.

Cheers.

Tim.

Hi Tim,
I believe standard support for dynamically sized arrays is in the C++14 draft. But
sizeof(arr) still will be a compile time computation, so it won't be supported
in C++14 either.

enjoy,
Karen