[MC] Remove UseAssemblerInfoForParsing
Commit 6c0665e22174d474050e85ca367424f6e02476be (https://reviews.llvm.org/D45164) enabled certain constant expression evaluation for `MCObjectStreamer` at parse time (e.g. `.if` directives, see llvm/test/MC/AsmParser/assembler-expressions.s). `getUseAssemblerInfoForParsing` was added to make `clang -c` handling inline assembly similar to `MCAsmStreamer` (e.g. `llvm-mc -filetype=asm`), where such expression folding (related to `AttemptToFoldSymbolOffsetDifference`) is unavailable. I believe this is overly conservative. We can make some parse-time expression folding work for `clang -c` even if `clang -S` would still report an error, a MCAsmStreamer issue (we cannot print `.if` directives) that should not restrict the functionality of MCObjectStreamer. ``` % cat b.cc asm(R"( .pushsection .text,"ax" .globl _start; _start: ret .if . -_start == 1 ret .endif .popsection )"); % gcc -S b.cc && gcc -c b.cc % clang -S -fno-integrated-as b.cc # succeeded % clang -c b.cc # succeeded with this patch % clang -S b.cc # still failed <inline asm>:4:5: error: expected absolute expression 4 | .if . -_start == 1 | ^ 1 error generated. ``` Close #62520 Link: https://discourse.llvm.org/t/rfc-clang-assembly-object-equivalence-for-files-with-inline-assembly/78841 Pull Request: https://github.com/llvm/llvm-project/pull/91082
This commit is contained in:
parent
9bbefb7f60
commit
03c53c69a3
@ -576,9 +576,6 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||||||
Str.get()->emitZeros(1);
|
Str.get()->emitZeros(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assembly to object compilation should leverage assembly info.
|
|
||||||
Str->setUseAssemblerInfoForParsing(true);
|
|
||||||
|
|
||||||
bool Failed = false;
|
bool Failed = false;
|
||||||
|
|
||||||
std::unique_ptr<MCAsmParser> Parser(
|
std::unique_ptr<MCAsmParser> Parser(
|
||||||
|
@ -245,8 +245,6 @@ class MCStreamer {
|
|||||||
/// requires.
|
/// requires.
|
||||||
unsigned NextWinCFIID = 0;
|
unsigned NextWinCFIID = 0;
|
||||||
|
|
||||||
bool UseAssemblerInfoForParsing;
|
|
||||||
|
|
||||||
/// Is the assembler allowed to insert padding automatically? For
|
/// Is the assembler allowed to insert padding automatically? For
|
||||||
/// correctness reasons, we sometimes need to ensure instructions aren't
|
/// correctness reasons, we sometimes need to ensure instructions aren't
|
||||||
/// separated in unexpected ways. At the moment, this feature is only
|
/// separated in unexpected ways. At the moment, this feature is only
|
||||||
@ -296,11 +294,10 @@ public:
|
|||||||
|
|
||||||
MCContext &getContext() const { return Context; }
|
MCContext &getContext() const { return Context; }
|
||||||
|
|
||||||
|
// MCObjectStreamer has an MCAssembler and allows more expression folding at
|
||||||
|
// parse time.
|
||||||
virtual MCAssembler *getAssemblerPtr() { return nullptr; }
|
virtual MCAssembler *getAssemblerPtr() { return nullptr; }
|
||||||
|
|
||||||
void setUseAssemblerInfoForParsing(bool v) { UseAssemblerInfoForParsing = v; }
|
|
||||||
bool getUseAssemblerInfoForParsing() { return UseAssemblerInfoForParsing; }
|
|
||||||
|
|
||||||
MCTargetStreamer *getTargetStreamer() {
|
MCTargetStreamer *getTargetStreamer() {
|
||||||
return TargetStreamer.get();
|
return TargetStreamer.get();
|
||||||
}
|
}
|
||||||
|
@ -102,9 +102,6 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
|
|||||||
std::unique_ptr<MCAsmParser> Parser(
|
std::unique_ptr<MCAsmParser> Parser(
|
||||||
createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI, BufNum));
|
createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI, BufNum));
|
||||||
|
|
||||||
// Do not use assembler-level information for parsing inline assembly.
|
|
||||||
OutStreamer->setUseAssemblerInfoForParsing(false);
|
|
||||||
|
|
||||||
// We create a new MCInstrInfo here since we might be at the module level
|
// We create a new MCInstrInfo here since we might be at the module level
|
||||||
// and not have a MachineFunction to initialize the TargetInstrInfo from and
|
// and not have a MachineFunction to initialize the TargetInstrInfo from and
|
||||||
// we only need MCInstrInfo for asm parsing. We create one unconditionally
|
// we only need MCInstrInfo for asm parsing. We create one unconditionally
|
||||||
|
@ -40,14 +40,7 @@ MCObjectStreamer::MCObjectStreamer(MCContext &Context,
|
|||||||
|
|
||||||
MCObjectStreamer::~MCObjectStreamer() = default;
|
MCObjectStreamer::~MCObjectStreamer() = default;
|
||||||
|
|
||||||
// AssemblerPtr is used for evaluation of expressions and causes
|
MCAssembler *MCObjectStreamer::getAssemblerPtr() { return Assembler.get(); }
|
||||||
// difference between asm and object outputs. Return nullptr to in
|
|
||||||
// inline asm mode to limit divergence to assembly inputs.
|
|
||||||
MCAssembler *MCObjectStreamer::getAssemblerPtr() {
|
|
||||||
if (getUseAssemblerInfoForParsing())
|
|
||||||
return Assembler.get();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MCObjectStreamer::addPendingLabel(MCSymbol* S) {
|
void MCObjectStreamer::addPendingLabel(MCSymbol* S) {
|
||||||
MCSection *CurSection = getCurrentSectionOnly();
|
MCSection *CurSection = getCurrentSectionOnly();
|
||||||
|
@ -93,7 +93,7 @@ void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
|
|||||||
|
|
||||||
MCStreamer::MCStreamer(MCContext &Ctx)
|
MCStreamer::MCStreamer(MCContext &Ctx)
|
||||||
: Context(Ctx), CurrentWinFrameInfo(nullptr),
|
: Context(Ctx), CurrentWinFrameInfo(nullptr),
|
||||||
CurrentProcWinFrameInfoStartIndex(0), UseAssemblerInfoForParsing(false) {
|
CurrentProcWinFrameInfoStartIndex(0) {
|
||||||
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
|
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,12 +517,9 @@ bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
|
|
||||||
DumpCodeInstEmitter = nullptr;
|
DumpCodeInstEmitter = nullptr;
|
||||||
if (STM.dumpCode()) {
|
if (STM.dumpCode()) {
|
||||||
// For -dumpcode, get the assembler out of the streamer, even if it does
|
// For -dumpcode, get the assembler out of the streamer. This only works
|
||||||
// not really want to let us have it. This only works with -filetype=obj.
|
// with -filetype=obj.
|
||||||
bool SaveFlag = OutStreamer->getUseAssemblerInfoForParsing();
|
|
||||||
OutStreamer->setUseAssemblerInfoForParsing(true);
|
|
||||||
MCAssembler *Assembler = OutStreamer->getAssemblerPtr();
|
MCAssembler *Assembler = OutStreamer->getAssemblerPtr();
|
||||||
OutStreamer->setUseAssemblerInfoForParsing(SaveFlag);
|
|
||||||
if (Assembler)
|
if (Assembler)
|
||||||
DumpCodeInstEmitter = Assembler->getEmitterPtr();
|
DumpCodeInstEmitter = Assembler->getEmitterPtr();
|
||||||
}
|
}
|
||||||
|
@ -114,12 +114,9 @@ void SPIRVAsmPrinter::emitEndOfAsmFile(Module &M) {
|
|||||||
// Bound is an approximation that accounts for the maximum used register
|
// Bound is an approximation that accounts for the maximum used register
|
||||||
// number and number of generated OpLabels
|
// number and number of generated OpLabels
|
||||||
unsigned Bound = 2 * (ST->getBound() + 1) + NLabels;
|
unsigned Bound = 2 * (ST->getBound() + 1) + NLabels;
|
||||||
bool FlagToRestore = OutStreamer->getUseAssemblerInfoForParsing();
|
|
||||||
OutStreamer->setUseAssemblerInfoForParsing(true);
|
|
||||||
if (MCAssembler *Asm = OutStreamer->getAssemblerPtr())
|
if (MCAssembler *Asm = OutStreamer->getAssemblerPtr())
|
||||||
Asm->setBuildVersion(static_cast<MachO::PlatformType>(0), Major, Minor,
|
Asm->setBuildVersion(static_cast<MachO::PlatformType>(0), Major, Minor,
|
||||||
Bound, VersionTuple(Major, Minor, 0, Bound));
|
Bound, VersionTuple(Major, Minor, 0, Bound));
|
||||||
OutStreamer->setUseAssemblerInfoForParsing(FlagToRestore);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIRVAsmPrinter::emitFunctionHeader() {
|
void SPIRVAsmPrinter::emitFunctionHeader() {
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
; RUN: not llc -mtriple x86_64-unknown-linux-gnu -o %t.s -filetype=asm %s 2>&1 | FileCheck %s
|
; RUN: not llc -mtriple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s
|
||||||
; RUN: not llc -mtriple x86_64-unknown-linux-gnu -o %t.o -filetype=obj %s 2>&1 | FileCheck %s
|
; RUN: llc -mtriple=x86_64 -no-integrated-as < %s | FileCheck %s --check-prefix=GAS
|
||||||
|
; RUN: llc -mtriple=x86_64 -filetype=obj %s -o - | llvm-objdump -d - | FileCheck %s --check-prefix=DISASM
|
||||||
; Assembler-aware expression evaluation should be disabled in inline
|
|
||||||
; assembly to prevent differences in behavior between object and
|
|
||||||
; assembly output.
|
|
||||||
|
|
||||||
|
; GAS: nop; .if . - foo==1; nop;.endif
|
||||||
|
|
||||||
; CHECK: <inline asm>:1:17: error: expected absolute expression
|
; CHECK: <inline asm>:1:17: error: expected absolute expression
|
||||||
|
|
||||||
|
; DISASM: <main>:
|
||||||
|
; DISASM-NEXT: nop
|
||||||
|
; DISASM-NEXT: nop
|
||||||
|
; DISASM-NEXT: xorl %eax, %eax
|
||||||
|
; DISASM-NEXT: retq
|
||||||
|
|
||||||
define i32 @main() local_unnamed_addr {
|
define i32 @main() local_unnamed_addr {
|
||||||
tail call void asm sideeffect "foo: nop; .if . - foo==1; nop;.endif", "~{dirflag},~{fpsr},~{flags}"()
|
tail call void asm sideeffect "foo: nop; .if . - foo==1; nop;.endif", "~{dirflag},~{fpsr},~{flags}"()
|
||||||
ret i32 0
|
ret i32 0
|
||||||
|
@ -569,9 +569,6 @@ int main(int argc, char **argv) {
|
|||||||
Str->initSections(true, *STI);
|
Str->initSections(true, *STI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Assembler information for parsing.
|
|
||||||
Str->setUseAssemblerInfoForParsing(true);
|
|
||||||
|
|
||||||
int Res = 1;
|
int Res = 1;
|
||||||
bool disassemble = false;
|
bool disassemble = false;
|
||||||
switch (Action) {
|
switch (Action) {
|
||||||
|
@ -428,9 +428,6 @@ int llvm_ml_main(int Argc, char **Argv, const llvm::ToolContext &) {
|
|||||||
Str->emitAssignment(Feat00Sym, MCConstantExpr::create(Feat00Flags, Ctx));
|
Str->emitAssignment(Feat00Sym, MCConstantExpr::create(Feat00Flags, Ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Assembler information for parsing.
|
|
||||||
Str->setUseAssemblerInfoForParsing(true);
|
|
||||||
|
|
||||||
int Res = 1;
|
int Res = 1;
|
||||||
if (InputArgs.hasArg(OPT_as_lex)) {
|
if (InputArgs.hasArg(OPT_as_lex)) {
|
||||||
// -as-lex; Lex only, and output a stream of tokens
|
// -as-lex; Lex only, and output a stream of tokens
|
||||||
|
Loading…
x
Reference in New Issue
Block a user