rustc_codegen_cranelift icon indicating copy to clipboard operation
rustc_codegen_cranelift copied to clipboard

aarch64/macOS: error: invalid asm template string: expected `}`, found `.` + unsupported architectural extension: dit

Open Nicceboy opened this issue 6 months ago • 7 comments

There are couple issues when compiling crate rustls-graviola, which utilises a lot of inline assembly.

Compiled on aarch64/macOS with latest Nightly/cranelift.

   Compiling graviola v0.2.1
error: invalid asm template string: expected `}`, found `.`
   Compiling rustls-graviola v0.2.1
    --> <anon>:5041:15
     |
5041 |        st1 {q0.16b}, [x0]
     |            -  ^ expected `}` in asm template string
     |            |
     |            because of this opening brace
     |
     = note: if you intended to print `{`, you can escape it using `{{`

error: aborting due to 1 previous error

error: unsupported architectural extension: dit
  |
note: instantiated into assembly here
 --> <inline asm>:8:17
  |
8 | .arch_extension dit
  |                 ^

error: unsupported architectural extension: dit
   |
note: instantiated into assembly here
  --> <inline asm>:10:17
   |
10 | .arch_extension nodit

See minimal example here to reproduce: https://github.com/Nicceboy/cranelift-graviola/.

Nicceboy avatar Jun 28 '25 01:06 Nicceboy

There are two issues:

  • I didn't escape { and } before passing the generated global_asm!() to cg_llvm.
  • Graviola expects a register name like v0 to be used for out(vreg) to combine with .16b to form v0.16b, cg_clif however uses q0 as it enables the q modifier by default since https://github.com/rust-lang/rustc_codegen_cranelift/pull/1564. It seems like I was a bit too eager using the q modifier everywhere though. I think it is only necessary for the loads/stores that cg_clif inserts for clobbered registers. Not for user references to vector registers.
  • Enabling support for the dit feature using .arch_extension isn't supported by LLVM for whatever reason. That is going to be an issue for #[naked] functions too as those also use .arch_extension. cc @folkertdev In any case removing #[target_feature(enable = "dit")] in graviola doesn't work either as the DIT msr is not accessible.

Opened https://github.com/rust-lang/rustc_codegen_cranelift/pull/1587 for the first two issues.

bjorn3 avatar Jul 03 '25 10:07 bjorn3

Fun. I guess I'll open an LLVM error for that one and hope for the best?

folkertdev avatar Jul 03 '25 10:07 folkertdev

this works apparently https://godbolt.org/z/jWvxGKjPG

#[unsafe(no_mangle)]
#[unsafe(naked)]
//#[target_feature(enable = "dit")]
unsafe extern "C" fn write() {
    core::arch::naked_asm!(
        ".arch armv8.4-a",
        "msr DIT, #0",
        "ret"
    ) 
}

Still that seems really inconsistent

folkertdev avatar Jul 03 '25 10:07 folkertdev

I believe this is related to https://github.com/rust-lang/rust/issues/113221. Also arm's target features are just an absolute mess, and the above isn't really workable because there is no way to "pop" the .arch to go back to the previous state.

folkertdev avatar Jul 03 '25 10:07 folkertdev

Same error.

error: unsupported architectural extension: dit
  |
note: instantiated into assembly here
 --> <inline asm>:8:17
  |
8 | .arch_extension dit
  |                 ^

error: unsupported architectural extension: dit
   |
note: instantiated into assembly here
  --> <inline asm>:10:17
   |
10 | .arch_extension nodit
   |                 ^

error: unsupported architectural extension: dit
   |
note: instantiated into assembly here
  --> <inline asm>:49:17
   |
49 | .arch_extension dit
   |                 ^

error: unsupported architectural extension: dit
   |
note: instantiated into assembly here
  --> <inline asm>:51:17
   |
51 | .arch_extension nodit
   |                 ^

error: unsupported architectural extension: dit
   |
note: instantiated into assembly here
  --> <inline asm>:65:17
   |
65 | .arch_extension dit
   |                 ^

error: unsupported architectural extension: dit
   |
note: instantiated into assembly here
  --> <inline asm>:67:17
   |
67 | .arch_extension nodit
   |                 ^

error: aborting due to 6 previous errors

error: Failed to assemble `.globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n0
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n0:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
       .arch_extension dit
       msr dit, #1
       .arch_extension nodit
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n1
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n1:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
       .arch_extension sb
       sb
       .arch_extension nosb
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n2
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n2:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
       dsb nsh
       isb sy
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n3
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n3:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
       .arch_extension dit
       mrs x0, dit
       .arch_extension nodit
           str x0, [x19, 0x0]
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n4
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n4:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
           ldr x0, [x19, 0x0]
       .arch_extension dit
       msr dit, x0
       .arch_extension nodit
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n5
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n5:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
           ldr q0, [x19, 0x0]
           ldr q1, [x19, 0x10]
       and v0.16b, v0.16b, v1.16b
           str q0, [x19, 0x0]
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n6
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n6:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
           ldr q0, [x19, 0x0]
           ldr q1, [x19, 0x10]
       cmeq v0.16b, v0.16b, v1.16b
           str q0, [x19, 0x0]
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n7
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n7:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
           ldr q0, [x19, 0x0]
       shrn v0.8b, v0.8h, #4
           str q0, [x19, 0x0]
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n8
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n8:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
           ldr x0, [x19, 0x0]
       /* x0 */
           str x0, [x19, 0x0]
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       .globl ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n9
       ___inline_asm_constant_time_eq__6de17b028b8a3a1d_cgu__0_n9:
           stp fp, lr, [sp, #-32]!
           mov fp, sp
           str x19, [sp, #24]
           mov x19, x0
           ldr x0, [x19, 0x0]
       /* x0 */
           str x0, [x19, 0x0]
           ldr x19, [sp, #24]
           ldp fp, lr, [sp], #32
           ret
       
       
       `

error: could not compile `constant_time_eq` (lib) due to 1 previous error

YuniqueUnic avatar Sep 10 '25 06:09 YuniqueUnic

There is not much I can do about this. LLVM's assembler just doesn't support .arch_extension dit and without .arch_extension dit the assembler rejects setting the instruction to set the dit flag due to the dit target feature not being enabled for the assembly block.

bjorn3 avatar Sep 15 '25 15:09 bjorn3

The fix has landed in LLVM. We will now have to wait for the next LLVM release and have rustc update LLVM.

bjorn3 avatar Dec 10 '25 12:12 bjorn3