A strange problem about type i64 for LLVM

Hello, everyone,

I encounter a strange problem about llvm type i64 and C++ type int64_t.

I instrumented a program to call the function ‘myFunction’ in the C++ shared library. ‘myFunction’ is something like this:

int64_t myFunction() {
int64_t retValue;

std::cout << "retValue: " << retValue << “\n”;
return retValue;
}

The call instruction in llvm bytecode is something like this:

%0 = call i64 myFunction();

However, I found retValue in ‘myFunction’ have a different value with %0. For exmple, when ‘retValue’ got ‘140583176769504’, ‘%0’ got ‘306205760’. I found ‘306205760’ is the result of truncate int64_t ‘140583176769504’ to int32_t. But how this happens, because %0 also has the type of i64. Or type i64 actually doesn’t correspond to int64_t? If so, how can I represent int64_t in llvm?

Thanks in advance.

If retValue isn't initialized then this program has undefined
behaviour as C++ so all bets are off (LLVM might be propagating an
"undef" and simply not returning a meaningful value).

Otherwise we need more detail. I'd expect this to work on all targets
(int64_t would in almost every case map to i64, and this straight
return should be fine, particularly if it comes from C++). So are you
using a custom target and does it have any quirks that might be
relevant? The key functions to look at would be LowerCall and
LowerReturn in XYZISelLowering.cpp.

Cheers.

Tim.

Hi Tim Northover,

I just use Mac OS X, Intel Core i5. ‘retValue’ is initialized, computed, and then returned from ‘myFunction’, so I think this problem is not introduced by uninitialized value. In addition, ‘306205760’ is not a meaningless value, but the result of truncating ‘140583176769504’ to 32 bits.

Actually, I instrumented some call instructions for value store and load, which can be simplified as follow:

  1. Storing values with function ‘myStore’:
    call void myStore(i64 %1);

  2. Loading values with function ‘myLoad’:
    %0 = call i64 myLoad();

The problem is that the call on ‘myStore’ can correctly pass ‘i64 %1’ to the function body of ‘myStore’. However, when I use ‘myLoad’ to return the stored value to ‘%0’, the 64bits value is truncated to a 32bits value. For example, ‘140583176769504’ is returned in ‘myLoad’, but actually ‘306205760’ is assigned to %0.

I think this requires “complete code” (ideally the smallest possible that still reproduces the problem), not snippets. It is quite likely that the problem is somewhere other than in the precise lines quoted.

Using 64-bit values in x86 is far from rare, but it’s of course possible that:

  1. you have found a rare bug because your code is doing something unusual.

  2. there is a bug somewhere in your own code, that you haven’t spotted.

The bits of code you have posted don’t look wrong, but they also aren’t showing enough code to determine “yes that should work” or “no, that is wrong because …”

Thanks for your help and advice. I have found the problem, which is resulted from my own code.