/r/LLVM
A place to discuss or ask questions relating to the LLVM Compiler Infrastructure.
To learn more about LLVM visit http://llvm.org/
/r/LLVM
Hi. I'm compiling a project in Swift and debugging it using the lldb. A couple of weeks ago, it was working just fine. But now I'm getting this message, and my breakpoints aren't working anymore.
Could you give me some tips on where I should start to investigate the problem?
I currently have a compiler where I use the legacy FunctionPassManager. My code for this is essentially identical to the Kaleidoscope implementation here: https://llvm.org/docs/tutorial/BuildingAJIT2.html.
Here is the relevant snippet from the tutorial:
class KaleidoscopeJIT {
private:
ExecutionSession ES;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer CompileLayer;
IRTransformLayer TransformLayer;
DataLayout DL;
MangleAndInterner Mangle;
ThreadSafeContext Ctx;
public:
KaleidoscopeJIT(JITTargetMachineBuilder JTMB, DataLayout DL)
: ObjectLayer(ES,
[]() { return std::make_unique<SectionMemoryManager>(); }),
CompileLayer(ES, ObjectLayer, ConcurrentIRCompiler(std::move(JTMB))),
TransformLayer(ES, CompileLayer, optimizeModule),
DL(std::move(DL)), Mangle(ES, this->DL),
Ctx(std::make_unique<LLVMContext>()) {
ES.getMainJITDylib().addGenerator(
cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(DL.getGlobalPrefix())));
}
static Expected<ThreadSafeModule>
optimizeModule(ThreadSafeModule M, const MaterializationResponsibility &R) {
// Create a function pass manager.
auto FPM = std::make_unique<legacy::FunctionPassManager>(M.get());
// Add some optimizations.
FPM->add(createInstructionCombiningPass());
FPM->add(createReassociatePass());
FPM->add(createGVNPass());
FPM->add(createCFGSimplificationPass());
FPM->doInitialization();
// Run the optimizations over all functions in the module being added to
// the JIT.
for (auto &F : *M)
FPM->run(F);
return M;
}
I'm struggling to understand how to adapt this to use the new PassManager, since I will also have to change how the TransformLayer is used `TransformLayer(ES, CompileLayer, optimizeModule)`, since optimizeModule must return a ThreadSafeModule and I'm not sure how to do that with the new PassManager.
I have read the docs on using the new pass manager and I have been looking at how other people have done the migration on their Githubs but I can't find an example that is similar to mine.
I would really appreciate any pointers, or if someone has resources to share. Thanks in advance!
I have a compiler project which I have been working on for close to three months. The first iteration of development, I was spawning actual assembly code and then one month ago my friend and I transferred the code to LLVM. We are developing the entire compiler infrastructure in C++.
Since LLVM-IR and MLIR are natively in C++, is there any way to bring the core to Rust? Because we could frankly use a lot of type safety, traits, memory safety, etc. Rust provides over C++.
Any ideas or suggestions?
I want to run a loop pass, which in my case is IndVars, but I want to run the pass only on a specific loop. How do I use opt tool to achieve this? I'm hoping for answers using new pass manager.
Hey guys I am starting to learn llvm. I have successfully implemented basic DMAS math operations, now I am doing vector operations. However I always get a double as output of calc, I believe I have identified the issue, but I do not know how to solve it, please help.
I believe this to be the issue:
llvm::FunctionType *funcType = llvm::FunctionType::
get
(builder.
getDoubleTy
(), false);
llvm::Function *calcFunction = llvm::Function::
Create
(funcType, llvm::Function::ExternalLinkage, "calc", module.
get
());
llvm::BasicBlock *entry = llvm::BasicBlock::
Create
(context, "entry", calcFunction); llvm::FunctionType *funcType = llvm::FunctionType::get(builder.getDoubleTy(), false);
llvm::Function *calcFunction = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "calc", module.get());
llvm::BasicBlock *entry = llvm::BasicBlock::Create(context, "entry", calcFunction);
The return function type is set to DoubleTy. So when I add my arrays, I get:
Enter an expression to evaluate (e.g., 1+2-4*4): [1,2]+[3,4]
; ModuleID = 'calc_module'
source_filename = "calc_module"
define double u/calc() {
entry:
ret <2 x double> <double 4.000000e+00, double 6.000000e+00>
}
Result (double): 4
I can see in the IR that it is successfully computing it, but it is returning only the first value, I would like to print the whole vector instead.
I have attached the main function below. If you would like rest of the code please let me know.
Main function:
void
printResult
(llvm::GenericValue
gv
, llvm::Type *
returnType
) {
//
std::cout << "Result: "<<returnType<<std::endl;
if
(
returnType
->
isDoubleTy
()) {
//
If the return type is a scalar double
double resultValue =
gv
.DoubleVal;
std::cout
<<
"Result (double): "
<<
resultValue
<<
std::
endl
;
}
else
if
(
returnType
->
isVectorTy
()) {
//
If the return type is a vector
llvm::VectorType *vectorType = llvm::
cast
<llvm::VectorType>(
returnType
);
llvm::ElementCount elementCount = vectorType->
getElementCount
();
unsigned numElements = elementCount.
getKnownMinValue
();
std::cout
<<
"Result (vector): [";
for
(unsigned i = 0; i < numElements; ++i) {
double elementValue =
gv
.AggregateVal
[
i
]
.DoubleVal;
std::cout
<<
elementValue;
if
(i < numElements - 1) {
std::cout
<<
", ";
}
}
std::cout
<<
"]"
<<
std::
endl
;
}
else
{
std::cerr
<<
"Unsupported return type!"
<<
std::
endl
;
}
}
//
Main function to test the AST creation and execution
int
main
() {
//
Initialize LLVM components for native code execution.
llvm::
InitializeNativeTarget
();
llvm::
InitializeNativeTargetAsmPrinter
();
llvm::
InitializeNativeTargetAsmParser
();
llvm::LLVMContext context;
llvm::IRBuilder<>
builder
(context);
auto module = std::
make_unique
<llvm::Module>("calc_module", context);
//
Prompt user for an expression and parse it into an AST.
std::string expression;
std::cout
<<
"Enter an expression to evaluate (e.g., 1+2-4*4): ";
std::
getline
(std::cin, expression);
//
Assuming Parser class exists and parses the expression into an AST
Parser parser;
auto astRoot = parser.
parse
(expression);
if
(!astRoot) {
std::cerr
<<
"Error parsing expression."
<<
std::
endl
;
return
1;
}
//
Create function definition for LLVM IR and compile the AST.
llvm::FunctionType *funcType = llvm::FunctionType::
get
(builder.
getDoubleTy
(), false);
llvm::Function *calcFunction = llvm::Function::
Create
(funcType, llvm::Function::ExternalLinkage, "calc", module.
get
());
llvm::BasicBlock *entry = llvm::BasicBlock::
Create
(context, "entry", calcFunction);
builder.
SetInsertPoint
(entry);
llvm::Value *result = astRoot
->codegen
(context, builder);
if
(!result) {
std::cerr
<<
"Error generating code."
<<
std::
endl
;
return
1;
}
builder.
CreateRet
(result);
module
->print
(llvm::
outs
(), nullptr);
//
Prepare and run the generated function.
std::string error;
llvm::ExecutionEngine *execEngine = llvm::
EngineBuilder
(std::
move
(module)).
setErrorStr
(&error).
create
();
if
(!execEngine) {
std::cerr
<<
"Failed to create execution engine: "
<<
error
<<
std::
endl
;
return
1;
}
std::vector<llvm::GenericValue> args;
llvm::GenericValue gv = execEngine->
runFunction
(calcFunction, args);
//
Run the compiled function and display the result.
llvm::Type *returnType = calcFunction->
getReturnType
();
printResult
(gv, returnType);
delete execEngine;
return
0;
}void printResult(llvm::GenericValue gv, llvm::Type *returnType) {
// std::cout << "Result: "<<returnType<<std::endl;
if (returnType->isDoubleTy()) {
// If the return type is a scalar double
double resultValue = gv.DoubleVal;
std::cout << "Result (double): " << resultValue << std::endl;
} else if (returnType->isVectorTy()) {
// If the return type is a vector
llvm::VectorType *vectorType = llvm::cast<llvm::VectorType>(returnType);
llvm::ElementCount elementCount = vectorType->getElementCount();
unsigned numElements = elementCount.getKnownMinValue();
std::cout << "Result (vector): [";
for (unsigned i = 0; i < numElements; ++i) {
double elementValue = gv.AggregateVal[i].DoubleVal;
std::cout << elementValue;
if (i < numElements - 1) {
std::cout << ", ";
}
}
std::cout << "]" << std::endl;
} else {
std::cerr << "Unsupported return type!" << std::endl;
}
}
// Main function to test the AST creation and execution
int main() {
// Initialize LLVM components for native code execution.
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetAsmParser();
llvm::LLVMContext context;
llvm::IRBuilder<> builder(context);
auto module = std::make_unique<llvm::Module>("calc_module", context);
// Prompt user for an expression and parse it into an AST.
std::string expression;
std::cout << "Enter an expression to evaluate (e.g., 1+2-4*4): ";
std::getline(std::cin, expression);
// Assuming Parser class exists and parses the expression into an AST
Parser parser;
auto astRoot = parser.parse(expression);
if (!astRoot) {
std::cerr << "Error parsing expression." << std::endl;
return 1;
}
// Create function definition for LLVM IR and compile the AST.
llvm::FunctionType *funcType = llvm::FunctionType::get(builder.getDoubleTy(), false);
llvm::Function *calcFunction = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "calc", module.get());
llvm::BasicBlock *entry = llvm::BasicBlock::Create(context, "entry", calcFunction);
builder.SetInsertPoint(entry);
llvm::Value *result = astRoot->codegen(context, builder);
if (!result) {
std::cerr << "Error generating code." << std::endl;
return 1;
}
builder.CreateRet(result);
module->print(llvm::outs(), nullptr);
// Prepare and run the generated function.
std::string error;
llvm::ExecutionEngine *execEngine = llvm::EngineBuilder(std::move(module)).setErrorStr(&error).create();
if (!execEngine) {
std::cerr << "Failed to create execution engine: " << error << std::endl;
return 1;
}
std::vector<llvm::GenericValue> args;
llvm::GenericValue gv = execEngine->runFunction(calcFunction, args);
// Run the compiled function and display the result.
llvm::Type *returnType = calcFunction->getReturnType();
printResult(gv, returnType);
delete execEngine;
return 0;
}
Thank you guys
I'm currently making a compiler that outputs bare LLVM-IR instructions and implementing variadic function calls. I have defined a println
function that accepts a (format) string and variable amount of arguments for the printf
call. I have included printf
calls to see where my program faults and it is as the return of the function, which would make me think that there is something wrong with cleaning up the \@llvm.va_end
calls, since it does what i wanted it to do before the fault.
Here is the llvm instrucitons:
declare void u/llvm.va_start(i8*)
declare void @llvm.va_end(i8*)
declare void @vprintf(i8*, i8*)
@.str_3 = private unnamed_addr constant [2 x i8] c"\0A\00"
declare void @printf(i8*, ...)
@.str_5 = private unnamed_addr constant [4 x i8] c"%i\0A\00"
@.str_6 = private unnamed_addr constant [16 x i8] c"number is %i %i\00"
define void @println(i8* %a, ...) {
entry:
call void @printf(i8* @.str_5, i32 1) ; debug, added prior
%.va_list = alloca i8*
call void @printf(i8* @.str_5, i32 2) ; debug, added prior
call void @llvm.va_start(i8* %.va_list)
call void @printf(i8* @.str_5, i32 3) ; debug, added prior
call void @vprintf(i8* %a, i8* %.va_list)
call void @printf(i8* @.str_3)
call void @printf(i8* @.str_5, i32 4) ; debug, added prior
call void @llvm.va_end(i8* %.va_list)
call void @printf(i8* @.str_5, i32 5) ; debug, added prior
ret void
}
define void @main() {
entry:
call void @printf(i8* @.str_5, i32 0) ; debug, added prior
call void @println(i8* @.str_6, i32 5, i32 2)
call void @printf(i8* @.str_5, i32 6) ; debug, added prior
ret void
}
Output of running the built program:
0
1
2
3
number is 5 2
4
5
As you can see here i get the segmentation fault between printf(5) and printf(6) which would entail that there is something going on at the return/deallocating of memory or something in the println function.
SOLUTION:
Put this ast the va_list definition
%.va_list = alloca i8, i32 128
Hi guys! Any idea on how can I implement a side-channel attack using LLVM?
It can be any known attack, I just want to do it using LLVM to be able to log the information.
P.S.: I just started LLVM and I'm an absolute beginner.
I have the following IR that uses the @ llvm.x86.rdrand.16
intrinsic:
%1 = alloca i32, align 4
%2 = call { i16, i32 } @llvm.x86.rdrand.16.sl_s()
...
ret i32 0
I then try to generate an executable using clang -target $(gcc -dumpmachine) -mrdrnd foo.bc -o foo.o
. This however gives the error:
/usr/bin/x86_64-linux-gnu-ld: /tmp/foo-714550.o: in function `main':
foo.c:(.text+0x9): undefined reference to `llvm.x86.rdrand.16.sl_s'
I believe I need to link some libraries for this to work but I'm not sure what or how, and couldn't find any documentation on the subject of using intrinsics. Any help would be appreciated! TIA.
Looking at the [LLVM 17.0.6 releases] I cannot find a Windows build other than LLVM-17.0.6-win64.exe
and LLVM-17.0.6-win32.exe
. These installers do not install the full LLVM toolchain, only the core tools like clang and lld. Do I need to build LLVM myself?
I have built llvm and clang but when I want to use the built clang++ version it cannot find the headers. My system clang implementation is able to find them and it works fine. Using the same headers as my local (v.15) version with -I also doesn't work.
So is it normal to also have to build libc/libcxx for clang development or what else do I need?
When I run the fuzze by default (The default memory should be 2048MB) , I get out-of-memory at rss:119MB.
But when I run it with -rss_limit_mb=10000. it works forever and the rss stops at 481MB.
I know there may be memory leaks but It's still a weird behaviour.
I want to change the calling convention of a function during clang frontend codegen (when LLVM IR is generated from AST). The files of interest are clang/lib/CodeGen/CodeGenModule.cpp. I see that EmitGlobal() is working with the Decls passed on, where I can change the calling convention in the FunctionType associated with the FunctionDecl, this change reflects in the function declaration and definition but not at the call site where this function is called.
The callsite calling convention is picked form the QualType obtained from CallExpr, and not the FunctionType of the callee. This can be seen in the function CodeGenFunction::EmitCallExpr() in clang/lib/CodeGen/CGExpr.cpp.
I wish to change the calling convention of a function at one place, and this should reflect at all callsites where given function is called.
What should be the best approach to do this?
Hi all, AFAIK, GCC performs better on coremark based on RISC-V than LLVM.
My question is: are there any options we can use to achieve same even better score on RISC-V coremark? If not, I would like to achieve this goal with optimizing LLVM compiler, can anyone guide how to proceed on it?
I am really sorry if this is the wrong place to as this question but I do not know where to ask.
The compilation targets available in my llvm binary for windows ( 18.1.8) does not have wasm as a target. Neither does any older versions or higher versions (19.1.0) of llvm binaries for windows.
this is the output received when I type clang --version :
clang version 18.1.8
Target: x86_64-pc-windows-msvc
Thread model: posix
Emscripten? - I need to do it in hard way to learn more stuff. I am not willing to use Emscripten to compile my c code to wasm but only use llvm
Is the only solution is to build from source all by myself? for which I need to get that huge visual studio stuff?
I am sorry if this question was already answered . But I dd not find a solution when searched through google.
Thank you for helping me
Have a good day :)
https://stackoverflow.com/questions/79023513/whats-wrong-in-my-generated-debug-info-in-llvm-ir
I have tried a few days to but no progress.
I've written my own compiler for my own programming language. Across my own benchmark suite my language is ~2% faster than C compiled with clang -O2
. People keep telling me that "LLVM is the #1 backend for optimization".
So can anyone recommend a benchmark task where there is a simple C/C++/Rust solution to a realistic problem that LLVM does an incredible job optimising so it will put my compiler to shame? I'd like to compare...
( let me know if there are pinned posts or an FAQ section and if this question is repeated here alot)
TLDR; New to open source contribution and lost in the inner workings of C++ to IR code gen.
Hey everyone, I’m a hobbyist with an interest in compilers looking to contribute to LLVM.
I have quite a bit of experience with C++ , but relatively low experience with LLVM (I only built my own compiler with it for a pet language).
I’m currently struggling with understanding the inner workings of LLVM and which part is responsible for what. I know there are a lot of sub projects under the umbrella of LLVM , i’m mostly interested in the c++/C code generation to LLVM IR.
Please drop some tips for a beginner to open source contributions.
(Cross-post from https://discourse.llvm.org/t/clang-development-environment/81140)
Hi,
I’m a masters student, and I’m strating on my thesis now. I’ll write about safety within C++, and would like to develop on Clang.
Currently, I’ve not been able to create a good environment in Clion where I can use it’s debugger with clang (it simply skips over). I am placing breakpoints in the AST, CFG builders, non of which is hit (within Clion). I am currently building the ‘clang’ target in the llvm sub project, and when I modify Clang, the change is compiled, but not executed when I use Clang (a simple print when building the CFG). I’m experiencing this both when compiling C++ and C code.
I was wondering if anyone has experience with debugging Clang through Clion, or if I should use GDB instead? And generally if anyone has some good experiences/advice regarding developing on Clang.
I’m sorry if this has been asked before, I’ve not been able to find any posts or anything.
I cheated and used raylib for rendering and also looked at how clang links to it. but other than that this code is all hand written to be this terrible. so no blaming clang for this catastrophe
https://github.com/nevakrien/first_llvm
Or am I using them wrong?
clang++ --std=c++20 -O3 -Wall -Werror hashmap.cpp -o hashmap -fprofile-instr-generate=instr.profile -fmemory-profile=mp -fuse-ld=lld
ld.lld: error: cannot open /usr/local/lib/clang/20/lib/x86_64-unknown-linux-gnu/libclang_rt.memprof.a: No such file or directory
ld.lld: error: cannot open /usr/local/lib/clang/20/lib/x86_64-unknown-linux-gnu/libclang_rt.memprof_cxx.a: No such file or directory
ld.lld: error: cannot open /usr/local/lib/clang/20/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a: No such file or directory
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
Those files indeed do not exist. Do I need another option to make or install them? llvm is compiled and installed locally with this build script I made (targetting /usr/local by default obviously).
cmake -S llvm-project/llvm -B /mnt/ramdisk/llvm-build -G 'Unix Makefiles' -DLLVM_ENABLE_LIBEDIT=true -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='clang;clang-tools-extra;libclc;lld;lldb;polly;pstl' -DLLVM_ENABLE_RUNTIMES='all' -DLLDB_ENABLE_LIBEDIT=ON || exit 2
cd /mnt/ramdisk/llvm-build || exit 3
nice -n20 make -j48 || exit 4
nice -n20 make -j32 check-clang || exit 5
sudo make -j32 install || exit 6
e: fix formatting
e2: version info:
$ clang++ --version
clang version 20.0.0git (https://github.com/llvm/llvm-project.git 0c274d527ae36db420c4273f83fcb6c859b28f1b)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
$ ld.lld --version
LLD 20.0.0 (https://github.com/llvm/llvm-project.git 0c274d527ae36db420c4273f83fcb6c859b28f1b) (compatible with GNU linkers)
Links to sources are appreciated.