Skip to content

Commit 227496d

Browse files
luxufanluxufan
luxufan
authored and
luxufan
committed
[RISCV] Generate correct ELF EFlags when .ll file has target-abi attribute
In the past, when construct RISCVAsmBackend, MCTargetOptions.ABIName would be passed and stored in RISCVAsmBackend. But MCTargetOptions.ABIName can only be specified by -target-abi xxx in command line, if the .ll file has target-abi attribute, the codegen module will ignore it. And the generated object file would have incorrect EFlags value. #50591 also caused by this problem. This patch override the AsmPrinter::emitFunctionEntryLabel function and use it to set the target abi value that get from .ll file's target-abi attribute. And storing the target-abi in RISCVTargetStreamer instead of RISCVAsmBackend. Differential Revision: https://reviews.llvm.org/D121183
1 parent 5bb5704 commit 227496d

9 files changed

+80
-41
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ class RISCVAsmParser : public MCTargetAsmParser {
256256
"target-abi)\n";
257257
}
258258

259+
// Use computeTargetABI to check if ABIName is valid. If invalid, output
260+
// error message.
261+
RISCVABI::computeTargetABI(STI.getTargetTriple(), STI.getFeatureBits(),
262+
ABIName);
263+
259264
const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
260265
ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
261266
}

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,12 @@ class RISCVAsmBackend : public MCAsmBackend {
2727
bool Is64Bit;
2828
bool ForceRelocs = false;
2929
const MCTargetOptions &TargetOptions;
30-
RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
3130

3231
public:
3332
RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
3433
const MCTargetOptions &Options)
3534
: MCAsmBackend(support::little), STI(STI), OSABI(OSABI), Is64Bit(Is64Bit),
3635
TargetOptions(Options) {
37-
TargetABI = RISCVABI::computeTargetABI(
38-
STI.getTargetTriple(), STI.getFeatureBits(), Options.getABIName());
3936
RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits());
4037
}
4138
~RISCVAsmBackend() override = default;
@@ -103,7 +100,6 @@ class RISCVAsmBackend : public MCAsmBackend {
103100
const MCSubtargetInfo *STI) const override;
104101

105102
const MCTargetOptions &getTargetOptions() const { return TargetOptions; }
106-
RISCVABI::ABI getTargetABI() const { return TargetABI; }
107103
};
108104
}
109105

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "llvm/MC/MCSectionELF.h"
2424
#include "llvm/MC/MCSubtargetInfo.h"
2525
#include "llvm/MC/MCValue.h"
26-
#include "llvm/Support/Casting.h"
2726
#include "llvm/Support/LEB128.h"
2827
#include "llvm/Support/RISCVAttributes.h"
2928

@@ -32,38 +31,12 @@ using namespace llvm;
3231
// This part is for ELF object output.
3332
RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
3433
const MCSubtargetInfo &STI)
35-
: RISCVTargetStreamer(S), CurrentVendor("riscv") {
34+
: RISCVTargetStreamer(S), CurrentVendor("riscv"), STI(STI) {
3635
MCAssembler &MCA = getStreamer().getAssembler();
3736
const FeatureBitset &Features = STI.getFeatureBits();
3837
auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
39-
RISCVABI::ABI ABI = MAB.getTargetABI();
40-
assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
41-
42-
unsigned EFlags = MCA.getELFHeaderEFlags();
43-
44-
if (Features[RISCV::FeatureStdExtC])
45-
EFlags |= ELF::EF_RISCV_RVC;
46-
47-
switch (ABI) {
48-
case RISCVABI::ABI_ILP32:
49-
case RISCVABI::ABI_LP64:
50-
break;
51-
case RISCVABI::ABI_ILP32F:
52-
case RISCVABI::ABI_LP64F:
53-
EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE;
54-
break;
55-
case RISCVABI::ABI_ILP32D:
56-
case RISCVABI::ABI_LP64D:
57-
EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
58-
break;
59-
case RISCVABI::ABI_ILP32E:
60-
EFlags |= ELF::EF_RISCV_RVE;
61-
break;
62-
case RISCVABI::ABI_Unknown:
63-
llvm_unreachable("Improperly initialised target ABI");
64-
}
65-
66-
MCA.setELFHeaderEFlags(EFlags);
38+
setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features,
39+
MAB.getTargetOptions().getABIName()));
6740
}
6841

6942
MCELFStreamer &RISCVTargetELFStreamer::getStreamer() {
@@ -174,6 +147,39 @@ size_t RISCVTargetELFStreamer::calculateContentSize() const {
174147
return Result;
175148
}
176149

150+
void RISCVTargetELFStreamer::finish() {
151+
RISCVTargetStreamer::finish();
152+
MCAssembler &MCA = getStreamer().getAssembler();
153+
const FeatureBitset &Features = STI.getFeatureBits();
154+
RISCVABI::ABI ABI = getTargetABI();
155+
156+
unsigned EFlags = MCA.getELFHeaderEFlags();
157+
158+
if (Features[RISCV::FeatureStdExtC])
159+
EFlags |= ELF::EF_RISCV_RVC;
160+
161+
switch (ABI) {
162+
case RISCVABI::ABI_ILP32:
163+
case RISCVABI::ABI_LP64:
164+
break;
165+
case RISCVABI::ABI_ILP32F:
166+
case RISCVABI::ABI_LP64F:
167+
EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE;
168+
break;
169+
case RISCVABI::ABI_ILP32D:
170+
case RISCVABI::ABI_LP64D:
171+
EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
172+
break;
173+
case RISCVABI::ABI_ILP32E:
174+
EFlags |= ELF::EF_RISCV_RVE;
175+
break;
176+
case RISCVABI::ABI_Unknown:
177+
llvm_unreachable("Improperly initialised target ABI");
178+
}
179+
180+
MCA.setELFHeaderEFlags(EFlags);
181+
}
182+
177183
namespace {
178184
class RISCVELFStreamer : public MCELFStreamer {
179185
static std::pair<unsigned, unsigned> getRelocPairForSize(unsigned Size) {

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer {
2929
SmallVector<AttributeItem, 64> Contents;
3030

3131
MCSection *AttributeSection = nullptr;
32+
const MCSubtargetInfo &STI;
3233

3334
AttributeItem *getAttributeItem(unsigned Attribute) {
3435
for (size_t i = 0; i < Contents.size(); ++i)
@@ -103,6 +104,8 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer {
103104
void emitDirectiveOptionNoRVC() override;
104105
void emitDirectiveOptionRelax() override;
105106
void emitDirectiveOptionNoRelax() override;
107+
108+
void finish() override;
106109
};
107110

108111
MCELFStreamer *createRISCVELFStreamer(MCContext &C,

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,17 @@ static MCSubtargetInfo *createRISCVMCSubtargetInfo(const Triple &TT,
7979
StringRef CPU, StringRef FS) {
8080
if (CPU.empty() || CPU == "generic")
8181
CPU = TT.isArch64Bit() ? "generic-rv64" : "generic-rv32";
82-
return createRISCVMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
82+
83+
MCSubtargetInfo *STI =
84+
createRISCVMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
85+
86+
// Check if Feature string is valid
87+
auto ISAInfo =
88+
RISCVFeatures::parseFeatureBits(TT.isArch64Bit(), STI->getFeatureBits());
89+
if (!ISAInfo)
90+
report_fatal_error(ISAInfo.takeError());
91+
else
92+
return STI;
8393
}
8494

8595
static MCInstPrinter *createRISCVMCInstPrinter(const Triple &T,

llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ void RISCVTargetStreamer::emitTextAttribute(unsigned Attribute,
3838
void RISCVTargetStreamer::emitIntTextAttribute(unsigned Attribute,
3939
unsigned IntValue,
4040
StringRef StringValue) {}
41+
void RISCVTargetStreamer::setTargetABI(RISCVABI::ABI ABI) {
42+
assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialized target ABI");
43+
TargetABI = ABI;
44+
}
4145

4246
void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
4347
if (STI.hasFeature(RISCV::FeatureRV32E))

llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVTARGETSTREAMER_H
1010
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVTARGETSTREAMER_H
1111

12+
#include "RISCV.h"
1213
#include "llvm/MC/MCStreamer.h"
1314
#include "llvm/MC/MCSubtargetInfo.h"
1415

@@ -17,6 +18,8 @@ namespace llvm {
1718
class formatted_raw_ostream;
1819

1920
class RISCVTargetStreamer : public MCTargetStreamer {
21+
RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
22+
2023
public:
2124
RISCVTargetStreamer(MCStreamer &S);
2225
void finish() override;
@@ -36,6 +39,8 @@ class RISCVTargetStreamer : public MCTargetStreamer {
3639
StringRef StringValue);
3740

3841
void emitTargetAttributes(const MCSubtargetInfo &STI);
42+
void setTargetABI(RISCVABI::ABI ABI);
43+
RISCVABI::ABI getTargetABI() const { return TargetABI; }
3944
};
4045

4146
// This part is for ascii assembly output

llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ STATISTIC(RISCVNumInstrsCompressed,
3838

3939
namespace {
4040
class RISCVAsmPrinter : public AsmPrinter {
41-
const MCSubtargetInfo *STI;
41+
const MCSubtargetInfo *MCSTI;
42+
const RISCVSubtarget *STI;
4243

4344
public:
4445
explicit RISCVAsmPrinter(TargetMachine &TM,
4546
std::unique_ptr<MCStreamer> Streamer)
46-
: AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {}
47+
: AsmPrinter(TM, std::move(Streamer)), MCSTI(TM.getMCSubtargetInfo()) {}
4748

4849
StringRef getPassName() const override { return "RISCV Assembly Printer"; }
4950

@@ -68,6 +69,8 @@ class RISCVAsmPrinter : public AsmPrinter {
6869
void emitStartOfAsmFile(Module &M) override;
6970
void emitEndOfAsmFile(Module &M) override;
7071

72+
void emitFunctionEntryLabel() override;
73+
7174
private:
7275
void emitAttributes();
7376
};
@@ -170,7 +173,8 @@ bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
170173
MCSubtargetInfo &NewSTI =
171174
OutStreamer->getContext().getSubtargetCopy(*TM.getMCSubtargetInfo());
172175
NewSTI.setFeatureBits(MF.getSubtarget().getFeatureBits());
173-
STI = &NewSTI;
176+
MCSTI = &NewSTI;
177+
STI = &MF.getSubtarget<RISCVSubtarget>();
174178

175179
SetupMachineFunction(MF);
176180
emitFunctionBody();
@@ -193,7 +197,14 @@ void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
193197
void RISCVAsmPrinter::emitAttributes() {
194198
RISCVTargetStreamer &RTS =
195199
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
196-
RTS.emitTargetAttributes(*STI);
200+
RTS.emitTargetAttributes(*MCSTI);
201+
}
202+
203+
void RISCVAsmPrinter::emitFunctionEntryLabel() {
204+
AsmPrinter::emitFunctionEntryLabel();
205+
RISCVTargetStreamer &RTS =
206+
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
207+
RTS.setTargetABI(STI->getTargetABI());
197208
}
198209

199210
// Force static initialization.

llvm/test/CodeGen/RISCV/module-target-abi2.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88

99
; RV32IF-ILP32: -target-abi option != target-abi module flag
1010

11-
; FLAGS: Flags: 0x0
12-
; // this should be "Flags :0x2, single-float ABI", it will be fixed later.
11+
; FLAGS: Flags: 0x2, single-float ABI
1312

1413
define float @foo(i32 %a) nounwind #0 {
1514
; DEFAULT: # %bb.0:

0 commit comments

Comments
 (0)