[llvm] 5f23686 - [RISCV][AsmParser] Implement .option (no)pic

Roger Ferrer Ibanez via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 17 05:14:14 PDT 2020


Author: Roger Ferrer Ibanez
Date: 2020-04-17T12:08:30Z
New Revision: 5f236864124d3b6f29689b8779a1e880df970a1c

URL: https://github.com/llvm/llvm-project/commit/5f236864124d3b6f29689b8779a1e880df970a1c
DIFF: https://github.com/llvm/llvm-project/commit/5f236864124d3b6f29689b8779a1e880df970a1c.diff

LOG: [RISCV][AsmParser] Implement .option (no)pic

Differential Revision: https://reviews.llvm.org/D77867

Added: 
    llvm/test/CodeGen/RISCV/option-nopic.ll
    llvm/test/CodeGen/RISCV/option-pic.ll
    llvm/test/MC/RISCV/option-nopic.s
    llvm/test/MC/RISCV/option-pic.s

Modified: 
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
    llvm/test/MC/RISCV/option-pushpop.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 388b55a83195..0f284710f79c 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -51,9 +51,16 @@ STATISTIC(RISCVNumInstrsCompressed,
 namespace {
 struct RISCVOperand;
 
+struct ParserOptionsSet {
+  bool IsPicEnabled;
+};
+
 class RISCVAsmParser : public MCTargetAsmParser {
   SmallVector<FeatureBitset, 4> FeatureBitStack;
 
+  SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
+  ParserOptionsSet ParserOptions;
+
   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
   bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
   bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); }
@@ -170,10 +177,15 @@ class RISCVAsmParser : public MCTargetAsmParser {
   }
 
   void pushFeatureBits() {
+    assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
+           "These two stacks must be kept synchronized");
     FeatureBitStack.push_back(getSTI().getFeatureBits());
+    ParserOptionsStack.push_back(ParserOptions);
   }
 
   bool popFeatureBits() {
+    assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
+           "These two stacks must be kept synchronized");
     if (FeatureBitStack.empty())
       return true;
 
@@ -181,8 +193,11 @@ class RISCVAsmParser : public MCTargetAsmParser {
     copySTI().setFeatureBits(FeatureBits);
     setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
 
+    ParserOptions = ParserOptionsStack.pop_back_val();
+
     return false;
   }
+
 public:
   enum RISCVMatchResultTy {
     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
@@ -216,6 +231,9 @@ class RISCVAsmParser : public MCTargetAsmParser {
                 "doesn't support the D instruction set extension (ignoring "
                 "target-abi)\n";
     }
+
+    const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
+    ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
   }
 };
 
@@ -1668,6 +1686,30 @@ bool RISCVAsmParser::parseDirectiveOption() {
     return false;
   }
 
+  if (Option == "pic") {
+    getTargetStreamer().emitDirectiveOptionPIC();
+
+    Parser.Lex();
+    if (Parser.getTok().isNot(AsmToken::EndOfStatement))
+      return Error(Parser.getTok().getLoc(),
+                   "unexpected token, expected end of statement");
+
+    ParserOptions.IsPicEnabled = true;
+    return false;
+  }
+
+  if (Option == "nopic") {
+    getTargetStreamer().emitDirectiveOptionNoPIC();
+
+    Parser.Lex();
+    if (Parser.getTok().isNot(AsmToken::EndOfStatement))
+      return Error(Parser.getTok().getLoc(),
+                   "unexpected token, expected end of statement");
+
+    ParserOptions.IsPicEnabled = false;
+    return false;
+  }
+
   if (Option == "relax") {
     getTargetStreamer().emitDirectiveOptionRelax();
 
@@ -1931,8 +1973,7 @@ void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
   unsigned SecondOpcode;
   RISCVMCExpr::VariantKind VKHi;
-  // FIXME: Should check .option (no)pic when implemented
-  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
+  if (ParserOptions.IsPicEnabled) {
     SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
     VKHi = RISCVMCExpr::VK_RISCV_GOT_HI;
   } else {

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 8382edf09231..079dc919928a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -66,6 +66,8 @@ MCELFStreamer &RISCVTargetELFStreamer::getStreamer() {
 
 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}
 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}
+void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}
+void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}
 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
index 0221392054ce..392c87054d43 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
@@ -97,6 +97,8 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer {
 
   void emitDirectiveOptionPush() override;
   void emitDirectiveOptionPop() override;
+  void emitDirectiveOptionPIC() override;
+  void emitDirectiveOptionNoPIC() override;
   void emitDirectiveOptionRVC() override;
   void emitDirectiveOptionNoRVC() override;
   void emitDirectiveOptionRelax() override;

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
index b5b59c1227f6..4865d9d212fe 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
@@ -61,6 +61,14 @@ void RISCVTargetAsmStreamer::emitDirectiveOptionPop() {
   OS << "\t.option\tpop\n";
 }
 
+void RISCVTargetAsmStreamer::emitDirectiveOptionPIC() {
+  OS << "\t.option\tpic\n";
+}
+
+void RISCVTargetAsmStreamer::emitDirectiveOptionNoPIC() {
+  OS << "\t.option\tnopic\n";
+}
+
 void RISCVTargetAsmStreamer::emitDirectiveOptionRVC() {
   OS << "\t.option\trvc\n";
 }

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
index f7c8db2edb01..94b324030154 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
@@ -21,6 +21,8 @@ class RISCVTargetStreamer : public MCTargetStreamer {
 
   virtual void emitDirectiveOptionPush() = 0;
   virtual void emitDirectiveOptionPop() = 0;
+  virtual void emitDirectiveOptionPIC() = 0;
+  virtual void emitDirectiveOptionNoPIC() = 0;
   virtual void emitDirectiveOptionRVC() = 0;
   virtual void emitDirectiveOptionNoRVC() = 0;
   virtual void emitDirectiveOptionRelax() = 0;
@@ -49,6 +51,8 @@ class RISCVTargetAsmStreamer : public RISCVTargetStreamer {
 
   void emitDirectiveOptionPush() override;
   void emitDirectiveOptionPop() override;
+  void emitDirectiveOptionPIC() override;
+  void emitDirectiveOptionNoPIC() override;
   void emitDirectiveOptionRVC() override;
   void emitDirectiveOptionNoRVC() override;
   void emitDirectiveOptionRelax() override;

diff  --git a/llvm/test/CodeGen/RISCV/option-nopic.ll b/llvm/test/CodeGen/RISCV/option-nopic.ll
new file mode 100644
index 000000000000..681ace8ce64f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/option-nopic.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=riscv32 -filetype=obj --relocation-model=pic < %s\
+; RUN: | llvm-objdump --triple=riscv32 --mattr=+c -d -M no-aliases -\
+; RUN: | FileCheck -check-prefix=CHECK %s
+
+; This test demonstrates that .option nopic has no effect on codegen when
+; emitting an ELF directly.
+
+ at symbol = global i32 zeroinitializer
+
+define i32 @get_symbol() nounwind {
+; CHECK-LABEL: <get_symbol>:
+; CHECK: auipc	a0, 0
+; CHECK: lw	a0, 0(a0)
+; CHECK: lw	a0, 0(a0)
+  tail call void asm sideeffect ".option nopic", ""()
+  %v = load i32, i32* @symbol
+  ret i32 %v
+}

diff  --git a/llvm/test/CodeGen/RISCV/option-pic.ll b/llvm/test/CodeGen/RISCV/option-pic.ll
new file mode 100644
index 000000000000..0810936d7bb5
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/option-pic.ll
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=riscv32 -filetype=obj < %s\
+; RUN: | llvm-objdump --triple=riscv32 --mattr=+c -d -M no-aliases -\
+; RUN: | FileCheck -check-prefix=CHECK %s
+
+; This test demonstrates that .option pic has no effect on codegen when
+; emitting an ELF directly.
+
+ at symbol = global i32 zeroinitializer
+
+define i32 @get_symbol() nounwind {
+; CHECK-LABEL: <get_symbol>:
+; CHECK: lui	a0, 0
+; CHECK: lw	a0, 0(a0)
+  tail call void asm sideeffect ".option pic", ""()
+  %v = load i32, i32* @symbol
+  ret i32 %v
+}

diff  --git a/llvm/test/MC/RISCV/option-nopic.s b/llvm/test/MC/RISCV/option-nopic.s
new file mode 100644
index 000000000000..7673b0455619
--- /dev/null
+++ b/llvm/test/MC/RISCV/option-nopic.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc -triple riscv32 -mattr=-relax -riscv-no-aliases < %s \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv32 -mattr=-relax -riscv-no-aliases \
+# RUN:     -position-independent < %s | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -position-independent < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=-relax -riscv-no-aliases < %s \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=-relax -riscv-no-aliases \
+# RUN:     -position-independent < %s | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -position-independent < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+.option nopic
+# CHECK-INST: .option nopic
+
+la s0, symbol
+# CHECK-INST: auipc	s0, %pcrel_hi(symbol)
+# CHECK-INST: addi	s0, s0, %pcrel_lo(.Lpcrel_hi0)
+# CHECK-RELOC: R_RISCV_PCREL_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi0 0x0
+

diff  --git a/llvm/test/MC/RISCV/option-pic.s b/llvm/test/MC/RISCV/option-pic.s
new file mode 100644
index 000000000000..37d643c32483
--- /dev/null
+++ b/llvm/test/MC/RISCV/option-pic.s
@@ -0,0 +1,28 @@
+# RUN: llvm-mc -triple riscv32 -mattr=-relax -riscv-no-aliases < %s \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv32 -mattr=-relax -riscv-no-aliases \
+# RUN:     -position-independent < %s | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -position-independent < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=-relax -riscv-no-aliases < %s \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=-relax -riscv-no-aliases \
+# RUN:     -position-independent < %s | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -position-independent < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+.option pic
+# CHECK-INST: .option pic
+
+la s0, symbol
+# CHECK-INST: auipc	s0, %got_pcrel_hi(symbol)
+# CHECK-INST: l{{[wd]}}	s0, %pcrel_lo(.Lpcrel_hi0)(s0)
+# CHECK-RELOC: R_RISCV_GOT_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi0 0x0

diff  --git a/llvm/test/MC/RISCV/option-pushpop.s b/llvm/test/MC/RISCV/option-pushpop.s
index 0754a74c58a3..96101dbc6376 100644
--- a/llvm/test/MC/RISCV/option-pushpop.s
+++ b/llvm/test/MC/RISCV/option-pushpop.s
@@ -72,3 +72,45 @@ call baz
 # CHECK-BYTES: 13 04 c1 3f
 # CHECK-ALIAS: addi s0, sp, 1020
 addi s0, sp, 1020
+
+.option push    # Push pic=false
+# CHECK-INST: .option push
+
+.option pic
+# CHECK-INST: .option pic
+
+la s0, symbol
+# CHECK-INST: auipc	s0, %got_pcrel_hi(symbol)
+# CHECK-INST: l{{[wd]}}	s0, %pcrel_lo(.Lpcrel_hi0)(s0)
+# CHECK-RELOC: R_RISCV_GOT_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi0 0x0
+
+.option push    # Push pic=true
+# CHECK-INST: .option push
+
+.option nopic
+# CHECK-INST: .option nopic
+
+la s0, symbol
+# CHECK-INST: auipc	s0, %pcrel_hi(symbol)
+# CHECK-INST: addi	s0, s0, %pcrel_lo(.Lpcrel_hi1)
+# CHECK-RELOC: R_RISCV_PCREL_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi1 0x0
+
+.option pop    # Push pic=true
+# CHECK-INST: .option pop
+
+la s0, symbol
+# CHECK-INST: auipc	s0, %got_pcrel_hi(symbol)
+# CHECK-INST: l{{[wd]}}	s0, %pcrel_lo(.Lpcrel_hi2)(s0)
+# CHECK-RELOC: R_RISCV_GOT_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi2 0x0
+
+.option pop    # Push pic=false
+# CHECK-INST: .option pop
+
+la s0, symbol
+# CHECK-INST: auipc	s0, %pcrel_hi(symbol)
+# CHECK-INST: addi	s0, s0, %pcrel_lo(.Lpcrel_hi3)
+# CHECK-RELOC: R_RISCV_PCREL_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi3 0x0


        


More information about the llvm-commits mailing list