1

I'm trying LLVM and hitting some walls, like this one. When I compile and run the piece of code below, instead of getting the current year, I'm getting the day of the week:

target datalayout = "e"

declare dllimport x86_stdcallcc void @GetLocalTime(%SYSTEMTIME*)

%SYSTEMTIME = type {
    i16, ; wYear
    i16, ; wMonth
    i16, ; wDayOfWeek
    i16, ; wDay
    i16, ; wHour
    i16, ; wMinute
    i16, ; wSecond
    i16  ; wMilliseconds
}

define i32 @main() {
    %now = alloca %SYSTEMTIME
    call void @GetLocalTime(%SYSTEMTIME* %now)
    %ptr = getelementptr %SYSTEMTIME* %now, %i32 0, %i32 0
    %day = load i16* %ptr
    %int = zext i16 %day to i32
    ret i32 %int
}

Please note that I'm not writing C or C++ code, I'm writing the code above as it is. Can someone point me out what I'm doing wrong? All members of SYSTEMTIME seems to be off by 2 positions...

1
  • 1
    Check your alignments Commented Jan 12, 2014 at 13:04

2 Answers 2

1

You declare:

declare dllimport x86_stdcallcc void @GetLocalTime(%SYSTEMTIME*)

Which is absolutely correct; but when you call it:

call void @GetLocalTime(%SYSTEMTIME* %now)

You forgot the x86_stdcallcc calling convention. From the documentation of call:

The calling convention of the call must match the calling convention of the target function, or else the behavior is undefined.

So perhaps adding the cc would fix this issue.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, Oak. You nailed it! I really missed it in the documentation. Now it is working perfectly when I call like this: codecall x86_stdcallcc void @GetLocalTime(%SYSTEMTIME* %now)
@user1577561 great, happy to hear. I'm going to leave my other answer up, though, might be of use to someone else in the future.
1

You write:

All members of SYSTEMTIME seems to be off by 2 positions...

This might be caused by bad alignment. In particular, you allocate the structure on the stack, and LLVM default data layout does not specify the stack alignment, while Windows 32-bit requires 4 bytes. To satisfy this requirement, add S32 to your data layout string (or S128, I guess, for 64-bit Windows).

To verify this I checked what data layout string Clang inserts on my Windows system, and indeed you can see S32 there, right at the end:

"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"

2 Comments

I changed my target datalayout for "e-S32", "e-S128", "e-64", copied the whole string from Oak, but nothing changed. I'm compiling a 32 .EXE that runs in my 64 bit machine. What puzzles me is that the GetLocalTime seems to fill properly the structure, but the first two fields are not reachable through getelementptr... Where else could I try to change? I'm pretty new with LLVM.
@user1577561 your usage of the getelementptr instruction seems fine to me. Other than alignment, the only thing I can think of that can have the symptom you are describing is faulty calling convention; I've added another answer about it, give it a try.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.