diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index c15ee1c006c..6297defb1c5 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -475,6 +475,9 @@ public: extractStoreMemRefs(MachineInstr::mmo_iterator Begin, MachineInstr::mmo_iterator End); + /// Allocate a string and populate it with the given external symbol name. + const char *createExternalSymbolName(StringRef Name); + //===--------------------------------------------------------------------===// // Label Manipulation. // diff --git a/lib/CodeGen/MIRParser/MILexer.cpp b/lib/CodeGen/MIRParser/MILexer.cpp index ee4d59ddcaa..2a1caab5794 100644 --- a/lib/CodeGen/MIRParser/MILexer.cpp +++ b/lib/CodeGen/MIRParser/MILexer.cpp @@ -271,6 +271,36 @@ static Cursor maybeLexGlobalValue( return C; } +static Cursor lexName( + Cursor C, MIToken &Token, MIToken::TokenKind Type, + MIToken::TokenKind QuotedType, unsigned PrefixLength, + function_ref ErrorCallback) { + auto Range = C; + C.advance(PrefixLength); + if (C.peek() == '"') { + if (Cursor R = lexStringConstant(C, ErrorCallback)) { + Token = MIToken(QuotedType, Range.upto(R), PrefixLength); + return R; + } + Token = MIToken(MIToken::Error, Range.remaining()); + return Range; + } + while (isIdentifierChar(C.peek())) + C.advance(); + Token = MIToken(Type, Range.upto(C), PrefixLength); + return C; +} + +static Cursor maybeLexExternalSymbol( + Cursor C, MIToken &Token, + function_ref ErrorCallback) { + if (C.peek() != '$') + return None; + return lexName(C, Token, MIToken::ExternalSymbol, + MIToken::QuotedExternalSymbol, + /*PrefixLength=*/1, ErrorCallback); +} + static Cursor maybeLexIntegerLiteral(Cursor C, MIToken &Token) { if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1)))) return None; @@ -331,6 +361,8 @@ StringRef llvm::lexMIToken( return R.remaining(); if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback)) return R.remaining(); + if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback)) + return R.remaining(); if (Cursor R = maybeLexIntegerLiteral(C, Token)) return R.remaining(); if (Cursor R = maybeLexSymbol(C, Token)) diff --git a/lib/CodeGen/MIRParser/MILexer.h b/lib/CodeGen/MIRParser/MILexer.h index fd94d61cab3..7f36b9ab7f6 100644 --- a/lib/CodeGen/MIRParser/MILexer.h +++ b/lib/CodeGen/MIRParser/MILexer.h @@ -54,6 +54,8 @@ struct MIToken { NamedGlobalValue, QuotedNamedGlobalValue, GlobalValue, + ExternalSymbol, + QuotedExternalSymbol, // Other tokens IntegerLiteral, @@ -96,7 +98,9 @@ public: StringRef::iterator location() const { return Range.begin(); } - bool isStringValueQuoted() const { return Kind == QuotedNamedGlobalValue; } + bool isStringValueQuoted() const { + return Kind == QuotedNamedGlobalValue || Kind == QuotedExternalSymbol; + } /// Return the token's raw string value. /// diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index 34d3e1e3c53..ca98ae3c97f 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -110,6 +110,7 @@ public: bool parseGlobalAddressOperand(MachineOperand &Dest); bool parseConstantPoolIndexOperand(MachineOperand &Dest); bool parseJumpTableIndexOperand(MachineOperand &Dest); + bool parseExternalSymbolOperand(MachineOperand &Dest); bool parseMachineOperand(MachineOperand &Dest); private: @@ -560,6 +561,17 @@ bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) { + assert(Token.is(MIToken::ExternalSymbol) || + Token.is(MIToken::QuotedExternalSymbol)); + StringValueUtility Name(Token); + const char *Symbol = MF.createExternalSymbolName(Name); + lex(); + // TODO: Parse the target flags. + Dest = MachineOperand::CreateES(Symbol); + return false; +} + bool MIParser::parseMachineOperand(MachineOperand &Dest) { switch (Token.kind()) { case MIToken::kw_implicit: @@ -587,6 +599,9 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) { return parseConstantPoolIndexOperand(Dest); case MIToken::JumpTableIndex: return parseJumpTableIndexOperand(Dest); + case MIToken::ExternalSymbol: + case MIToken::QuotedExternalSymbol: + return parseExternalSymbolOperand(Dest); case MIToken::Error: return true; case MIToken::Identifier: diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index c3a655aec0b..9413a7e3811 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MIRYamlMapping.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/Module.h" #include "llvm/IR/ModuleSlotTracker.h" #include "llvm/Support/MemoryBuffer.h" @@ -430,6 +431,11 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { OS << "%jump-table." << Op.getIndex(); // TODO: Print target flags. break; + case MachineOperand::MO_ExternalSymbol: + OS << '$'; + printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); + // TODO: Print the target flags. + break; case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); // TODO: Print offset and target flags. diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 9856e70edae..0a8309eb2f2 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -322,6 +322,13 @@ MachineFunction::extractStoreMemRefs(MachineInstr::mmo_iterator Begin, return std::make_pair(Result, Result + Num); } +const char *MachineFunction::createExternalSymbolName(StringRef Name) { + char *Dest = Allocator.Allocate(Name.size() + 1); + std::copy(Name.begin(), Name.end(), Dest); + Dest[Name.size()] = 0; + return Dest; +} + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MachineFunction::dump() const { print(dbgs()); diff --git a/test/CodeGen/MIR/X86/external-symbol-operands.mir b/test/CodeGen/MIR/X86/external-symbol-operands.mir new file mode 100644 index 00000000000..a786882bea6 --- /dev/null +++ b/test/CodeGen/MIR/X86/external-symbol-operands.mir @@ -0,0 +1,60 @@ +# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s +# This test ensures that the MIR parser parses the external symbol machine +# operands correctly. + +--- | + @__stack_chk_guard = external global i8* + + define i32 @test(i32 %n) #0 { + entry: + %StackGuardSlot = alloca i8* + %StackGuard = load i8*, i8** @__stack_chk_guard + call void @llvm.stackprotector(i8* %StackGuard, i8** %StackGuardSlot) + %a = alloca [128 x i32], align 16 + %idxprom = sext i32 %n to i64 + %arrayidx = getelementptr inbounds [128 x i32], [128 x i32]* %a, i64 0, i64 %idxprom + %0 = load i32, i32* %arrayidx, align 4 + call void @llvm.stackprotectorcheck(i8** @__stack_chk_guard) + ret i32 %0 + } + + declare void @llvm.stackprotector(i8*, i8**) #1 + + declare void @llvm.stackprotectorcheck(i8**) #1 + + attributes #0 = { ssp "stack-protector-buffer-size"="8" } + attributes #1 = { nounwind } + +... +--- +name: test +tracksRegLiveness: true +body: + - id: 0 + name: entry + successors: [ '%bb.1.entry', '%bb.2.entry' ] + instructions: + - '%rsp = SUB64ri32 %rsp, 520, implicit-def %eflags' + - '%rcx = LOAD_STACK_GUARD' + - 'MOV64mr %rsp, 1, _, 512, _, %rcx' + - '%rax = MOVSX64rr32 %edi' + - '%eax = MOV32rm %rsp, 4, %rax, 0, _' + - 'CMP64rm %rcx, %rsp, 1, _, 512, _, implicit-def %eflags' + - 'JNE_1 %bb.2.entry, implicit %eflags' + - id: 1 + name: entry + instructions: + - '%rsp = ADD64ri32 %rsp, 520, implicit-def %eflags' + - 'RETQ %eax' + - id: 2 + name: entry + instructions: + # CHECK: CALL64pcrel32 $__stack_chk_fail, + # CHECK-NEXT: CALL64pcrel32 $__stack_chk_fail.09-_, + # CHECK-NEXT: CALL64pcrel32 $"__stack_chk_fail$", + # CHECK-NEXT: CALL64pcrel32 $"$Quoted \09 External symbol \11 ", + - 'CALL64pcrel32 $__stack_chk_fail, csr_64, implicit %rsp, implicit-def %rsp' + - 'CALL64pcrel32 $__stack_chk_fail.09-_, csr_64, implicit %rsp, implicit-def %rsp' + - 'CALL64pcrel32 $__stack_chk_fail$, csr_64, implicit %rsp, implicit-def %rsp' + - 'CALL64pcrel32 $"$Quoted \09 External symbol \11 ", csr_64, implicit %rsp, implicit-def %rsp' +...