ldc-developers / ldc

The LLVM-based D Compiler.
http://wiki.dlang.org/LDC
Other
1.19k stars 259 forks source link

error: couldn't allocate input reg for constraint '{dx}' at line 5 #4454

Closed rempas closed 1 year ago

rempas commented 1 year ago

I do have the following function to implement and do system calls:

RT syscall(RT, SYSN syscall_num, T...)(T args) {
  static assert(args.length <= 6, "Wrong number of arguments. They can be up to 6");

  RT result;

  static if (args.length == 0) {
    asm {
      "syscall"
        : "=a" (result)
        : "a" (syscall_num)
        : "memory", "rcx", "r11";
    }
  }

  else static if (args.length == 1) {
    asm {
      "syscall"
        : "=a" (result)
        : "a" (syscall_num), "D" (args[0])
        : "memory", "rcx", "r11";
    }
  }

  else static if (args.length == 2) {
    import commons;
    asm {
      "syscall"
        : "=a" (result)
        : "a" (syscall_num), "D" (args[0]), "S" (args[1])
        : "memory", "rcx", "r11";
    }
  }

  else static if (args.length == 3) {
    asm {
      "syscall"
        : "=a" (result)
        : "a" (syscall_num), "D" (args[0]), "S" (args[1]), "d" (args[2])
        : "memory", "rcx", "r11";
    }
  }

  else static if (args.length == 4) {
    asm {
      "syscall"
        : "=a" (result)
        : "a" (syscall_num), "D" (args[0]), "S" (args[1]), "d" (args[2]), "r10" (args[3])
        : "memory", "rcx", "r11";
    }
  }

  else static if (args.length == 5) {
    asm {
      "syscall"
        : "=a" (result)
        : "a" (syscall_num), "D" (args[0]), "S" (args[1]), "d" (args[2]), "r10" (args[3]), "r8" (args[4])
        : "memory", "rcx", "r11";
    }
  }

  else {
    asm {
      "syscall"
        : "=a" (result)
        : "a" (syscall_num), "D" (args[0]), "S" (args[1]), "d" (args[2]), "r10" (args[3]), "r8" (args[4]), "r9" (args[5])
        : "memory", "rcx", "r11";
    }
  }

  return result;
}

This seems to be working great but for some reason, it seems to be having a problem when I'm trying to implement the "exec" system call in ONE specific case. So yeah, I do have a very specific problem...

What's worse is that I'm not even able to reproduce it in a smaller code example. So, could you at least give me info on when this problem may occur so I can at least get an idea of what MIGHT be causing it?

System information: OS: Arch Linux output of ldc2 --version:

LDC - the LLVM D compiler (1.32.2):
  based on DMD v2.102.2 and LLVM 15.0.7
  built with LDC - the LLVM D compiler (1.32.1)
  Default target: x86_64-pc-linux-gnu
  Host CPU: znver1
  http://dlang.org - http://wiki.dlang.org/LDC

  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_32 - AArch64 (little endian ILP32)
    aarch64_be - AArch64 (big endian)
    amdgcn     - AMD GCN GPUs
    arm        - ARM
    arm64      - ARM64 (little endian)
    arm64_32   - ARM64 (little endian ILP32)
    armeb      - ARM (big endian)
    avr        - Atmel AVR Microcontroller
    bpf        - BPF (host endian)
    bpfeb      - BPF (big endian)
    bpfel      - BPF (little endian)
    hexagon    - Hexagon
    lanai      - Lanai
    mips       - MIPS (32-bit big endian)
    mips64     - MIPS (64-bit big endian)
    mips64el   - MIPS (64-bit little endian)
    mipsel     - MIPS (32-bit little endian)
    msp430     - MSP430 [experimental]
    nvptx      - NVIDIA PTX 32-bit
    nvptx64    - NVIDIA PTX 64-bit
    ppc32      - PowerPC 32
    ppc32le    - PowerPC 32 LE
    ppc64      - PowerPC 64
    ppc64le    - PowerPC 64 LE
    r600       - AMD GPUs HD2XXX-HD6XXX
    riscv32    - 32-bit RISC-V
    riscv64    - 64-bit RISC-V
    sparc      - Sparc
    sparcel    - Sparc LE
    sparcv9    - Sparc V9
    systemz    - SystemZ
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
    ve         - VE
    wasm32     - WebAssembly 32-bit
    wasm64     - WebAssembly 64-bit
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64
    xcore      - XCore
JohanEngelen commented 1 year ago

For this particular code example, we also need the specific template instantiation code. Something where you actually call the syscall template. Please reproduce the problem here: https://d.godbolt.org/z/nxzb4fPPc

kinke commented 1 year ago

couldn't allocate input reg for constraint '{dx}'

All I can say at this point is that {dx} is the LLVM translation of the gcc d constraint. So maybe a type of some 3rd argument is unexpected.

rempas commented 1 year ago

All I can say at this point is that {dx} is the LLVM translation of the gcc d constraint. So maybe a type of some 3rd argument is unexpected.

Thank you! This itself say a lot! Could I ask if there is documentation about LLVM translations?

rempas commented 1 year ago

For this particular code example, we also need the specific template instantiation code. Something where you actually call the syscall template. Please reproduce the problem here: https://d.godbolt.org/z/nxzb4fPPc

Like I said, the problem is that, this error happens only in my code project and I wasn't able to reproduce it in a smaller code example...

I think that I should probably close the issue. If I end up finding the what's wrong (@kinke gave me an idea), I will reply!

kinke commented 1 year ago

Could I ask if there is documentation about LLVM translations?

Well, not docs, but code: https://github.com/ldc-developers/ldc/blob/1a93fc75b454d8d3e164067ff6d6beb5313ce84a/gen/asm-gcc.cpp#L95-L122

rempas commented 1 year ago

Could I ask if there is documentation about LLVM translations?

Well, not docs, but code:

https://github.com/ldc-developers/ldc/blob/1a93fc75b454d8d3e164067ff6d6beb5313ce84a/gen/asm-gcc.cpp#L95-L122

Thank you! I'll fix it quickly now that I know what causes it! Probably I'm messing a pointer...

Have a nice day!