[llvm] r367580 - [mips] Fix lowering load/store instruction in PIC case
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 22 08:51:26 PDT 2019
Merged to release_90 in r369663.
On Thu, Aug 1, 2019 at 6:03 PM Simon Atanasyan via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: atanasyan
> Date: Thu Aug 1 09:04:29 2019
> New Revision: 367580
>
> URL: http://llvm.org/viewvc/llvm-project?rev=367580&view=rev
> Log:
> [mips] Fix lowering load/store instruction in PIC case
>
> If an operand of the `lw/sw` instructions is a symbol, these instructions
> incorrectly lowered using not-position-independent chain of commands.
> For PIC code we should use `lw/addiu` instructions with the `R_MIPS_GOT16`
> and `R_MIPS_LO16` relocations respectively. Instead of that LLVM generates
> position dependent code with the `R_MIPS_HI16` and `R_MIPS_LO16`
> relocations.
>
> This patch provides a fix for the bug by handling PIC case separately in
> the `MipsAsmParser::expandMemInst`. The main idea is to generate a chain
> of PIC instructions to load a symbol address into a register and then
> load the address content.
>
> The fix is not optimal and does not fix all PIC-related problems. This
> is a task for subsequent patches.
>
> Differential Revision: https://reviews.llvm.org/D65524
>
> Modified:
> llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
> llvm/trunk/test/MC/Mips/mips-expansions.s
> llvm/trunk/test/MC/Mips/mips64-expansions.s
>
> Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=367580&r1=367579&r2=367580&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Thu Aug 1 09:04:29 2019
> @@ -3625,8 +3625,25 @@ void MipsAsmParser::expandMemInst(MCInst
> TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
> BaseReg, IDLoc, STI);
> TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
> + return;
> + }
> +
> + assert(OffsetOp.isExpr() && "expected expression operand kind");
> + if (inPicMode()) {
> + // FIXME:
> + // a) Fix lw/sw $reg, symbol($reg) instruction expanding.
> + // b) If expression includes offset (sym + number), do not
> + // encode the offset into a relocation. Take it in account
> + // in the last load/store instruction.
> + // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
> + // do not exceed 16-bit.
> + // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
> + // of R_MIPS_GOT_DISP in appropriate cases to reduce number
> + // of GOT entries.
> + expandLoadAddress(TmpReg, Mips::NoRegister, OffsetOp, !ABI.ArePtrs64bit(),
> + IDLoc, Out, STI);
> + TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, 0, IDLoc, STI);
> } else {
> - assert(OffsetOp.isExpr() && "expected expression operand kind");
> const MCExpr *ExprOffset = OffsetOp.getExpr();
> MCOperand LoOperand = MCOperand::createExpr(
> MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
>
> Modified: llvm/trunk/test/MC/Mips/mips-expansions.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips-expansions.s?rev=367580&r1=367579&r2=367580&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Mips/mips-expansions.s (original)
> +++ llvm/trunk/test/MC/Mips/mips-expansions.s Thu Aug 1 09:04:29 2019
> @@ -50,6 +50,7 @@
> # CHECK-LE: lhu $4, 4($4)
>
> # LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst():
> +# NON-PIC code
> .set noat
> lw $10, symbol($4)
> # CHECK-LE: lui $10, %hi(symbol) # encoding: [A,A,0x0a,0x3c]
> @@ -105,6 +106,64 @@
> # CHECK-LE: lui $1, %hi(symbol)
> # CHECK-LE: sdc1 $f0, %lo(symbol)($1)
>
> +# PIC code
> + .option pic2
> + .set noat
> + lw $10, symbol($4)
> +# CHECK-LE: lw $10, %got(symbol)($gp) # encoding: [A,A,0x8a,0x8f]
> +# CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
> +# CHECK-LE-FIXME: addu $10, $10, $4 # encoding: [0x21,0x50,0x44,0x01]
> +# CHECK-LE: lw $10, 0($10) # encoding: [0x00,0x00,0x4a,0x8d]
> + .set at
> + sw $10, symbol($9)
> +# CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]
> +# CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
> +# CHECK-LE-FIXME: addu $1, $1, $9 # encoding: [0x21,0x08,0x29,0x00]
> +# CHECK-LE: sw $10, 0($1) # encoding: [0x00,0x00,0x2a,0xac]
> +
> + lw $8, 1f+8
> +# CHECK-LE: lw $8, %got(($tmp0)+8)($gp) # encoding: [A,A,0x88,0x8f]
> +# CHECK-LE: # fixup A - offset: 0, value: %got(($tmp0)+8), kind: fixup_Mips_GOT
> +# CHECK-LE: addiu $8, $8, %lo(($tmp0)+8) # encoding: [A,A,0x08,0x25]
> +# CHECK-LE: # fixup A - offset: 0, value: %lo(($tmp0)+8), kind: fixup_Mips_LO16
> +# CHECK-LE: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
> + sw $8, 1f+8
> +# CHECK-LE: lw $1, %got(($tmp0)+8)($gp) # encoding: [A,A,0x81,0x8f]
> +# CHECK-LE: # fixup A - offset: 0, value: %got(($tmp0)+8), kind: fixup_Mips_GOT
> +# CHECK-LE: addiu $1, $1, %lo(($tmp0)+8) # encoding: [A,A,0x21,0x24]
> +# CHECK-LE: # fixup A - offset: 0, value: %lo(($tmp0)+8), kind: fixup_Mips_LO16
> +# CHECK-LE: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
> +
> + lw $10, 655483($4)
> +# CHECK-LE: lui $10, 10 # encoding: [0x0a,0x00,0x0a,0x3c]
> +# CHECK-LE: addu $10, $10, $4 # encoding: [0x21,0x50,0x44,0x01]
> +# CHECK-LE: lw $10, 123($10) # encoding: [0x7b,0x00,0x4a,0x8d]
> + sw $10, 123456($9)
> +# CHECK-LE: lui $1, 2 # encoding: [0x02,0x00,0x01,0x3c]
> +# CHECK-LE: addu $1, $1, $9 # encoding: [0x21,0x08,0x29,0x00]
> +# CHECK-LE: sw $10, -7616($1) # encoding: [0x40,0xe2,0x2a,0xac]
> +
> + lw $8, symbol+8
> +# CHECK-LE: lw $8, %got(symbol+8)($gp) # encoding: [A,A,0x88,0x8f]
> +# CHECK-LE: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
> +# CHECK-LE: addiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x25]
> +# CHECK-LE: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
> + sw $8, symbol+8
> +# CHECK-LE: lw $1, %got(symbol+8)($gp) # encoding: [A,A,0x81,0x8f]
> +# CHECK-LE: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
> +# CHECK-LE: addiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x24]
> +# CHECK-LE: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
> +
> + ldc1 $f0, symbol
> +# CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]
> +# CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
> +# CHECK-LE: ldc1 $f0, 0($1) # encoding: [0x00,0x00,0x20,0xd4]
> + sdc1 $f0, symbol
> +# CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]
> +# CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
> +# CHECK-LE: sdc1 $f0, 0($1) # encoding: [0x00,0x00,0x20,0xf4]
> + .option pic0
> +
> # Test BNE with an immediate as the 2nd operand.
> bne $2, 0, 1332
> # CHECK-LE: bnez $2, 1332 # encoding: [0x4d,0x01,0x40,0x14]
>
> Modified: llvm/trunk/test/MC/Mips/mips64-expansions.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips64-expansions.s?rev=367580&r1=367579&r2=367580&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/Mips/mips64-expansions.s (original)
> +++ llvm/trunk/test/MC/Mips/mips64-expansions.s Thu Aug 1 09:04:29 2019
> @@ -466,3 +466,56 @@ sym:
> # CHECK-NEXT: dsll $4, $4, 16
> # CHECK-NEXT: daddu $4, $4, $3
> # CHECK-NEXT: lhu $4, -32764($4)
> +
> +# LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst():
> + .option pic2
> + lw $10, symbol($4)
> +# CHECK: ld $10, %got_disp(symbol)($gp) # encoding: [A,A,0x8a,0xdf]
> +# CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
> +# CHECK-FIXME: daddu $10, $10, $4 # encoding: [0x2d,0x50,0x44,0x01]
> +# CHECK: lw $10, 0($10) # encoding: [0x00,0x00,0x4a,0x8d]
> + sw $10, symbol($9)
> +# CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
> +# CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
> +# CHECK-FIXME: daddu $1, $1, $9 # encoding: [0x2d,0x08,0x29,0x00]
> +# CHECK: sw $10, 0($1) # encoding: [0x00,0x00,0x2a,0xac]
> +
> + lw $8, sym+8
> +# CHECK: ld $8, %got_disp(sym)($gp) # encoding: [A,A,0x88,0xdf]
> +# CHECK: # fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
> +# CHECK: daddiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x65]
> +# CHECK: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
> + sw $8, sym+8
> +# CHECK: ld $1, %got_disp(sym)($gp) # encoding: [A,A,0x81,0xdf]
> +# CHECK: # fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
> +# CHECK: daddiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x64]
> +# CHECK: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
> +
> + lw $10, 655483($4)
> +# CHECK: lui $10, 10 # encoding: [0x0a,0x00,0x0a,0x3c]
> +# CHECK: daddu $10, $10, $4 # encoding: [0x2d,0x50,0x44,0x01]
> +# CHECK: lw $10, 123($10) # encoding: [0x7b,0x00,0x4a,0x8d]
> + sw $10, 123456($9)
> +# CHECK: lui $1, 2 # encoding: [0x02,0x00,0x01,0x3c]
> +# CHECK: daddu $1, $1, $9 # encoding: [0x2d,0x08,0x29,0x00]
> +# CHECK: sw $10, -7616($1) # encoding: [0x40,0xe2,0x2a,0xac]
> +
> + lw $8, symbol+8
> +# CHECK: ld $8, %got_disp(symbol)($gp) # encoding: [A,A,0x88,0xdf]
> +# CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
> +# CHECK: daddiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x65]
> +# CHECK: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
> + sw $8, symbol+8
> +# CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
> +# CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
> +# CHECK: daddiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x64]
> +# CHECK: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
> +
> + ldc1 $f0, symbol
> +# CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
> +# CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
> +# CHECK: ldc1 $f0, 0($1) # encoding: [0x00,0x00,0x20,0xd4]
> + sdc1 $f0, symbol
> +# CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
> +# CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
> +# CHECK: sdc1 $f0, 0($1) # encoding: [0x00,0x00,0x20,0xf4]
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list