[llvm] r346655 - [RISCV] Support .option relax and .option norelax

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 12 06:25:07 PST 2018


Author: asb
Date: Mon Nov 12 06:25:07 2018
New Revision: 346655

URL: http://llvm.org/viewvc/llvm-project?rev=346655&view=rev
Log:
[RISCV] Support .option relax and .option norelax

This extends the .option support from D45864 to enable/disable the relax 
feature flag from D44886

During parsing of the relax/norelax directives, the RISCV::FeatureRelax 
feature bits of the SubtargetInfo stored in the AsmParser are updated 
appropriately to reflect whether relaxation is currently enabled in the 
parser. When an instruction is parsed, the parser checks if relaxation is 
currently enabled and if so, gets a handle to the AsmBackend and sets the 
ForceRelocs flag. The AsmBackend uses a combination of the original 
RISCV::FeatureRelax feature bits set by e.g -mattr=+/-relax and the 
ForceRelocs flag to determine whether to emit relocations for symbol and 
branch diffs. Diff relocations should therefore only not be emitted if the 
relax flag was not set on the command line and no instruction was ever parsed 
in a section with relaxation enabled to ensure correct diffs are emitted.

Differential Revision: https://reviews.llvm.org/D46423
Patch by Lewis Revill.

Added:
    llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
    llvm/trunk/test/CodeGen/RISCV/fixups-relax-diff.ll
    llvm/trunk/test/CodeGen/RISCV/option-norelax.ll
    llvm/trunk/test/CodeGen/RISCV/option-relax.ll
    llvm/trunk/test/MC/RISCV/option-relax.s
Modified:
    llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
    llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
    llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
    llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
    llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
    llvm/trunk/test/MC/RISCV/option-invalid.s

Modified: llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp?rev=346655&r1=346654&r2=346655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp Mon Nov 12 06:25:07 2018
@@ -7,12 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "MCTargetDesc/RISCVAsmBackend.h"
 #include "MCTargetDesc/RISCVMCExpr.h"
 #include "MCTargetDesc/RISCVMCTargetDesc.h"
 #include "MCTargetDesc/RISCVTargetStreamer.h"
 #include "Utils/RISCVBaseInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
@@ -1164,6 +1166,21 @@ bool RISCVAsmParser::parseOperand(Operan
 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
                                       StringRef Name, SMLoc NameLoc,
                                       OperandVector &Operands) {
+  // Ensure that if the instruction occurs when relaxation is enabled,
+  // relocations are forced for the file. Ideally this would be done when there
+  // is enough information to reliably determine if the instruction itself may
+  // cause relaxations. Unfortunately instruction processing stage occurs in the
+  // same pass as relocation emission, so it's too late to set a 'sticky bit'
+  // for the entire file.
+  if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
+    auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
+    if (Assembler != nullptr) {
+      RISCVAsmBackend &MAB =
+          static_cast<RISCVAsmBackend &>(Assembler->getBackend());
+      MAB.setForceRelocs();
+    }
+  }
+
   // First operand is token for instruction
   Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
 
@@ -1291,9 +1308,33 @@ bool RISCVAsmParser::parseDirectiveOptio
     return false;
   }
 
+  if (Option == "relax") {
+    getTargetStreamer().emitDirectiveOptionRelax();
+
+    Parser.Lex();
+    if (Parser.getTok().isNot(AsmToken::EndOfStatement))
+      return Error(Parser.getTok().getLoc(),
+                   "unexpected token, expected end of statement");
+
+    setFeatureBits(RISCV::FeatureRelax, "relax");
+    return false;
+  }
+
+  if (Option == "norelax") {
+    getTargetStreamer().emitDirectiveOptionNoRelax();
+
+    Parser.Lex();
+    if (Parser.getTok().isNot(AsmToken::EndOfStatement))
+      return Error(Parser.getTok().getLoc(),
+                   "unexpected token, expected end of statement");
+
+    clearFeatureBits(RISCV::FeatureRelax, "relax");
+    return false;
+  }
+
   // Unknown option.
   Warning(Parser.getTok().getLoc(),
-          "unknown option, expected 'rvc' or 'norvc'");
+          "unknown option, expected 'rvc', 'norvc', 'relax' or 'norelax'");
   Parser.eatToEndOfStatement();
   return false;
 }

Modified: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp?rev=346655&r1=346654&r2=346655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp Mon Nov 12 06:25:07 2018
@@ -7,115 +7,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "MCTargetDesc/RISCVFixupKinds.h"
-#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "RISCVAsmBackend.h"
 #include "llvm/ADT/APInt.h"
-#include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCDirectives.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCFixupKindInfo.h"
 #include "llvm/MC/MCObjectWriter.h"
-#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
-namespace {
-class RISCVAsmBackend : public MCAsmBackend {
-  const MCSubtargetInfo &STI;
-  uint8_t OSABI;
-  bool Is64Bit;
-
-public:
-  RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit)
-      : MCAsmBackend(support::little), STI(STI), OSABI(OSABI),
-        Is64Bit(Is64Bit) {}
-  ~RISCVAsmBackend() override {}
-
-  // Generate diff expression relocations if the relax feature is enabled,
-  // otherwise it is safe for the assembler to calculate these internally.
-  bool requiresDiffExpressionRelocations() const override {
-    return STI.getFeatureBits()[RISCV::FeatureRelax];
-  }
-  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
-                  const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsResolved,
-                  const MCSubtargetInfo *STI) const override;
-
-  std::unique_ptr<MCObjectTargetWriter>
-  createObjectTargetWriter() const override;
-
-  // If linker relaxation is enabled, always emit relocations even if the fixup
-  // can be resolved. This is necessary for correctness as offsets may change
-  // during relaxation.
-  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
-                             const MCValue &Target) override {
-    return STI.getFeatureBits()[RISCV::FeatureRelax];
-  }
-
-  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
-                            const MCRelaxableFragment *DF,
-                            const MCAsmLayout &Layout) const override {
-    llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
-  }
-
-  bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
-                                    uint64_t Value,
-                                    const MCRelaxableFragment *DF,
-                                    const MCAsmLayout &Layout,
-                                    const bool WasForced) const override;
-
-  unsigned getNumFixupKinds() const override {
-    return RISCV::NumTargetFixupKinds;
-  }
-
-  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
-    const static MCFixupKindInfo Infos[] = {
-      // This table *must* be in the order that the fixup_* kinds are defined in
-      // RISCVFixupKinds.h.
-      //
-      // name                      offset bits  flags
-      { "fixup_riscv_hi20",         12,     20,  0 },
-      { "fixup_riscv_lo12_i",       20,     12,  0 },
-      { "fixup_riscv_lo12_s",        0,     32,  0 },
-      { "fixup_riscv_pcrel_hi20",   12,     20,  MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_riscv_pcrel_lo12_i", 20,     12,  MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_riscv_pcrel_lo12_s",  0,     32,  MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_riscv_jal",          12,     20,  MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_riscv_branch",        0,     32,  MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_riscv_rvc_jump",      2,     11,  MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_riscv_rvc_branch",    0,     16,  MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_riscv_call",          0,     64,  MCFixupKindInfo::FKF_IsPCRel },
-      { "fixup_riscv_relax",         0,      0,  0 }
-    };
-    static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds,
-                  "Not all fixup kinds added to Infos array");
-
-    if (Kind < FirstTargetFixupKind)
-      return MCAsmBackend::getFixupKindInfo(Kind);
-
-    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
-           "Invalid kind!");
-    return Infos[Kind - FirstTargetFixupKind];
-  }
-
-  bool mayNeedRelaxation(const MCInst &Inst,
-                         const MCSubtargetInfo &STI) const override;
-  unsigned getRelaxedOpcode(unsigned Op) const;
-
-  void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
-                        MCInst &Res) const override;
-
-
-  bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
-};
-
-
 bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
                                                    bool Resolved,
                                                    uint64_t Value,
@@ -348,8 +253,6 @@ RISCVAsmBackend::createObjectTargetWrite
   return createRISCVELFObjectWriter(OSABI, Is64Bit);
 }
 
-} // end anonymous namespace
-
 MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
                                           const MCSubtargetInfo &STI,
                                           const MCRegisterInfo &MRI,

Added: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h?rev=346655&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h (added)
+++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h Mon Nov 12 06:25:07 2018
@@ -0,0 +1,118 @@
+//===-- RISCVAsmBackend.h - RISCV Assembler Backend -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
+#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
+
+#include "MCTargetDesc/RISCVFixupKinds.h"
+#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+
+namespace llvm {
+class MCAssembler;
+class MCObjectTargetWriter;
+class raw_ostream;
+
+class RISCVAsmBackend : public MCAsmBackend {
+  const MCSubtargetInfo &STI;
+  uint8_t OSABI;
+  bool Is64Bit;
+  bool ForceRelocs = false;
+
+public:
+  RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit)
+      : MCAsmBackend(support::little), STI(STI), OSABI(OSABI),
+        Is64Bit(Is64Bit) {}
+  ~RISCVAsmBackend() override {}
+
+  void setForceRelocs() { ForceRelocs = true; }
+
+  // Generate diff expression relocations if the relax feature is enabled or had
+  // previously been enabled, otherwise it is safe for the assembler to
+  // calculate these internally.
+  bool requiresDiffExpressionRelocations() const override {
+    return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs;
+  }
+  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
+                  const MCValue &Target, MutableArrayRef<char> Data,
+                  uint64_t Value, bool IsResolved,
+                  const MCSubtargetInfo *STI) const override;
+
+  std::unique_ptr<MCObjectTargetWriter>
+  createObjectTargetWriter() const override;
+
+  // If linker relaxation is enabled, or the relax option had previously been
+  // enabled, always emit relocations even if the fixup can be resolved. This is
+  // necessary for correctness as offsets may change during relaxation.
+  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
+                             const MCValue &Target) override {
+    return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs;
+  }
+
+  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
+                            const MCRelaxableFragment *DF,
+                            const MCAsmLayout &Layout) const override {
+    llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
+  }
+
+  bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
+                                    uint64_t Value,
+                                    const MCRelaxableFragment *DF,
+                                    const MCAsmLayout &Layout,
+                                    const bool WasForced) const override;
+
+  unsigned getNumFixupKinds() const override {
+    return RISCV::NumTargetFixupKinds;
+  }
+
+  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
+    const static MCFixupKindInfo Infos[] = {
+      // This table *must* be in the order that the fixup_* kinds are defined in
+      // RISCVFixupKinds.h.
+      //
+      // name                      offset bits  flags
+      { "fixup_riscv_hi20",         12,     20,  0 },
+      { "fixup_riscv_lo12_i",       20,     12,  0 },
+      { "fixup_riscv_lo12_s",        0,     32,  0 },
+      { "fixup_riscv_pcrel_hi20",   12,     20,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_riscv_pcrel_lo12_i", 20,     12,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_riscv_pcrel_lo12_s",  0,     32,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_riscv_jal",          12,     20,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_riscv_branch",        0,     32,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_riscv_rvc_jump",      2,     11,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_riscv_rvc_branch",    0,     16,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_riscv_call",          0,     64,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_riscv_relax",         0,      0,  0 }
+    };
+    static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds,
+                  "Not all fixup kinds added to Infos array");
+
+    if (Kind < FirstTargetFixupKind)
+      return MCAsmBackend::getFixupKindInfo(Kind);
+
+    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
+           "Invalid kind!");
+    return Infos[Kind - FirstTargetFixupKind];
+  }
+
+  bool mayNeedRelaxation(const MCInst &Inst,
+                         const MCSubtargetInfo &STI) const override;
+  unsigned getRelaxedOpcode(unsigned Op) const;
+
+  void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
+                        MCInst &Res) const override;
+
+
+  bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
+};
+}
+
+#endif

Modified: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp?rev=346655&r1=346654&r2=346655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp Mon Nov 12 06:25:07 2018
@@ -40,3 +40,5 @@ MCELFStreamer &RISCVTargetELFStreamer::g
 
 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
+void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
+void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}

Modified: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h?rev=346655&r1=346654&r2=346655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h (original)
+++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h Mon Nov 12 06:25:07 2018
@@ -22,6 +22,8 @@ public:
 
   virtual void emitDirectiveOptionRVC();
   virtual void emitDirectiveOptionNoRVC();
+  virtual void emitDirectiveOptionRelax();
+  virtual void emitDirectiveOptionNoRelax();
 };
 }
 #endif

Modified: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp?rev=346655&r1=346654&r2=346655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp Mon Nov 12 06:25:07 2018
@@ -30,3 +30,11 @@ void RISCVTargetAsmStreamer::emitDirecti
 void RISCVTargetAsmStreamer::emitDirectiveOptionNoRVC() {
   OS << "\t.option\tnorvc\n";
 }
+
+void RISCVTargetAsmStreamer::emitDirectiveOptionRelax() {
+  OS << "\t.option\trelax\n";
+}
+
+void RISCVTargetAsmStreamer::emitDirectiveOptionNoRelax() {
+  OS << "\t.option\tnorelax\n";
+}

Modified: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h?rev=346655&r1=346654&r2=346655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h (original)
+++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h Mon Nov 12 06:25:07 2018
@@ -20,6 +20,8 @@ public:
 
   virtual void emitDirectiveOptionRVC() = 0;
   virtual void emitDirectiveOptionNoRVC() = 0;
+  virtual void emitDirectiveOptionRelax() = 0;
+  virtual void emitDirectiveOptionNoRelax() = 0;
 };
 
 // This part is for ascii assembly output
@@ -31,6 +33,8 @@ public:
 
   void emitDirectiveOptionRVC() override;
   void emitDirectiveOptionNoRVC() override;
+  void emitDirectiveOptionRelax() override;
+  void emitDirectiveOptionNoRelax() override;
 };
 
 }

Added: llvm/trunk/test/CodeGen/RISCV/fixups-relax-diff.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/fixups-relax-diff.ll?rev=346655&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/fixups-relax-diff.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/fixups-relax-diff.ll Mon Nov 12 06:25:07 2018
@@ -0,0 +1,20 @@
+; RUN: llc -filetype=obj -mtriple=riscv32 -mattr=+relax %s -o - \
+; RUN:     | llvm-readobj -r | FileCheck -check-prefix=RELAX %s
+; RUN: llc -filetype=obj -mtriple=riscv32 -mattr=-relax %s -o - \
+; RUN:     | llvm-readobj -r | FileCheck -check-prefix=NORELAX %s
+
+; This test checks that a diff inserted via inline assembly only causes
+; relocations when relaxation is enabled. This isn't an assembly test
+; as the assembler takes a different path through LLVM, which is
+; already covered by the fixups-expr.s test.
+
+define i32 @main() {
+entry:
+  %retval = alloca i32, align 4
+  store i32 0, i32* %retval, align 4
+  ; RELAX: R_RISCV_ADD64 b
+  ; RELAX: R_RISCV_SUB64 a
+  ; NORELAX-NOT: R_RISCV
+  call void asm sideeffect "a:\0Ab:\0A.dword b-a", ""()
+  ret i32 0
+}

Added: llvm/trunk/test/CodeGen/RISCV/option-norelax.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/option-norelax.ll?rev=346655&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/option-norelax.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/option-norelax.ll Mon Nov 12 06:25:07 2018
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple=riscv32 -mattr=+relax -filetype=obj < %s \
+; RUN:     | llvm-objdump -d -r - | FileCheck %s
+
+; This test demonstrates that .option norelax has no effect on codegen
+; when emitting an ELF directly.
+
+declare i32 @foo(i32)
+
+define i32 @bar(i32 %a) nounwind {
+; CHECK-LABEL: bar:
+; CHECK: R_RISCV_CALL
+; CHECK: R_RISCV_RELAX
+  tail call void asm sideeffect ".option norelax", ""()
+  %1 = call i32 @foo(i32 %a)
+  ret i32 %1
+}

Added: llvm/trunk/test/CodeGen/RISCV/option-relax.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/option-relax.ll?rev=346655&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/option-relax.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/option-relax.ll Mon Nov 12 06:25:07 2018
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple=riscv32 -mattr=-relax -filetype=obj < %s \
+; RUN:     | llvm-objdump -d -r - | FileCheck %s
+
+; This test demonstrates that .option relax has no effect on codegen
+; when emitting an ELF directly.
+
+declare i32 @foo(i32)
+
+define i32 @bar(i32 %a) nounwind {
+; CHECK-LABEL: bar:
+; CHECK: R_RISCV_CALL
+; CHECK-NOT: R_RISCV_RELAX
+  tail call void asm sideeffect ".option relax", ""()
+  %1 = call i32 @foo(i32 %a)
+  ret i32 %1
+}

Modified: llvm/trunk/test/MC/RISCV/option-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/option-invalid.s?rev=346655&r1=346654&r2=346655&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/option-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/option-invalid.s Mon Nov 12 06:25:07 2018
@@ -13,5 +13,5 @@
 # CHECK: error: unexpected token, expected end of statement
 .option rvc foo
 
-# CHECK: warning: unknown option, expected 'rvc' or 'norvc'
+# CHECK: warning: unknown option, expected 'rvc', 'norvc', 'relax' or 'norelax'
 .option bar

Added: llvm/trunk/test/MC/RISCV/option-relax.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/option-relax.s?rev=346655&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/option-relax.s (added)
+++ llvm/trunk/test/MC/RISCV/option-relax.s Mon Nov 12 06:25:07 2018
@@ -0,0 +1,66 @@
+# RUN: llvm-mc -triple riscv32 < %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 riscv64 < %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
+
+# Check .option relax causes R_RISCV_RELAX to be emitted, and .option
+# norelax suppresses it. Also check that if .option relax was enabled
+# at any point and an instruction may have been relaxed, diff & branch
+# relocations are emitted to ensure correct codegen. See
+# linker-relaxation.s and fixups-expr.s for behaviour of the relax
+# attribute.
+
+.L1:
+.option norelax
+# CHECK-INST: .option norelax
+
+# CHECK-INST: call foo
+# CHECK-RELOC: R_RISCV_CALL foo 0x0
+# CHECK-RELOC-NOT: R_RISCV_RELAX foo 0x0
+call foo
+
+# CHECK-RELOC-NEXT: R_RISCV_ADD64
+# CHECK-RELOC-NEXT: R_RISCV_SUB64
+.dword .L2-.L1
+# CHECK-RELOC-NEXT: R_RISCV_JAL
+jal zero, .L1
+# CHECK-RELOC-NEXT: R_RISCV_BRANCH
+beq s1, s1, .L1
+
+.L2:
+.option relax
+# CHECK-INST: .option relax
+
+# CHECK-INST: call bar
+# CHECK-RELOC-NEXT: R_RISCV_CALL bar 0x0
+# CHECK-RELOC-NEXT: R_RISCV_RELAX bar 0x0
+call bar
+
+# CHECK-RELOC-NEXT: R_RISCV_ADD64
+# CHECK-RELOC-NEXT: R_RISCV_SUB64
+.dword .L2-.L1
+# CHECK-RELOC-NEXT: R_RISCV_JAL
+jal zero, .L1
+# CHECK-RELOC-NEXT: R_RISCV_BRANCH
+beq s1, s1, .L1
+
+.option norelax
+# CHECK-INST: .option norelax
+
+# CHECK-INST: call baz
+# CHECK-RELOC-NEXT: R_RISCV_CALL baz 0x0
+# CHECK-RELOC-NOT: R_RISCV_RELAX baz 0x0
+call baz
+
+# CHECK-RELOC-NEXT: R_RISCV_ADD64
+# CHECK-RELOC-NEXT: R_RISCV_SUB64
+.dword .L2-.L1
+# CHECK-RELOC-NEXT: R_RISCV_JAL
+jal zero, .L1
+# CHECK-RELOC-NEXT: R_RISCV_BRANCH
+beq s1, s1, .L1




More information about the llvm-commits mailing list