[llvm-dev] Instcombine and llvm.ptr.annotation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] Instcombine and llvm.ptr.annotation

David Jones via llvm-dev

Hi,

 

I’m trying to figure out if this behavior by Instcombine is ok, and I’d appreciate some feedback.

 

Suppose you have this kind of struct:

 

    %struct.State = type {  i32, i32,  i32, i32, %"struct.State::InnerState" }

    %"struct.State::InnerState" = type { i32, i32 }

 

Now suppose we have %S which is of type struct.State and we want to use two llvm.ptr.annotations:

1- one to annotate the last member of struct.State (which is of type struct.State::InnerState)

2- one to annotate the first member of %"struct.State::InnerState"

 

This is the IR out of clang:

 

define i32 @foo(%struct.State* %S)  {

  %my_inner_state = getelementptr inbounds %struct.State, %struct.State* %S, i32 0, i32 4

  %0 = bitcast %"struct.State::InnerState"* %my_inner_state to i8*

  %1 = call i8* @llvm.ptr.annotation.p0i8(i8* %0, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i32 20)

  %2 = bitcast i8* %1 to %"struct.State::InnerState"*

  %inner_member = getelementptr inbounds %"struct.State::InnerState", %"struct.State::InnerState"* %2, i32 0, i32 0

  %3 = bitcast i32* %inner_member to i8*

  %4 = call i8* @llvm.ptr.annotation.p0i8(i8* %3, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i32 15)

}

 

Instcombine is replacing the GEP with all 0 indices + bitcast with the base pointer of the GEP:

 

  %my_inner_state = getelementptr inbounds %struct.State, %struct.State* %S, i64 0, i32 4

  %0 = bitcast %"struct.State::InnerState"* %my_inner_state to i8*

  %1 = call i8* @llvm.ptr.annotation.p0i8(i8* %0, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0), i32 20)

  %2 = call i8* @llvm.ptr.annotation.p0i8(i8* %1, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.5, i64 0, i64 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0), i32 15)

 

Now we cannot distinguish between what is actually being annotated. In other words, it looks like the whole %"struct.State::InnerState” is being annotated twice.

Is this ok?

 

Thanks!

 

--

Felipe de Azevedo Piovezan

 


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Instcombine and llvm.ptr.annotation

David Jones via llvm-dev

Hi Felipe,

 

My understanding is that the type of pointer types in LLVM IR have no semantic meaning. That is, the pointer is just an address and the fact that the type system currently describes the type of the data that it points to is more or less just a convenience. In fact, there’s an effort underway to make all pointers opaquely typed.

 

So the transformation you’re describing is correct. In spite of all the hoops the original IR is jumping through, a pointer to InnerState and a pointer to the first member of InnerState are in fact pointing to the same place. If you need to know more than that, I think it needs to be captured in the annotation itself.

 

-Andy

 

From: llvm-dev [mailto:[hidden email]] On Behalf Of De Azevedo Piovezan, Felipe via llvm-dev
Sent: Wednesday, November 07, 2018 10:13 AM
To: [hidden email]
Subject: [llvm-dev] Instcombine and llvm.ptr.annotation

 

Hi,

 

I’m trying to figure out if this behavior by Instcombine is ok, and I’d appreciate some feedback.

 

Suppose you have this kind of struct:

 

    %struct.State = type {  i32, i32,  i32, i32, %"struct.State::InnerState" }

    %"struct.State::InnerState" = type { i32, i32 }

 

Now suppose we have %S which is of type struct.State and we want to use two llvm.ptr.annotations:

1- one to annotate the last member of struct.State (which is of type struct.State::InnerState)

2- one to annotate the first member of %"struct.State::InnerState"

 

This is the IR out of clang:

 

define i32 @foo(%struct.State* %S)  {

  %my_inner_state = getelementptr inbounds %struct.State, %struct.State* %S, i32 0, i32 4

  %0 = bitcast %"struct.State::InnerState"* %my_inner_state to i8*

  %1 = call i8* @llvm.ptr.annotation.p0i8(i8* %0, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i32 20)

  %2 = bitcast i8* %1 to %"struct.State::InnerState"*

  %inner_member = getelementptr inbounds %"struct.State::InnerState", %"struct.State::InnerState"* %2, i32 0, i32 0

  %3 = bitcast i32* %inner_member to i8*

  %4 = call i8* @llvm.ptr.annotation.p0i8(i8* %3, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i32 15)

}

 

Instcombine is replacing the GEP with all 0 indices + bitcast with the base pointer of the GEP:

 

  %my_inner_state = getelementptr inbounds %struct.State, %struct.State* %S, i64 0, i32 4

  %0 = bitcast %"struct.State::InnerState"* %my_inner_state to i8*

  %1 = call i8* @llvm.ptr.annotation.p0i8(i8* %0, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0), i32 20)

  %2 = call i8* @llvm.ptr.annotation.p0i8(i8* %1, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.5, i64 0, i64 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0), i32 15)

 

Now we cannot distinguish between what is actually being annotated. In other words, it looks like the whole %"struct.State::InnerState” is being annotated twice.

Is this ok?

 

Thanks!

 

--

Felipe de Azevedo Piovezan

 


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev