[llvm-dev] How to calculate the offset obtained via a GEP instruction

Alberto Barbaro via llvm-dev llvm-dev at lists.llvm.org
Tue Jan 25 12:03:02 PST 2022


Hi Nikita,
so I think I made some progress but I'm not quite there yet.

So the GEP Instruction that I'm interested to analyze are:

%3 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 0
%4 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 1
%5 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 2

and the Point struct is declared in the following way:

struct Point
{
   int x;
   char y;
   long z;
};

Reading some doc online I tried the following:

Module *M = I.getModule();
I.dump();
APInt ap_offset(32, 0, false);
std::cout << "ap_offset: " << ap_offset.getSExtValue() << "\n";
std::cout << "Accumulated offset: " <<
I.accumulateConstantOffset(M->getDataLayout(), ap_offset) << "\n";
std::cout << "ap_offset: " << ap_offset.getSExtValue() << "\n";

The output is something like:
  %3 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 0
ap_offset: 0
Accumulated offset: 1
ap_offset: 0
  %4 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 1
ap_offset: 0
Accumulated offset: 1
ap_offset: 4
  %5 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 2
ap_offset: 0
Accumulated offset: 1
ap_offset: 8
  %3 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 0
ap_offset: 0
Accumulated offset: 1
ap_offset: 0
  %4 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 1
ap_offset: 0
Accumulated offset: 1
ap_offset: 4
  %5 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 2
ap_offset: 0
Accumulated offset: 1
ap_offset: 8
  %3 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 0
ap_offset: 0
Accumulated offset: 1
ap_offset: 0
  %4 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 1
ap_offset: 0
Accumulated offset: 1
ap_offset: 4
  %5 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 2
ap_offset: 0
Accumulated offset: 1
ap_offset: 8

I think the output is almost correct because the offset is increased by 4
each time... but the struct has char and long elements so the offset does
not always look right. I think it due to the fact that the GEP is referring
only to i32.

How should I fix this situation?  Few lines of code would be very helpful

Thanks
Alberto


Il giorno mar 25 gen 2022 alle ore 08:25 Nikita Popov <nikita.ppv at gmail.com>
ha scritto:

> On Tue, Jan 25, 2022 at 8:00 AM Alberto Barbaro via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>> Hi all,
>> so I'm trying to understand how to manually calculate the offset
>> calculated by a GEP instruction. I found that this question was asked over
>> 6 years ago on stackoverflow[1] as well but never got a real answer.
>>
>> Since I need exactly the same, is there anyone willing to help me to
>> understand how to calculate the offset?
>>
>
> You can use GEPOperator::accumulateConstantOffset(). Or more generically,
> there is Value::stripAndAccumulateConstantOffsets(), which can look through
> multiple GEPs, bitcasts, etc.
>
> Regards,
> Nikita
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20220125/003ce25a/attachment.html>


More information about the llvm-dev mailing list