This is an archive of the discontinued LLVM Phabricator instance.

[mips] Check lb / lbu offset range in the expandLoadInst routine
AbandonedPublic

Authored by atanasyan on Apr 25 2018, 10:57 PM.

Details

Reviewers
sdardis
Summary

lb and lbu commands accepts 16-bit signed offsets. But GAS accepts larger offsets for these commands. If an offset does not fit in 16-bit range, lb command is translated into lui/lb or lui/addu/lb series. It's interesting that initially LLVM assembler supported this feature, but later it was broken.

This patch restores support for 32-bit offsets. It replaces mem_simm16 operand for LB and LBu definitions by the mem operand and checks the offset's range in the MipsAsmParser::expandLoadInst routine.

Some issues remain:

  • If lb / lbu instructions use out-of-range offset, assembler shows an error. But in the MipsAsmParser::expandLoadInst routine assembler does not know about position of invalid instruction's operand and uses beginning of a whole instruction as a point of error. There is an alternative patch D45020 which uses another approach for the range checking and shows a place of the error more precisely.
  • The regression also affects LD, SD, LH, LHU commands. I'm going to fix them by a separate patch.
  • GAS accepts any 32-bit values as an offset. Now LLVM accepts signed 16-bit values and this patch extends the range to signed 32-bit offsets. In other words, the following code accepted by GAS and still triggers an error by LLVM:
lb      $4, 0x80000004

# gas
lui     a0, 0x8000
lb      a0, 4(a0)
  • In case of 64-bit pointers GAS accepts a 64-bit offset and translates it to the li/dsll/lb series of commands. LLVM still rejects it. Probably this feature has never been implemented in LVVM. This issue is for a separate patch.
lb      $4, 0x800000001

# gas
li      a0, 0x8000
dsll    a0, a0, 0x14
lb      a0, 4(a0)

Diff Detail

Repository
rL LLVM