Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

x86 assembly printer fails to print "mov eax, [0xfed00010]" correctly #12220

Open Quuxplusone opened 12 years ago

Quuxplusone commented 12 years ago
Bugzilla Link PR12102
Status NEW
Importance P normal
Reported by Ben Panning (benjamin.j.panning@intel.com)
Reported on 2012-02-27 14:08:48 -0800
Last modified on 2017-05-01 10:32:20 -0700
Version 3.0
Hardware PC All
CC anton@korobeynikov.info, flash@pobox.com, llvm-bugs@lists.llvm.org, wendling@apple.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
The assembly printer for x86 fails to print certain MOVrm instructions
correctly.  This can be reproduced following these steps:

*** 1. Create a basic C++ example to be compiled:

int main() {
  int* x = (int*)0xfed00010; // HPET MMIO
  return *x; // Read on this MMIO
}

*** 2. Run this through clang using the following command (Windows):

  clang.exe -emit-llvm -S -o source.ll source.cpp

*** 3. Run this through llc using the following command (Windows):

  llc.exe -filetype=asm -x86-asm-syntax=intel -print-after-all source.ll

*** 4. Examine the final assembly product (source.s):

  # MMIO read shows up as this...
  mov     EAX, -19922928 # mov     EAX, 0xfed00010

I've examined the object file produced when I change the -filetype to "obj",
and the binary appears to be correct.  Decoding the binary results in the
following instruction:

  mov     eax, dword ptr [0xfed00010]

Looking at the "IR Dump After X86 AT&T-Style Assembly Printer" yields the
following instruction:

  %EAX<def> = MOV32rm %noreg, 1, %noreg, -19922928, %noreg; mem:LD4[%0]

This looks correct, and it's only when this is printed does the error occur.
This leads me to believe the bug is isolated within the assembly printer.
Quuxplusone commented 12 years ago

Intel asm printer is of 'listing' quality. It should not be used to produce anything which can be assembled back.

Quuxplusone commented 12 years ago

Devang would normally have picked this up since he was pushing the intel printer forward, but he isn't working on llvm anymore.

Quuxplusone commented 12 years ago

This issue appears to impact all short form move instructions that encode destination register as EAX within the opcode.

Looking at the x86InstrInfo.td file, it appears that the encoding of these instructions is incorrect. The addressing mode is described as being PC-relative, but that addressing mode is invalid in protected mode (32-bit). PC relative addressing is only valid within long-mode (64-bit).

I'm unsure if this encoding is to blame or whether the special short-form move simplification within X86MCInstLower::Lower() is to blame.

For now, I've worked around this issue in our tool-chain by removing the short-form move instructions from the instruction set. If I have time, I will try to provide a real fix for this issue (granted, I'm not very familiar with TableGen and the X86 back-end, so it may take some time...).