Skip to content

Commit

Permalink
[RISCV] emit .option directive for functions with target features whi…
Browse files Browse the repository at this point in the history
…ch differ from module default

When function has different attributes from module, emit the .option <attribute> before the function body.  This allows non-integrated assemblers to properly assemble the functions (which may contain instructions dependent on the extra target features).

Reviewed By: craig.topper, reames

Differential Revision: https://reviews.llvm.org/D155155
  • Loading branch information
BeMg committed Aug 3, 2023
1 parent c7cacb2 commit 05041b7
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
41 changes: 41 additions & 0 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/RISCVISAInfo.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"

Expand All @@ -46,6 +47,10 @@ using namespace llvm;
STATISTIC(RISCVNumInstrsCompressed,
"Number of RISC-V Compressed instructions emitted");

namespace llvm {
extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
} // namespace llvm

namespace {
class RISCVAsmPrinter : public AsmPrinter {
const RISCVSubtarget *STI;
Expand Down Expand Up @@ -83,6 +88,8 @@ class RISCVAsmPrinter : public AsmPrinter {
void emitEndOfAsmFile(Module &M) override;

void emitFunctionEntryLabel() override;
void emitDirectiveOptionArch();
bool isSameAttribute();

private:
void emitAttributes();
Expand Down Expand Up @@ -238,11 +245,45 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
return false;
}

void RISCVAsmPrinter::emitDirectiveOptionArch() {
RISCVTargetStreamer &RTS =
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
SmallVector<RISCVOptionArchArg> NeedEmitStdOptionArgs;
const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
for (const auto &Feature : RISCVFeatureKV) {
if (STI->hasFeature(Feature.Value) == MCSTI.hasFeature(Feature.Value))
continue;

if (!llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key))
continue;

auto Delta = STI->hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
: RISCVOptionArchArgType::Minus;
NeedEmitStdOptionArgs.emplace_back(Delta, Feature.Key);
}
if (!NeedEmitStdOptionArgs.empty())
RTS.emitDirectiveOptionArch(NeedEmitStdOptionArgs);
}

bool RISCVAsmPrinter::isSameAttribute() {
const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
return MCSTI.getFeatureBits() == STI->getFeatureBits();
}

bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
STI = &MF.getSubtarget<RISCVSubtarget>();
RISCVTargetStreamer &RTS =
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
if (!isSameAttribute()) {
RTS.emitDirectiveOptionPush();
emitDirectiveOptionArch();
}

SetupMachineFunction(MF);
emitFunctionBody();

if (!isSameAttribute())
RTS.emitDirectiveOptionPop();
return false;
}

Expand Down
36 changes: 36 additions & 0 deletions llvm/test/CodeGen/RISCV/riscv-func-target-feature.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -verify-machineinstrs < %s | FileCheck %s

; CHECK: .option push
; CHECK-NEXT: .option arch, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
define void @test1() "target-features"="+a,+d,+f,+m,+c,+v,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" {
; CHECK-LABEL: test1
; CHECK: .option pop
entry:
ret void
}

; CHECK: .option push
; CHECK-NEXT: .option arch, +experimental-zihintntl
define void @test2() "target-features"="+a,+d,+f,+m,+experimental-zihintntl,+zifencei" {
; CHECK-LABEL: test2
; CHECK: .option pop
entry:
ret void
}

; CHECK: .option push
; CHECK-NEXT: .option arch, -a, -d, -f, -m
define void @test3() "target-features"="-a,-d,-f,-m" {
; CHECK-LABEL: test3
; CHECK: .option pop
entry:
ret void
}

; CHECK-NOT: .option push
define void @test4() {
; CHECK-LABEL: test4
; CHECK-NOT: .option pop
entry:
ret void
}

0 comments on commit 05041b7

Please sign in to comment.