llvm / llvm-project

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

[X86] Inline assembly operands don't work with .intel_syntax #24606

Open rnk opened 9 years ago

rnk commented 9 years ago
Bugzilla Link 24232
Version trunk
OS All
CC @compnerd,@noloader,@pawelsopensource,@yurivict

Extended Description

Consider this C code:

int mynegation(int r) { __asm(".intel_syntax\n" "negl %0\n" : "=r"(r) : "0"(r)); return r; }

It gives this IR:

define i32 @​mynegation(i32 %r) { entry: %0 = tail call i32 asm ".intel_syntax\0Anegl $0\0A", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %r) ret i32 %0 }

Our inline asm operand support expands the $0 operand as '%ecx' and then attempts to re-parse the inline assembly. This fails, because '%ecx' should not have the percent in intel style assembly. We get this error:

:2:6: error: unknown token in expression negl %ecx ^ Our current inline assembly support works by running the operands through the old AsmPrinter infrastructure and then re-parsing with MC. If instead we could teach the MC asm parser how to tolerate symbolic operands, we could fix this problem without worrying about .intel_syntax directives. Alternatively, we could hack the intel syntax parser to be OK with %. GCC probably does this.
rnk commented 2 years ago

mentioned in issue llvm/llvm-bugzilla-archive#39895

rnk commented 5 years ago

Bug llvm/llvm-bugzilla-archive#39895 has been marked as a duplicate of this bug.

70311826-e6d8-4d29-8604-c4ec4bfa7f0d commented 6 years ago

This issue is present in Clang 3.7 and 3.8. Does anyone know if this is ever going to be fixed?

If it is not going to be fixed, then can LLVM please stop defining GNUC. LLVM cannot consume the same program as GCC who it is pretending to be.

70311826-e6d8-4d29-8604-c4ec4bfa7f0d commented 8 years ago

The bug is marked as Windows NT, but we experience it on both Mac OS X and Linux. For example, I just encountered it on Ubuntu Server 14.04 LTS with Clang 3.4.

Ironically, we have never encountered it on Windows. As far as I know, all of our users enlist Microsoft toolchains on the platform. When we compile on Windows, different code paths are activated that use MASM syntax.

70311826-e6d8-4d29-8604-c4ec4bfa7f0d commented 9 years ago

If you want a real world test case, try the Crypto++ library. We have skeleton support for LLVM/Clang's integrated assembler. Its an awful mix of ASM inline statements, ASM code blocks, AT&T dialect and Intel dialect.

The library is UBsan and Asan clean when unaligned access is disabled


Reduced test case


This tests GCM mode. GCM mode only required 3 tweaks. Look for CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER at https://github.com/weidai11/cryptopp/blob/master/gcm.cpp.

git clone https://github.com/weidai11/cryptopp.git cryptopp-asm cd cryptopp-asm

Disable unaligned access

sed -i "s|// #define CRYPTOPP_NO_UNALIGNED_DATA_ACCESS|#define CRYPTOPP_NO_UNALIGNED_DATA_ACCESS|g" config.h

First, build everything without ASM

make cryptest.exe

Next, enable ASM for GCM

rm gcm.o make cryptest.exe FORCE_ASM=1

Run them, test suite, and then test vectors

./cryptest.exe v 2>&1 | grep FAILED ./cryptest.exe tv all 2>&1 | grep FAILED


Full test case


git clone https://github.com/weidai11/cryptopp.git cryptopp-asm cd cryptopp-asm

Disable unaligned access

sed -i "s|// #define CRYPTOPP_NO_UNALIGNED_DATA_ACCESS|#define CRYPTOPP_NO_UNALIGNED_DATA_ACCESS|g" config.h

Build everything with ASM

This used to die...

make cryptest.exe FORCE_ASM=1

Run them, test suite, and then test vectors

./cryptest.exe v 2>&1 | grep FAILED ./cryptest.exe tv all 2>&1 | grep FAILED


Other changes


I have commit access. I can change anything LLVM needs.

I embrace working with SME's to solve problems. LLVM is clearly the the experts on compilation and assembly, so I have no problem deferring and following advice.

rnk commented 9 years ago

We already want to avoid doing this reparsing of symbolic operands for https://llvm.org/bugs/show_bug.cgi?id=23933. If we fix that, fixing this shouldn't be hard.