ptrtoint

What kind of C or C++ code will emit a "ptrtoint" op?

Also, what causes i1 to be emitted?

Tia.

Reed

What kind of C or C++ code will emit a "ptrtoint" op?

This C code:

    long ptrtoint(void *p) { return (long)p; }

gives:

    define i64 @ptrtoint(i8* %p) {
      %1 = ptrtoint i8* %p to i64
      ret i64 %1
    }

Also, what causes i1 to be emitted?

This C++ code:

    bool i1() { return false; }

gives:

    define zeroext i1 @_Z2i1v() {
      ret i1 false
    }

Thanks.

So what about a fragment like this: (taken from fast-isel.ll in X86 )

define void @ptrtoint_i1(i8* %p, i1* %q) nounwind {
   %t = ptrtoint i8* %p to i1
   store i1 %t, i1* %q
   ret void
}

TIA.

Thanks.

So what about a fragment like this: (taken from fast-isel.ll in X86 )

define void @ptrtoint_i1(i8* %p, i1* %q) nounwind {
%t = ptrtoint i8* %p to i1
store i1 %t, i1* %q
ret void
}

Intuitively, this looks like:

    void ptrtoint_i1(char *p, bool *q) { *q = (bool)p; }

However, `q` needs to be addressable in C/C++, so it's left as an `i8`.

`git log` suggests this particular testcase evolved incrementally out
of hand-written IR.

Why do you need C/C++ code for it? Just interested?

Technically I don't need C/C++ code for it.

I'm not really very good at writing LLVM assembly code by hand
(but I should be - lol ).

I'm working on fast-isel and I want to have executable tests for all of this
and not just make check tests.

It's easier for me to do that in C/C++ and then save the .ll and morph it into
a make check test.

I'm going through the fast-isel tests for x86 now and adapting them for Mips.
(will do the same for AArch64 and other ports).

I want an executable variant for all of them.

If I wanted to call this function that they generated by hand, from C or C+ code, how would that be done?

if have seen cases where a real boolean gets generated but it was
something fairly involved.

is a boolean and a char supposed to occupy the same amount of storage?

is this prototype going to work in general:

void ptrtoint_i1(char *p, bool *q)

TIA.

Reed

If you can't make an executable test from C or C++ code then how do you
know something works.

Just by examination of the .s?

Hi Reed,

I think you can try this:

  1. write C/C++ code that use ptrtoint_i1 (declare ptrtoint_i1 as an external function)
  2. compile it using clang to LLVM IR,
  3. link the compiled IR with the IR for ptrtoint_i1 to executable using llvm-ld or the clang driver.

However, one complication in your case is I doubt there’s a mapping from any C/C++ type to i1 (bool is translated to i8). If that’s the case, you may need to put a wrapper around ptrtoint_i1, e.g.,
define void @ptrtoint_i8(i8* a, i8* b) {
%slot = alloca i1
call void @ptrtoint_i1(i8* a, i1* %slot)
%value = load i1* %slot
%ext_value = zext i1 %value to i8
store i8 %ext_value, i8* b
}
// not tested :slight_smile: be careful when you copy and paste
Then, you can use ptrtoint_i8(char *, char *) in your C/C++ code, and when linked ptrtoint_i1 will show up too.

Jingyue

I understand what you are suggesting and thought of this myself but it really
does not help unless we say that

size(i1) == size(i8)

which is certainly logical

i have seen i1 get generated with C/c++ code but am not sure
how to construct this case myself.

so some of the test cases, like fast-isel.ll for X86 are probably
only eyeballed to see of ptrtoint and inttoptr work