[llvm-bugs] [Bug 50984] New: Assembler for aarch64 does not accept loading a float register with a 64 bits immediate with ldr pseudo-instruction

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Jul 4 23:57:23 PDT 2021


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

            Bug ID: 50984
           Summary: Assembler for aarch64 does not accept loading a float
                    register with a 64 bits immediate with ldr
                    pseudo-instruction
           Product: tools
           Version: 12.0
          Hardware: Macintosh
                OS: MacOS X
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: llvm-as
          Assignee: unassignedbugs at nondot.org
          Reporter: didou.diaz at gmail.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 24999
  --> https://bugs.llvm.org/attachment.cgi?id=24999&action=edit
The asm file with triggering the error

On arm64/darwin (actually M1/MacOS X), trying to assemble the loading of d0
with the binary representation of a float as a 64 bits integer, using the ldr
pseudo-instruction results in an error. Example:

  ldr d0, =4614256657332092287

triggers: error: Immediate too large for register

(the integer corresponds to the double floating number 3.141593).

This is valid and well compiled under aarch64/linux with gcc toolchain).

To repoduce it, I provide 2 files : the problematic asm file and a C main
(simply to check the execution when well assembled).

Run with (gcc being an alias for clang):

$ gcc -o main main.c dbl_as_64imm.S 
dbl_as_64imm.S:21:17: error: Immediate too large for register
        ldr d0, =pi
                ^

The same files works well under aarch64/linux (the asm file can be compiled on
both platforms).

$ gcc -o main main.c dbl_as_64imm.S 
$ ./main
3.141593

On macOS, you can modify the dbl_as_64imm.S:1 replacing #if 0 by #if 1 to
activate a workaround which decomposes the loading into 2 instructions:

  ldr x0, =461425665733209228
  fmov    d0, x0

This works well:

$ gcc -o main main.c dbl_as_64imm.S 
$ ./main
3.141593

>From what I can see, it seems the problem is in AArch64AsmParser::parseOperand
where I see:

     APInt Simm = APInt(64, Imm << ShiftAmt);
       // check if the immediate is an unsigned or signed 32-bit int for W regs
       if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
         return Error(Loc, "Immediate too large for register");
     }

The test only allows a 64bits immediate for an X register, not a D register.

Hope this helps

Daniel

-- 
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/20210705/136cf913/attachment.html>


More information about the llvm-bugs mailing list