llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.98k stars 11.55k forks source link

Support choosing assembly dialect per snippet in clang #101328

Open dzaima opened 1 month ago

dzaima commented 1 month ago

Currently the primary way to change x86 inline assembly dialect (intel vs AT&T) is -masm=intel & -masm=att. This is a global change, undesired if some #included code assumes AT&T.

Using .intel_syntax breaks on passing operands, as those still get generated with a leading % (https://github.com/llvm/llvm-project/issues/24606; https://godbolt.org/z/1xbfYsWh1). But, even if that were fixed, "m" operands would still likely remain broken due to having a completely different syntax.

A complete solution would be the ability to choose assembly dialect per assembly block. https://reviews.llvm.org/D113707 mentioned a potential option of #pragma clang asm_dialect push "att" & #pragma clang asm_dialect pop, but as far as I can tell nothing like that ever landed.

Motivating use-case is using inline intel assembly in a project which, for valgrind builds, uses <valgrind/valgrind.h> which in turn assumes AT&T assembly.

MitalAshok commented 1 month ago

What do you think about the strategy used by #101871? An attribute that can be per-asm statement, or applied to a region of functions with:

#pragma clang attribute push ([[clang::asm_dialect("att")]], apply_to = function)
#include <valgrind/valgrind.h>
#pragma clang attribute pop

Also possibly reach out to Valgrind to allow their headers with both Intel and AT&T syntax: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Multiple-assembler-dialects-in-asm-templates

dzaima commented 1 month ago

@MitalAshok Something like that (but worse, i.e. ad-hoc identifiers) was what I was gonna propose if I hadn't found the previous proposal. Your attribute approach would be perfect.