28 июля 2025
Фотография
нажмите — покажем
нажмите — покажем
Хотите учиться в магистратуре бесплатно? Ведущие вузы страны ИТМО, МФТИ, МИЭТ и компания YADRO предлагают практико-ориентированное обучение по четырем направлениям на выбор.
Преимущества магистратуры YADRO:
— Бюджетные места и возможность получать стипендию.
— Трудоустройство в YADRO и партнерские компании.
— Диплом государственного образца.
— Обучение у лидеров индустрии и преподавателей ведущих вузов — получите сильный технический бэкграунд, который выделит вас на рынке.
Учитесь бесплатно у крупнейшей российской компании на рынке вычислительной техники — подавайте заявку уже сейчас, а документы загружайте, когда удобно!
1 августа 2025
Добрый день, подскажите ещё вопрос по кодген тестам, пожалуйста. Не могу понять принцип их написания. Вот, например, тест из файла freeze.ll. Тут тестируется что freeze нормально отработал что ли?
define i32 @freeze_int() {
; CHECK-LABEL: freeze_int:
; CHECK: // %bb.0:
; CHECK-NEXT: mul w0, w8, w8
; CHECK-NEXT: ret
%y1 = freeze i32 undef
%t1 = mul i32 %y1, %y1
ret i32 %t1
}
Ещё, у Никиты Попова есть статья про llvm, там приводится пример кодген теста. И тоже непонятно, что он тестирует. Там правка заключалась в преобразовании A + (B & ~A) в A | (B & ~A), а потом и в A | B. Но в тесте этого нет, насколько вижу, что в IR A + (B & ~A), что в CHECK то же A + (B & ~A)
define i8 @add_and_xor(i8 %x, i8 %y) {
; CHECK-LABEL: @add_and_xor(
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1
; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X]]
; CHECK-NEXT: ret i8 [[ADD]]
;
%xor = xor i8 %x, -1
%and = and i8 %xor, %y
%add = add i8 %and, %x
ret i8 %add
}
19 августа 2025
20 августа 2025
21 сентября 2025
12 октября 2025
6 декабря 2025
25 января 2026
#ifdef CONFIG_PGO_CLANG
#define PGO_CLANG_DATA \
__llvm_prf_data : AT(ADDR(__llvm_prf_data) - LOAD_OFFSET) { \
. = ALIGN(8); \
__llvm_prf_start = .; \
__llvm_prf_data_start = .; \
KEEP(*(__llvm_prf_data)) \
. = ALIGN(8); \
__llvm_prf_data_end = .; \
} \
__llvm_prf_cnts : AT(ADDR(__llvm_prf_cnts) - LOAD_OFFSET) { \
. = ALIGN(8); \
__llvm_prf_cnts_start = .; \
KEEP(*(__llvm_prf_cnts)) \
. = ALIGN(8); \
__llvm_prf_cnts_end = .; \
} \
__llvm_prf_names : AT(ADDR(__llvm_prf_names) - LOAD_OFFSET) { \
. = ALIGN(8); \
__llvm_prf_names_start = .; \
KEEP(*(__llvm_prf_names)) \
. = ALIGN(8); \
__llvm_prf_names_end = .; \
. = ALIGN(8); \
} \
__llvm_prf_vals : AT(ADDR(__llvm_prf_vals) - LOAD_OFFSET) { \
__llvm_prf_vals_start = .; \
KEEP(*(__llvm_prf_vals)) \
. = ALIGN(8); \
__llvm_prf_vals_end = .; \
. = ALIGN(8); \
} \
__llvm_prf_vnds : AT(ADDR(__llvm_prf_vnds) - LOAD_OFFSET) { \
__llvm_prf_vnds_start = .; \
KEEP(*(__llvm_prf_vnds)) \
. = ALIGN(8); \
__llvm_prf_vnds_end = .; \
__llvm_prf_end = .; \
}
#else
#define PGO_CLANG_DATA
#endif
7 марта 2026
31 августа 2026
[ Taha. Dostifam ]Is there really any way to cast a StructValue into ArrayValue in LLVM 18? BitCast didn't worked.
P.S. In global vars, not inside function
if you have ptr to ArrayValue, you can just load StructValue from ptr directly:
llvm::Value* structVal = LLVMBuilder->CreateLoad(YourStructType, ptrToArr);
Egor Antonchikovif you have ptr to ArrayValue, you can just load StructValue from ptr directly:
llvm::Value* structVal = LLVMBuilder->CreateLoad(YourStructType, ptrToArr);
Problem is that when emitting global var, there is no position set to be used, so when I try to load, llvm panics.
Фотография
нажмите — покажем
нажмите — покажем
The bigger problem is that we can't convert a pointer (with PIE enabled) to byte. But I don't really understand how LLVM is supposed to handle such case.
Interestingly rustc does not store explicit tag, and embeds it inside the value with shift. But I don't why they are doing this and it somehow works
1 сентября 2026
[ Taha. Dostifam ]I even tried to convert struct value byte by byte to string but didn't worked
Why don't you use getelementptr with @"tmp_main$my_enum1" directly?
I think the Panic occurs after calling @llvm.memcpy. I think you use @llvm.memcpy incorrect.
Egor AntonchikovWhy don't you use getelementptr with @"tmp_main$my_enum1" directly?
I think the Panic occurs after calling @llvm.memcpy. I think you use @llvm.memcpy incorrect.
It's possible.
But as I showed in selected text we cannot hardcode the pointer inside buffer because with PIE enabled, the address is not known until linked.
Rust uses different approach and stores the global var with actual payload type, so they never convert pointers, but convert other values (e.g. integer, struct, ...) to bytes.
Why I can't do the same thing easily? Because it becomes very painful when loading enum value in runtime. We have to keep track of payload kind, that it's a buffer? or actual payload type...
Фотография
нажмите — покажем
нажмите — покажем
I fixed it!
The solution is that, llvm has an intrinsic global var for initializing lazily. Here is how it works:
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @__cyrus_global_var_ctors, ptr null }]
It gets priority and a function pointer and runs automatically at program startup.
We could make this simply by having a simple function per module and calling all of the at main startup, but LLVM made it convenient and ready to use.
Thanks for everybody tried to help or participated in the discussion.