Skip to content

Commit a524036

Browse files
committedJun 11, 2019
[RISCV] Add lowering of addressing sequences for PIC
This patch allows lowering of PIC addresses by using PC-relative addressing for DSO-local symbols and accessing the address through the global offset table for non-DSO-local symbols. Differential Revision: https://reviews.llvm.org/D55303 llvm-svn: 363058
1 parent 6970755 commit a524036

File tree

7 files changed

+149
-16
lines changed

7 files changed

+149
-16
lines changed
 

‎llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp

+39-4
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,16 @@ class RISCVExpandPseudo : public MachineFunctionPass {
5454
bool expandAtomicCmpXchg(MachineBasicBlock &MBB,
5555
MachineBasicBlock::iterator MBBI, bool IsMasked,
5656
int Width, MachineBasicBlock::iterator &NextMBBI);
57+
bool expandAuipcInstPair(MachineBasicBlock &MBB,
58+
MachineBasicBlock::iterator MBBI,
59+
MachineBasicBlock::iterator &NextMBBI,
60+
unsigned FlagsHi, unsigned SecondOpcode);
5761
bool expandLoadLocalAddress(MachineBasicBlock &MBB,
5862
MachineBasicBlock::iterator MBBI,
5963
MachineBasicBlock::iterator &NextMBBI);
64+
bool expandLoadAddress(MachineBasicBlock &MBB,
65+
MachineBasicBlock::iterator MBBI,
66+
MachineBasicBlock::iterator &NextMBBI);
6067
};
6168

6269
char RISCVExpandPseudo::ID = 0;
@@ -122,6 +129,8 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
122129
return expandAtomicCmpXchg(MBB, MBBI, true, 32, NextMBBI);
123130
case RISCV::PseudoLLA:
124131
return expandLoadLocalAddress(MBB, MBBI, NextMBBI);
132+
case RISCV::PseudoLA:
133+
return expandLoadAddress(MBB, MBBI, NextMBBI);
125134
}
126135

127136
return false;
@@ -602,9 +611,10 @@ bool RISCVExpandPseudo::expandAtomicCmpXchg(
602611
return true;
603612
}
604613

605-
bool RISCVExpandPseudo::expandLoadLocalAddress(
614+
bool RISCVExpandPseudo::expandAuipcInstPair(
606615
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
607-
MachineBasicBlock::iterator &NextMBBI) {
616+
MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi,
617+
unsigned SecondOpcode) {
608618
MachineFunction *MF = MBB.getParent();
609619
MachineInstr &MI = *MBBI;
610620
DebugLoc DL = MI.getDebugLoc();
@@ -621,8 +631,8 @@ bool RISCVExpandPseudo::expandLoadLocalAddress(
621631
MF->insert(++MBB.getIterator(), NewMBB);
622632

623633
BuildMI(NewMBB, DL, TII->get(RISCV::AUIPC), DestReg)
624-
.addDisp(Symbol, 0, RISCVII::MO_PCREL_HI);
625-
BuildMI(NewMBB, DL, TII->get(RISCV::ADDI), DestReg)
634+
.addDisp(Symbol, 0, FlagsHi);
635+
BuildMI(NewMBB, DL, TII->get(SecondOpcode), DestReg)
626636
.addReg(DestReg)
627637
.addMBB(NewMBB, RISCVII::MO_PCREL_LO);
628638

@@ -642,6 +652,31 @@ bool RISCVExpandPseudo::expandLoadLocalAddress(
642652
return true;
643653
}
644654

655+
bool RISCVExpandPseudo::expandLoadLocalAddress(
656+
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
657+
MachineBasicBlock::iterator &NextMBBI) {
658+
return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI,
659+
RISCV::ADDI);
660+
}
661+
662+
bool RISCVExpandPseudo::expandLoadAddress(
663+
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
664+
MachineBasicBlock::iterator &NextMBBI) {
665+
MachineFunction *MF = MBB.getParent();
666+
667+
unsigned SecondOpcode;
668+
unsigned FlagsHi;
669+
if (MF->getTarget().isPositionIndependent()) {
670+
const auto &STI = MF->getSubtarget<RISCVSubtarget>();
671+
SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW;
672+
FlagsHi = RISCVII::MO_GOT_HI;
673+
} else {
674+
SecondOpcode = RISCV::ADDI;
675+
FlagsHi = RISCVII::MO_PCREL_HI;
676+
}
677+
return expandAuipcInstPair(MBB, MBBI, NextMBBI, FlagsHi, SecondOpcode);
678+
}
679+
645680
} // end of anonymous namespace
646681

647682
INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo",

‎llvm/lib/Target/RISCV/RISCVISelLowering.cpp

+19-11
Original file line numberDiff line numberDiff line change
@@ -403,10 +403,25 @@ static SDValue getTargetNode(ConstantPoolSDNode *N, SDLoc DL, EVT Ty,
403403
}
404404

405405
template <class NodeTy>
406-
SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG) const {
406+
SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
407+
bool IsLocal) const {
407408
SDLoc DL(N);
408409
EVT Ty = getPointerTy(DAG.getDataLayout());
409410

411+
if (isPositionIndependent()) {
412+
SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
413+
if (IsLocal)
414+
// Use PC-relative addressing to access the symbol. This generates the
415+
// pattern (PseudoLLA sym), which expands to (addi (auipc %pcrel_hi(sym))
416+
// %pcrel_lo(auipc)).
417+
return SDValue(DAG.getMachineNode(RISCV::PseudoLLA, DL, Ty, Addr), 0);
418+
419+
// Use PC-relative addressing to access the GOT for this symbol, then load
420+
// the address from the GOT. This generates the pattern (PseudoLA sym),
421+
// which expands to (ld (addi (auipc %got_pcrel_hi(sym)) %pcrel_lo(auipc))).
422+
return SDValue(DAG.getMachineNode(RISCV::PseudoLA, DL, Ty, Addr), 0);
423+
}
424+
410425
switch (getTargetMachine().getCodeModel()) {
411426
default:
412427
report_fatal_error("Unsupported code model for lowering");
@@ -436,10 +451,9 @@ SDValue RISCVTargetLowering::lowerGlobalAddress(SDValue Op,
436451
int64_t Offset = N->getOffset();
437452
MVT XLenVT = Subtarget.getXLenVT();
438453

439-
if (isPositionIndependent())
440-
report_fatal_error("Unable to lowerGlobalAddress");
441-
442-
SDValue Addr = getAddr(N, DAG);
454+
const GlobalValue *GV = N->getGlobal();
455+
bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV);
456+
SDValue Addr = getAddr(N, DAG, IsLocal);
443457

444458
// In order to maximise the opportunity for common subexpression elimination,
445459
// emit a separate ADD node for the global address offset instead of folding
@@ -455,19 +469,13 @@ SDValue RISCVTargetLowering::lowerBlockAddress(SDValue Op,
455469
SelectionDAG &DAG) const {
456470
BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
457471

458-
if (isPositionIndependent())
459-
report_fatal_error("Unable to lowerBlockAddress");
460-
461472
return getAddr(N, DAG);
462473
}
463474

464475
SDValue RISCVTargetLowering::lowerConstantPool(SDValue Op,
465476
SelectionDAG &DAG) const {
466477
ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
467478

468-
if (isPositionIndependent())
469-
report_fatal_error("Unable to lowerConstantPool");
470-
471479
return getAddr(N, DAG);
472480
}
473481

‎llvm/lib/Target/RISCV/RISCVISelLowering.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class RISCVTargetLowering : public TargetLowering {
155155
}
156156

157157
template <class NodeTy>
158-
SDValue getAddr(NodeTy *N, SelectionDAG &DAG) const;
158+
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const;
159159

160160
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
161161
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;

‎llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
439439
case RISCV::PseudoCALL:
440440
case RISCV::PseudoTAIL:
441441
case RISCV::PseudoLLA:
442+
case RISCV::PseudoLA:
442443
return 8;
443444
case TargetOpcode::INLINEASM:
444445
case TargetOpcode::INLINEASM_BR: {

‎llvm/lib/Target/RISCV/RISCVMCInstLower.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
5151
case RISCVII::MO_PCREL_HI:
5252
Kind = RISCVMCExpr::VK_RISCV_PCREL_HI;
5353
break;
54+
case RISCVII::MO_GOT_HI:
55+
Kind = RISCVMCExpr::VK_RISCV_GOT_HI;
56+
break;
5457
}
5558

5659
const MCExpr *ME =

‎llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ enum {
5353
MO_HI,
5454
MO_PCREL_LO,
5555
MO_PCREL_HI,
56+
MO_GOT_HI,
5657
};
5758
} // namespace RISCVII
5859

‎llvm/test/CodeGen/RISCV/pic-models.ll

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -relocation-model=static < %s \
3+
; RUN: | FileCheck -check-prefix=RV32-STATIC %s
4+
; RUN: llc -mtriple=riscv32 -relocation-model=pic < %s \
5+
; RUN: | FileCheck -check-prefix=RV32-PIC %s
6+
; RUN: llc -mtriple=riscv64 -relocation-model=static < %s \
7+
; RUN: | FileCheck -check-prefix=RV64-STATIC %s
8+
; RUN: llc -mtriple=riscv64 -relocation-model=pic < %s \
9+
; RUN: | FileCheck -check-prefix=RV64-PIC %s
10+
11+
; Check basic lowering of PIC addressing.
12+
; TODO: Check other relocation models?
13+
14+
@external_var = external global i32
15+
@internal_var = internal global i32 42
16+
17+
18+
; external address
19+
20+
define i32* @f1() nounwind {
21+
; RV32-STATIC-LABEL: f1:
22+
; RV32-STATIC: # %bb.0: # %entry
23+
; RV32-STATIC-NEXT: lui a0, %hi(external_var)
24+
; RV32-STATIC-NEXT: addi a0, a0, %lo(external_var)
25+
; RV32-STATIC-NEXT: ret
26+
;
27+
; RV32-PIC-LABEL: f1:
28+
; RV32-PIC: # %bb.0: # %entry
29+
; RV32-PIC-NEXT: .LBB0_1: # %entry
30+
; RV32-PIC-NEXT: # Label of block must be emitted
31+
; RV32-PIC-NEXT: auipc a0, %got_pcrel_hi(external_var)
32+
; RV32-PIC-NEXT: lw a0, %pcrel_lo(.LBB0_1)(a0)
33+
; RV32-PIC-NEXT: ret
34+
;
35+
; RV64-STATIC-LABEL: f1:
36+
; RV64-STATIC: # %bb.0: # %entry
37+
; RV64-STATIC-NEXT: lui a0, %hi(external_var)
38+
; RV64-STATIC-NEXT: addi a0, a0, %lo(external_var)
39+
; RV64-STATIC-NEXT: ret
40+
;
41+
; RV64-PIC-LABEL: f1:
42+
; RV64-PIC: # %bb.0: # %entry
43+
; RV64-PIC-NEXT: .LBB0_1: # %entry
44+
; RV64-PIC-NEXT: # Label of block must be emitted
45+
; RV64-PIC-NEXT: auipc a0, %got_pcrel_hi(external_var)
46+
; RV64-PIC-NEXT: ld a0, %pcrel_lo(.LBB0_1)(a0)
47+
; RV64-PIC-NEXT: ret
48+
entry:
49+
ret i32* @external_var
50+
}
51+
52+
53+
; internal address
54+
55+
define i32* @f2() nounwind {
56+
; RV32-STATIC-LABEL: f2:
57+
; RV32-STATIC: # %bb.0: # %entry
58+
; RV32-STATIC-NEXT: lui a0, %hi(internal_var)
59+
; RV32-STATIC-NEXT: addi a0, a0, %lo(internal_var)
60+
; RV32-STATIC-NEXT: ret
61+
;
62+
; RV32-PIC-LABEL: f2:
63+
; RV32-PIC: # %bb.0: # %entry
64+
; RV32-PIC-NEXT: .LBB1_1: # %entry
65+
; RV32-PIC-NEXT: # Label of block must be emitted
66+
; RV32-PIC-NEXT: auipc a0, %pcrel_hi(internal_var)
67+
; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB1_1)
68+
; RV32-PIC-NEXT: ret
69+
;
70+
; RV64-STATIC-LABEL: f2:
71+
; RV64-STATIC: # %bb.0: # %entry
72+
; RV64-STATIC-NEXT: lui a0, %hi(internal_var)
73+
; RV64-STATIC-NEXT: addi a0, a0, %lo(internal_var)
74+
; RV64-STATIC-NEXT: ret
75+
;
76+
; RV64-PIC-LABEL: f2:
77+
; RV64-PIC: # %bb.0: # %entry
78+
; RV64-PIC-NEXT: .LBB1_1: # %entry
79+
; RV64-PIC-NEXT: # Label of block must be emitted
80+
; RV64-PIC-NEXT: auipc a0, %pcrel_hi(internal_var)
81+
; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB1_1)
82+
; RV64-PIC-NEXT: ret
83+
entry:
84+
ret i32* @internal_var
85+
}

0 commit comments

Comments
 (0)
Please sign in to comment.