Understanding bitcast in LLVM IR
Asked Answered
H

2

6

I am trying to understand the LLVM IR generated from a C++ program

int add(int *x);
int func()
{
        int T;
        T=25;
        return add(&T);    
}

The generated IR is:

define i32 @_Z4funcv() local_unnamed_addr #0 {
entry:
  %T = alloca i32, align 4
  %0 = bitcast i32* %T to i8*
  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #3
  store i32 25, i32* %T, align 4, !tbaa !2
  %call = call i32 @_Z3addPi(i32* nonnull %T)
  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #3
  ret i32 %call
}

I do not understand this line %0 = bitcast i32* %T to i8*. What is the purpose of converting %T from i32 to i8?

Hamm answered 28/8, 2018 at 19:8 Comment(1)
This is done because the value of the pointer (i.e. the memory address) is passed to the @llvm.lifetime.start intrinsic that signifies that till that point in the function (i.e. before the following store) the pointer is dead. You can have a look at the doc and in the LLVM source code for example uses.Hamish
L
4

Assuming you know about intrinsics

llvm.lifetime.start / llvm.lifetime.end

and its uses as memory uses marker for MemoryDependenceAnalysis.

About the choice of pointer(address of variable) as i8 was made to make it more generic as byte addressable memory region with first arguments as number of bytes same as we use in malloc.

so to generate the intrinsic call we need a memory byte address and the number of bytes that is sizeof(T). that is why we need to convert i32* to i8*.

by the way the signature if lifetime intrinsics used in your examples are

declare void @llvm.lifetime.start(i64 , i8* nocapture )

declare void @llvm.lifetime.end(i64 , i8* nocapture )

go through Lang ref for more info.

Laveta answered 28/8, 2018 at 22:31 Comment(1)
Note that LLVM has recently changed to remove the need for this from its type system by instead using a generic pointer type.Magnetron
O
1

LLVM is typed and monomorphical. Thus, you need to cast values to the right type before you can use them. As the other answer explained, the llvm intrinsics operate on i8* which is kind of the translation of a void* in C.

Off answered 27/1, 2023 at 16:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.