[llvm-bugs] [Bug 42736] New: [mips] Incorrect code in case of applying 32-bit mask to result of 64-bit address loading
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Jul 24 04:10:54 PDT 2019
https://bugs.llvm.org/show_bug.cgi?id=42736
Bug ID: 42736
Summary: [mips] Incorrect code in case of applying 32-bit mask
to result of 64-bit address loading
Product: libraries
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: enhancement
Priority: P
Component: Backend: MIPS
Assignee: unassignedbugs at nondot.org
Reporter: simon at atanasyan.com
CC: llvm-bugs at lists.llvm.org
If result of 64-bit address loading combines with 32-bit mask, LLVM tries to
optimize the code and remove "redundant" loading of upper 32-bits of the
address. Unfortunately it leads to incorrect code on MIPS64 targets.
----------
$ cat test.ll
define dso_local void @bar1() {
entry:
%val = alloca i64, align 8
store i64 ptrtoint (void (...)* @foo to i64), i64* %val, align 8
%0 = load i64, i64* %val, align 8
ret void
}
define dso_local void @bar2() {
entry:
%val = alloca i64, align 8
store i64 and (i64 ptrtoint (void (...)* @foo to i64), i64 268435455), i64*
%val, align 8
%0 = load i64, i64* %val, align 8
ret void
}
declare dso_local void @foo(...)
$ llc -march=mips64 -relocation-model=static -mattr noabicalls < test.ll
bar1:
...
lui $1, %highest(foo) # load highest 16-bits of address, shift
and store
daddiu $1, $1, %higher(foo) # add next 16-bits of address
dsll $1, $1, 16 # shift result left
daddiu $1, $1, %hi(foo) # add hi 16-bits of address
dsll $1, $1, 16 # shift result left
daddiu $1, $1, %lo(foo) # add low 16-bits of address
...
bar2:
...
lui $1, 4095 # prepare 0x0FFFFFFF mask
ori $1, $1, 65535 #
lui $2, %hi(foo) # load hi 16-bits of address, shift and
store
dsll $2, $2, 16 # <<<< unnecessary instruction, bits
already shifted by `lui`
daddiu $2, $2, %lo(foo) # add low 16-bits of address
and $1, $2, $1 # apply the mask
----------
The problem is in the code optimization phase. MIPS backend creates the
following chain of commands to load 64-bit address in the
MipsTargetLowering::getAddrNonPICSym64 method:
(add (shl (add (shl (add %highest(sym), %higher(sym)),
16),
%high(sym)),
16),
%lo(%sym))
Without the mask it successfully translates to the following instructions:
lui at,0x0
R_MIPS_HIGHEST foo
daddiu at,at,0
R_MIPS_HIGHER foo
dsll at,at,0x10
daddiu at,at,0
R_MIPS_HI16 foo
dsll at,at,0x10
daddiu at,at,0
R_MIPS_LO16 foo
If the mask presents, LLVM decides to optimize the chain of commands. It really
does not make sense to load upper 32-bits because the 0x0fffffff mask anyway
clears them. So "unnecessary" commands removed and we get this chain:
(add (shl (%high(sym), 16), %lo(%sym))
As a result we get incorrect set of instructions:
lui at,0x0
R_MIPS_HI16 foo
dsll at,at,0x10
daddiu at,at,0
R_MIPS_LO16 foo
--
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/20190724/1fbf93d4/attachment-0001.html>
More information about the llvm-bugs
mailing list