Skip to content

Commit 05041b7

Browse files
committed
[RISCV] emit .option directive for functions with target features which 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
1 parent c7cacb2 commit 05041b7

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "llvm/MC/MCStreamer.h"
3737
#include "llvm/MC/MCSymbol.h"
3838
#include "llvm/MC/TargetRegistry.h"
39+
#include "llvm/Support/RISCVISAInfo.h"
3940
#include "llvm/Support/raw_ostream.h"
4041
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
4142

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

50+
namespace llvm {
51+
extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
52+
} // namespace llvm
53+
4954
namespace {
5055
class RISCVAsmPrinter : public AsmPrinter {
5156
const RISCVSubtarget *STI;
@@ -83,6 +88,8 @@ class RISCVAsmPrinter : public AsmPrinter {
8388
void emitEndOfAsmFile(Module &M) override;
8489

8590
void emitFunctionEntryLabel() override;
91+
void emitDirectiveOptionArch();
92+
bool isSameAttribute();
8693

8794
private:
8895
void emitAttributes();
@@ -238,11 +245,45 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
238245
return false;
239246
}
240247

248+
void RISCVAsmPrinter::emitDirectiveOptionArch() {
249+
RISCVTargetStreamer &RTS =
250+
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
251+
SmallVector<RISCVOptionArchArg> NeedEmitStdOptionArgs;
252+
const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
253+
for (const auto &Feature : RISCVFeatureKV) {
254+
if (STI->hasFeature(Feature.Value) == MCSTI.hasFeature(Feature.Value))
255+
continue;
256+
257+
if (!llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key))
258+
continue;
259+
260+
auto Delta = STI->hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
261+
: RISCVOptionArchArgType::Minus;
262+
NeedEmitStdOptionArgs.emplace_back(Delta, Feature.Key);
263+
}
264+
if (!NeedEmitStdOptionArgs.empty())
265+
RTS.emitDirectiveOptionArch(NeedEmitStdOptionArgs);
266+
}
267+
268+
bool RISCVAsmPrinter::isSameAttribute() {
269+
const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
270+
return MCSTI.getFeatureBits() == STI->getFeatureBits();
271+
}
272+
241273
bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
242274
STI = &MF.getSubtarget<RISCVSubtarget>();
275+
RISCVTargetStreamer &RTS =
276+
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
277+
if (!isSameAttribute()) {
278+
RTS.emitDirectiveOptionPush();
279+
emitDirectiveOptionArch();
280+
}
243281

244282
SetupMachineFunction(MF);
245283
emitFunctionBody();
284+
285+
if (!isSameAttribute())
286+
RTS.emitDirectiveOptionPop();
246287
return false;
247288
}
248289

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -verify-machineinstrs < %s | FileCheck %s
2+
3+
; CHECK: .option push
4+
; CHECK-NEXT: .option arch, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
5+
define void @test1() "target-features"="+a,+d,+f,+m,+c,+v,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" {
6+
; CHECK-LABEL: test1
7+
; CHECK: .option pop
8+
entry:
9+
ret void
10+
}
11+
12+
; CHECK: .option push
13+
; CHECK-NEXT: .option arch, +experimental-zihintntl
14+
define void @test2() "target-features"="+a,+d,+f,+m,+experimental-zihintntl,+zifencei" {
15+
; CHECK-LABEL: test2
16+
; CHECK: .option pop
17+
entry:
18+
ret void
19+
}
20+
21+
; CHECK: .option push
22+
; CHECK-NEXT: .option arch, -a, -d, -f, -m
23+
define void @test3() "target-features"="-a,-d,-f,-m" {
24+
; CHECK-LABEL: test3
25+
; CHECK: .option pop
26+
entry:
27+
ret void
28+
}
29+
30+
; CHECK-NOT: .option push
31+
define void @test4() {
32+
; CHECK-LABEL: test4
33+
; CHECK-NOT: .option pop
34+
entry:
35+
ret void
36+
}

0 commit comments

Comments
 (0)