[llvm-bugs] [Bug 48461] New: Linker defined variable used in asm() call results in incorrect value for 32-bit code

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Dec 9 10:55:56 PST 2020


https://bugs.llvm.org/show_bug.cgi?id=48461

            Bug ID: 48461
           Summary: Linker defined variable used in asm() call results in
                    incorrect value for 32-bit code
           Product: clang
           Version: 10.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
          Assignee: unassignedclangbugs at nondot.org
          Reporter: Jared.candelaria at intel.com
                CC: llvm-bugs at lists.llvm.org, neeilans at live.com,
                    richard-llvm at metafoo.co.uk

Created attachment 24256
  --> https://bugs.llvm.org/attachment.cgi?id=24256&action=edit
Repro consisting of C source and linker script with build script

I'm compiling 32-bit x86 code that uses inline assembly, linker defined
variables, and some arithmetic. Clang generates unexpected code around this
compared to gcc.

For example, given the following C:
extern uint8_t BASE[]; // This is the linker defined variable (0x2000).
#define BASE_ADDRESS                        ((uint32_t) BASE)
#define TOP                                 (0xFF100000UL)
#define OFFSET                              (0x000000a5UL)
#define REGISTERS_BASE                      (TOP - BASE_ADDRESS)
#define WRITE_CTL_REG(Register, Value)  WRITE_REG(REGISTERS_BASE + (Register),
Value)
#define WRITE_REG(Register, Value)      \
   __asm__(                             \
      "movl %1, %%fs:(%0) \n\t"         \
      :                                 \
      : "ir"(Register), "ir"(Value)     \
      : "memory"                        \
      )                                 \

    WRITE_CTL_REG(OFFSET, 0xdead);

Clang generates the corresponding:
64 c7 05 a5 20 f0 00    movl   $0xdead,%fs:0xf020a5

While gcc generates:
b8 00 20 00 00          mov    $0x2000,%eax
ba a5 00 10 ff          mov    $0xff1000a5,%edx
29 c2                   sub    %eax,%edx
89 d0                   mov    %edx,%eax
64 c7 00 ad de 00 00    movl   $0xdead,%fs:(%eax)

Clang generates the expected code when compiling as 64-bit.

I tested this on Ubuntu clang version
10.0.1-++20201013091236+ef32c611aa2-1~exp1~20201013191834.199. Attached is a
small repro that compiles, links, and disassembles the problem spot. You can
uncomment a gcc invocation in build.sh to see what gcc will do in the same
situation. Also attached is example.txt that does this for you.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201209/e421d2a1/attachment.html>


More information about the llvm-bugs mailing list