New direction: adding constants and function pointers to the IR

Compilation problems

For some reason, the devcontainer can’t cross compile stdlib.h for aarch64. It gives the following error:

usr/include/gnu/stubs.h:7:11: fatal error: 'gnu/stubs-32.h' file not found
  7 | # include <gnu/stubs-32.h>
    |           ^~~~~~~~~~~~~~~~ 

This can be resolved by installing glibc-devel.i686 with the following command:

dnf install glibc-devel.i686

However, this then produces the following error:

/usr/include/bits/floatn.h:97:9: error: __float128 is not supported on this target
   97 | typedef __float128 _Float128;
      |         ^

Based on an analysis by AI, it seems like the problem is that clang is using the wrong libraries for compilation (x86_64 as opposed to aarch64), which is causing invalid requirements.

AI recommends that I change the top line of the Dockerfile to

FROM --platform=linux/arm64 fedora:42

When I do that, I get the following error while running cargo run -- <benchmark>:

error: failed to run custom build command for `llvm-sys v170.4.0`

Caused by:
  process didn't exit successfully: `/workspaces/refinator/target/debug/build/llvm-sys-c997bb9b13eb2874/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-env-changed=LLVM_SYS_170_PREFIX
  cargo:rerun-if-env-changed=LLVM_SYS_170_IGNORE_BLOCKLIST
  cargo:rerun-if-env-changed=LLVM_SYS_170_STRICT_VERSIONING
  cargo:rerun-if-env-changed=LLVM_SYS_170_NO_CLEAN_CFLAGS
  cargo:rerun-if-env-changed=LLVM_SYS_170_USE_DEBUG_MSVCRT
  cargo:rerun-if-env-changed=LLVM_SYS_170_FFI_WORKAROUND

  --- stderr

  thread 'main' (3736) panicked at /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/llvm-sys-170.4.0/build.rs:132:21:
  Failed to search PATH for llvm-config: "llvm-config" "--version"
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

When I check if I have llvm-config, it seems like I have llvm-config-17, but not llvm-config.

Based on recommendations from AI, I ran llvm-config-17 --prefix, which printed out /usr/lib64/llvm17. Then, I reran the command, setting the environment variable LLVM_SYS_170_PREFIX to /usr/lib64/llvm17.

LLVM_SYS_170_PREFIX="/usr/lib64/llvm17" cargo run -- <benchmark>

This seemed to solve that problem. However, it also runs really slowly, so maybe I’ll try and install the aarch64 glibc on x86_64 Fedora.

I added glibc-devel.aarch64 to the dnf install list in the dev container Dockerfile, and it appears to have solved the problem.

Final solution: install glibc-devel.aarch64

EDIT: This is only possible if the platform is linux/arm64, glibc-devel.aarch64 can’t effectively be installed on x86_64, so this isn’t really a solution. I’ve given up on trying to resolve this for now. I’ll use --platform=linux/arm64 when I need to compile with #include <stdlib.h>, and I’ll use x86_64 when I need to do debugging.

Function pointers

What does a function pointer look like?

A function pointer has the syntax <ret_type> (* fn_name)(param_types...).

How does a function pointer translate to LLVM?

I was able to successfully get this working with the following C code.

int add(int *x, int *y) {
    return *x + *y;
}
 
int calc(int (*f)(int*, int*), int x, int y) {
    return (*f)(&x, &y);
}
 
int main() {
    int result = calc(&add, 1, 2);
    return 0;
}

This causes &inator to fail stating that it doesn’t support function pointers. I need to figure out where this happens.

Constants

What does this look like in C code?

Victor gave me this code, but it doesn’t quite compile.

#include <stdlib.h>
int main() {
    int a;
    *NULL = &a;
    return 0;
}

The goal is to produce LLVM code like this:

define i32 @main() {
entry:
    %a = alloca i32
    store ptr %a, ptr null
    return i32 0
}

The closest replication I could find is

#include <stdlib.h>
 
int main() {
    int* a = NULL;
    int b;
    *a = b;
    return *a;
}

However, this just compiles to

define dso_local i32 @main() #0 {
entry:
  unreachable
}

so it isn’t a useful reproduction. I need to figure out a different way to get constants to appear in the code.


I’ve searched for store ptr [^ ]+, [^%]+?, (since I believe this should match non-variable stores) in benchmarks/**/*.ll, and it appears to be giving me something in the form of ptr @<name>. What does this mean?

TODO for next session

  • Figure out a different way to get constants to appear in the code
  • Figure out what store ptr @.str.78, ptr @testName, align 8, !tbaa !6 means
  • Figure out how function pointers translate to LLVM and IR