I am trying to add support for new intrinsics in Julia. For this I use the llvmcall fork. However, when using this in a Julia function, I always encounter the following problem:
declare function:
julia> function ptx_test(a,b,c)
idx = Base.llvmcall("""%1 = tail call i32 #llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind
ret i32 %1""", Int32, ())
c[idx] = a[idx] + b[idx]
return nothing
end
ptx_test (generic function with 1 method)
retrieve llvm IR of this function:
julia> code_llvm(ptx_test, (Array{Int32,1},Array{Int32,1},Array{Int32,1}))
PTX function found: ptx_test
ERROR: error compiling ptx_test: Failed to parse LLVM Assembly:
julia: <string>:3:20: error: use of undefined value '#llvm.nvvm.read.ptx.sreg.tid.x'
%1 = tail call i32 #llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind
^
in _dump_function at reflection.jl:132
in code_llvm at reflection.jl:139
However, if I execute the same code_llvm command again directly after this, It works (correct IR is returned). How can I avoid this error when compiling for the first time?
Related
I'm using LLVM 3.9.1 Core libraries in implementation of a compiler front-end that targets Windows x64. I'm currently implementing exception handling.
For Windows x64 target LLVM generates so called funclets for catch and clean-up code. To catch an exception you generate a catchswitch instruction and then a catchpad instruction for each exception type caught:
...
catchsection0: ; preds = %entry
%8 = catchswitch within none [label %catch0] unwind to caller
catch0: ; preds = %catchsection0
%9 = catchpad within %8 [i8** #exceptionClassDescriptor", i32 8, i8** %1]
%10 = load i8*, i8** %1
br label %target10
target10: ; preds = %catch0
%11 = load i8*, i8** #__CD0
%12 = call i1 #RtHandleException(i8* %10, i8* %11) [ "funclet"(token %9) ]
br i1 %12, label %thisHandlerTarget10, label %nextHandlerTarget10
...
In order to call a function in a catch-block you need to set a funclet operand bundle for the call instruction passing the token returned by the catchpad instruction as argument:
%12 = call i1 #RtHandleException(i8* %10, i8* %11) [ "funclet"(token %9) ]
I have tried to search from the LLVM doxygen documentation and through the LLVM library source code for an API how to set the funclet operand bundle for the call or invoke instruction but without any success.
Does anyone know how to create an operand bundle and set it to the call instruction?
I found a solution that was simpler than I thought:
CallInst::Create and InvokeInst::Create instructions have overloads that take vector/array of OperandBundleDef as arguments. Problem solved.
Seppo
I'm splitting all Basic Blocks with minimum number of instructions (usually 3-5):
llvm::SplitBlock(BasicBlock, &*BasicBlockiter, Pass);
and trying to get object file from IR
llc -filetype=obj 2.ll
I got the following errors:
Instruction does not dominate all uses!
%1 = alloca i32
%mul = load i32* %1
Instruction does not dominate all uses!
%1 = alloca i32
%99 = load i32* %1
and
While deleting: i32 %
Use still stuck around after Def is destroyed: %var = alloca i32
Assertion failed: use_empty() && "Uses remain when a value is destroyed!"
and
error: expected instruction opcode
invoke.cont2: ; preds = %main_block, %invoke
.cont
IR:
invoke.cont2: ; preds = %main_block, %invoke.cont
%call4 = invoke i32 #_ZStorSt13_Ios_OpenmodeS_(i32 8, i32 16)
to label %invoke.cont3 unwind label %lpad1
store i32 %call4, i32* %var4
I think that after splitting, instructions are located in different basic blocks.
If I split the block into 10-15 instructions, all is OK.
How can I predict/check and avoid this errors?
In your first version, you had instruction after a terminator instruction, which was incorrect since this instruction is never executed.
In your second version (not mentioned here, please use stackoverflow instead of private emails...) are using %call (in the store inst) before defining it (%call = ...), so clearly your definition does not precede every use...
But as I said, the store should not be after the invoke, because invoke is a terminatorinst.
The solution is to put your store in the next basic block (you can create a new one) :
%invoke.cont
%call = invoke i8* #_ZNKSs5c_strEv(%"class.std::basic_string"* #loadedFile)
to label %invoke.cont2_before unwind label %lpad1
invoke.cont2_before: ; preds = %invoke.cont
store i8* %call, i8** %reduced_var
br label %invoke.cont2
invoke.cont2: ; preds = %main_block, %invoke.cont2_before
%call4 = invoke i32 #_ZStorSt13_Ios_OpenmodeS_(i32 8, i32 16)
to label %invoke.cont3_before unwind label %lpad1
etc...
How did you managed to pass through expected top-level entity error while executing lli in the llvm framework?
This error usually means that you copy-pasted part of some IR code which doesn't count as a top level entity. In other words, it's not a function, not a type, not a global variable, etc. The same error can happen in C, just for comparison:
x = 8;
Is not valid contents for a C file, because the assignment statement isn't a valid top level entity. To make it valid you put it in a function:
void foo() {
x = 8; /* assuming x is global and visible here */
}
The same error happens in LLVM IR.
My Issue: The .ll file format was "UTF-8 with BOM" instead of "UTF-8 without BOM".
Fix: With notepad++, in the encoding menu, select the "UTF-8 without BOM", then save.
Quick setup: (For llvm 3.4.0 .ll files on windows)
advanced text editor from https://notepad-plus-plus.org/
llvm binaries from https://github.com/CRogers/LLVM-Windows-Binaries
hello.ll as "UTF-8 without BOM" (This code is in llvm 3.4.0 format):
#msg = internal constant [13 x i8] c"Hello World!\00"
declare i32 #puts(i8*)
define i32 #main() {
call i32 #puts(i8* getelementptr inbounds ([13 x i8]* #msg, i32 0, i32 0))
ret i32 0
}
In command prompt:
lli hello.ll
Quick setup: (For llvm 3.8.0 .ll files on windows)
advanced text editor from https://notepad-plus-plus.org/
clang binaries from: http://llvm.org/releases/download.html#3.8.0
hello.ll as "UTF-8 without BOM" (This code is in llvm 3.8.0 format):
#msg = internal constant [13 x i8] c"Hello World!\00"
declare i32 #puts(i8*)
define i32 #main() {
call i32 #puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* #msg, i32 0, i32 0))
ret i32 0
}
In command prompt:
clang hello.ll -o hello.exe
hello.exe
Errors about char16_t, u16String, etc means clang needs: -fms-compatibility-version=19
I'm using LLVM to convert a user-defined language into bytecode, and I'm not sure to understand how should be used a module.
At the beginning, I thought it was something like the C/C++ object files (to avoid bytecode recompilation of every files when a single file is edited). However, I have found this line into LLVMpy documentation, which seems to say that it is not the case :
Inter-module reference is not possible. That is module A cannot call a function in module B, directly.
Can someone explain why are modules separated from the contexts if we can't have multiple modules for a single context ?
It is possible, but like the .o files you mention, they must first be linked together into a single binary.
Given a pair of bitcode files:
$ llvm-dis a.bc -o -
; ModuleID = 'a.bc'
#0 = global [13 x i8] c"Hello world!\0A"
declare i32 #printf(i8*)
define void #f() {
%1 = call i32 #printf(i8* getelementptr inbounds ([13 x i8]* #0, i64 0, i64 0))
ret void
}
$ llvm-dis b.bc -o -
; ModuleID = 'b.bc'
declare void #f()
define i32 #main() {
call void #f()
ret i32 0
}
This won't work:
$ lli b.bc
LLVM ERROR: Program used external function 'f' which could not be resolved!
But if you link them together, it will:
$ llvm-ld a.bc b.bc -disable-opt -o c
$ llvm-dis c.bc -o -
; ModuleID = 'c.bc'
#0 = global [13 x i8] c"Hello world!\0A"
declare i32 #printf(i8*)
define void #f() {
%1 = call i32 #printf(i8* getelementptr inbounds ([13 x i8]* #0, i64 0, i64 0))
ret void
}
define i32 #main() {
call void #f()
ret i32 0
}
$ lli c.bc
Hello world!
To test LLVM's functionality, I wrote the following simple program.
#include <stdio.h>
int main()
{
printf( "Hello World!\n" );
return 0;
}
And then compiled it to LLVM IR by typing clang -S -emit-llvm main.c -o main.ll. The generated code in main.ll was the following.
; ModuleID = 'main.c'
target datalayout = "e-p:64:64:64-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-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-linux-gnu"
#.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00"
define i32 #main() nounwind {
%1 = alloca i32, align 4
store i32 0, i32* %1
%2 = call i32 (i8*, ...)* #printf(i8* getelementptr inbounds ([14 x i8]* #.str, i32 0, i32 0))
ret i32 0
}
declare i32 #printf(i8*, ...)
Then when I tried to compile the IR code (in main.ll) to native executable binary, by typing llc main.ll -o main.s && gcc main.s -o main, I got the following error.
llc: main.ll:5:17: error: expected 'global' or 'constant'
#.str = private unnamed_addr constant [14 x i8] c"Hello World!\0A\00"
However, If I remove unnamed_addr from main.ll, it does get compiled. So my question is what is wrong with unnamed_addr. Why it is not compiling with it? Is this maybe because I'm using incompatible versions of clang and llvm?
The unnamed_addr attribute was introduced in LLVM 2.9.
Could it be that your clang is from 2.9 or newer, while your llc is from 2.8 or older?