From a41742659a7862cd60082b7419f511d06d1db37f Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Wed, 5 Aug 2015 22:26:15 +0000 Subject: [PATCH] MIR Serialization: Serialize the machine operand's offset. This commit serializes the offset for the following operands: target index, global address, external symbol, constant pool index, and block address. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244157 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MIRParser/MILexer.cpp | 4 ++ lib/CodeGen/MIRParser/MILexer.h | 2 + lib/CodeGen/MIRParser/MIParser.cpp | 39 +++++++++++++++--- lib/CodeGen/MIRPrinter.cpp | 24 +++++++++-- .../MIR/AMDGPU/target-index-operands.mir | 40 +++++++++++++++++++ .../MIR/X86/block-address-operands.mir | 27 +++++++++++++ test/CodeGen/MIR/X86/constant-pool.mir | 29 ++++++++++++++ .../expected-integer-after-offset-sign.mir | 26 ++++++++++++ .../MIR/X86/external-symbol-operands.mir | 4 ++ .../CodeGen/MIR/X86/global-value-operands.mir | 30 ++++++++++++++ .../MIR/X86/large-offset-number-error.mir | 26 ++++++++++++ 11 files changed, 242 insertions(+), 9 deletions(-) create mode 100644 test/CodeGen/MIR/X86/expected-integer-after-offset-sign.mir create mode 100644 test/CodeGen/MIR/X86/large-offset-number-error.mir diff --git a/lib/CodeGen/MIRParser/MILexer.cpp b/lib/CodeGen/MIRParser/MILexer.cpp index da79e1c070d..fece542d60e 100644 --- a/lib/CodeGen/MIRParser/MILexer.cpp +++ b/lib/CodeGen/MIRParser/MILexer.cpp @@ -399,6 +399,10 @@ static MIToken::TokenKind symbolToken(char C) { return MIToken::lparen; case ')': return MIToken::rparen; + case '+': + return MIToken::plus; + case '-': + return MIToken::minus; default: return MIToken::Error; } diff --git a/lib/CodeGen/MIRParser/MILexer.h b/lib/CodeGen/MIRParser/MILexer.h index 9896f7bcad7..064f68e2d5d 100644 --- a/lib/CodeGen/MIRParser/MILexer.h +++ b/lib/CodeGen/MIRParser/MILexer.h @@ -40,6 +40,8 @@ struct MIToken { exclaim, lparen, rparen, + plus, + minus, // Keywords kw_implicit, diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index a30a4a9a83f..1a47c5865bb 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -120,6 +120,7 @@ public: bool parseBlockAddressOperand(MachineOperand &Dest); bool parseTargetIndexOperand(MachineOperand &Dest); bool parseMachineOperand(MachineOperand &Dest); + bool parseOperandsOffset(MachineOperand &Op); bool parseIRValue(Value *&V); bool parseMemoryOperandFlag(unsigned &Flags); bool parseMachineMemoryOperand(MachineMemOperand *&Dest); @@ -693,9 +694,11 @@ bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) { GlobalValue *GV = nullptr; if (parseGlobalValue(GV)) return true; - Dest = MachineOperand::CreateGA(GV, /*Offset=*/0); - // TODO: Parse offset and target flags. lex(); + Dest = MachineOperand::CreateGA(GV, /*Offset=*/0); + // TODO: Parse the target flags. + if (parseOperandsOffset(Dest)) + return true; return false; } @@ -708,8 +711,10 @@ bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) { if (ConstantInfo == PFS.ConstantPoolSlots.end()) return error("use of undefined constant '%const." + Twine(ID) + "'"); lex(); - // TODO: Parse offset and target flags. + // TODO: Parse the target flags. Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0); + if (parseOperandsOffset(Dest)) + return true; return false; } @@ -733,6 +738,8 @@ bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) { lex(); // TODO: Parse the target flags. Dest = MachineOperand::CreateES(Symbol); + if (parseOperandsOffset(Dest)) + return true; return false; } @@ -882,8 +889,10 @@ bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) { lex(); if (expectAndConsume(MIToken::rparen)) return true; - // TODO: parse offset and target flags. + // TODO: parse the target flags. Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0); + if (parseOperandsOffset(Dest)) + return true; return false; } @@ -900,8 +909,10 @@ bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) { lex(); if (expectAndConsume(MIToken::rparen)) return true; - // TODO: Parse the offset and target flags. + // TODO: Parse the target flags. Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0); + if (parseOperandsOffset(Dest)) + return true; return false; } @@ -971,6 +982,24 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseOperandsOffset(MachineOperand &Op) { + if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus)) + return false; + StringRef Sign = Token.stringValue(); + bool IsNegative = Token.is(MIToken::minus); + lex(); + if (Token.isNot(MIToken::IntegerLiteral)) + return error("expected an integer literal after '" + Sign + "'"); + if (Token.integerValue().getMinSignedBits() > 64) + return error("expected 64-bit integer (too large)"); + int64_t Offset = Token.integerValue().getExtValue(); + if (IsNegative) + Offset = -Offset; + lex(); + Op.setOffset(Offset); + return false; +} + bool MIParser::parseIRValue(Value *&V) { switch (Token.kind()) { case MIToken::NamedIRValue: { diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index 375fb74790b..9af64823d04 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -117,6 +117,7 @@ public: void printIRBlockReference(const BasicBlock &BB); void printIRValueReference(const Value &V); void printStackObjectReference(int FrameIndex); + void printOffset(int64_t Offset); void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); void print(const MachineMemOperand &Op); @@ -505,6 +506,16 @@ void MIPrinter::printStackObjectReference(int FrameIndex) { OS << '.' << Operand.Name; } +void MIPrinter::printOffset(int64_t Offset) { + if (Offset == 0) + return; + if (Offset < 0) { + OS << " - " << -Offset; + return; + } + OS << " + " << Offset; +} + static const char *getTargetIndexName(const MachineFunction &MF, int Index) { const auto *TII = MF.getSubtarget().getInstrInfo(); assert(TII && "expected instruction info"); @@ -555,7 +566,8 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { break; case MachineOperand::MO_ConstantPoolIndex: OS << "%const." << Op.getIndex(); - // TODO: Print offset and target flags. + printOffset(Op.getOffset()); + // TODO: Print the target flags. break; case MachineOperand::MO_TargetIndex: { OS << "target-index("; @@ -565,7 +577,8 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { else OS << ""; OS << ')'; - // TODO: Print the offset and target flags. + printOffset(Op.getOffset()); + // TODO: Print the target flags. break; } case MachineOperand::MO_JumpTableIndex: @@ -575,11 +588,13 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { case MachineOperand::MO_ExternalSymbol: OS << '$'; printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); + printOffset(Op.getOffset()); // TODO: Print the target flags. break; case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); - // TODO: Print offset and target flags. + printOffset(Op.getOffset()); + // TODO: Print the target flags. break; case MachineOperand::MO_BlockAddress: OS << "blockaddress("; @@ -588,7 +603,8 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { OS << ", "; printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); OS << ')'; - // TODO: Print offset and target flags. + printOffset(Op.getOffset()); + // TODO: Print the target flags. break; case MachineOperand::MO_RegisterMask: { auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); diff --git a/test/CodeGen/MIR/AMDGPU/target-index-operands.mir b/test/CodeGen/MIR/AMDGPU/target-index-operands.mir index a130689419a..aedfae6e375 100644 --- a/test/CodeGen/MIR/AMDGPU/target-index-operands.mir +++ b/test/CodeGen/MIR/AMDGPU/target-index-operands.mir @@ -15,6 +15,14 @@ ret void } + define void @float2(float addrspace(1)* %out, i32 %index) #0 { + entry: + %0 = getelementptr inbounds [5 x float], [5 x float] addrspace(2)* @float_gv, i32 0, i32 %index + %1 = load float, float addrspace(2)* %0 + store float %1, float addrspace(1)* %out + ret void + } + declare { i1, i64 } @llvm.SI.if(i1) declare { i1, i64 } @llvm.SI.else(i64) @@ -64,3 +72,35 @@ body: - 'BUFFER_STORE_DWORD_OFFSET killed %vgpr0, %sgpr4_sgpr5_sgpr6_sgpr7, 0, 0, 0, 0, 0, implicit %exec' - S_ENDPGM ... +--- +name: float2 +tracksSubRegLiveness: true +liveins: + - { reg: '%sgpr0_sgpr1' } +frameInfo: + maxAlignment: 8 +body: + - id: 0 + name: entry + liveins: [ '%sgpr0_sgpr1' ] + instructions: + - '%sgpr2_sgpr3 = S_GETPC_B64' +# CHECK: %sgpr2 = S_ADD_U32 %sgpr2, target-index(amdgpu-constdata-start) + 1, implicit-def %scc, implicit-def %scc + - '%sgpr2 = S_ADD_U32 %sgpr2, target-index(amdgpu-constdata-start) + 1, implicit-def %scc, implicit-def %scc' + - '%sgpr3 = S_ADDC_U32 %sgpr3, 0, implicit-def %scc, implicit %scc, implicit-def %scc, implicit %scc' + - '%sgpr4_sgpr5 = S_LSHR_B64 %sgpr2_sgpr3, 32, implicit-def dead %scc' + - '%sgpr6 = S_LOAD_DWORD_IMM %sgpr0_sgpr1, 11' + - '%sgpr7 = S_ASHR_I32 %sgpr6, 31, implicit-def dead %scc' + - '%sgpr6_sgpr7 = S_LSHL_B64 %sgpr6_sgpr7, 2, implicit-def dead %scc' + - '%sgpr2 = S_ADD_U32 %sgpr2, @float_gv, implicit-def %scc' + - '%sgpr3 = S_ADDC_U32 %sgpr4, 0, implicit-def dead %scc, implicit %scc' + - '%sgpr4 = S_ADD_U32 %sgpr2, %sgpr6, implicit-def %scc' + - '%sgpr5 = S_ADDC_U32 %sgpr3, %sgpr7, implicit-def dead %scc, implicit %scc' + - '%sgpr2 = S_LOAD_DWORD_IMM %sgpr4_sgpr5, 0' + - '%sgpr4_sgpr5 = S_LOAD_DWORDX2_IMM killed %sgpr0_sgpr1, 9' + - '%sgpr7 = S_MOV_B32 61440' + - '%sgpr6 = S_MOV_B32 -1' + - '%vgpr0 = V_MOV_B32_e32 killed %sgpr2, implicit %exec' + - 'BUFFER_STORE_DWORD_OFFSET killed %vgpr0, %sgpr4_sgpr5_sgpr6_sgpr7, 0, 0, 0, 0, 0, implicit %exec' + - S_ENDPGM +... diff --git a/test/CodeGen/MIR/X86/block-address-operands.mir b/test/CodeGen/MIR/X86/block-address-operands.mir index a0b17b00d2f..c96720d3559 100644 --- a/test/CodeGen/MIR/X86/block-address-operands.mir +++ b/test/CodeGen/MIR/X86/block-address-operands.mir @@ -35,6 +35,16 @@ ret void } + define void @test4() { + entry: + store volatile i8* blockaddress(@test4, %block), i8** @addr + %val = load volatile i8*, i8** @addr + indirectbr i8* %val, [label %block] + + block: + ret void + } + ... --- name: test @@ -87,3 +97,20 @@ body: instructions: - RETQ ... +--- +name: test4 +body: + - id: 0 + name: entry + successors: [ '%bb.1.block' ] + instructions: + # CHECK: %rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block.block) + 2, _ + - '%rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block.block) + 2, _' + - 'MOV64mr %rip, 1, _, @addr, _, killed %rax' + - 'JMP64m %rip, 1, _, @addr, _' + - id: 1 + name: block + addressTaken: true + instructions: + - RETQ +... diff --git a/test/CodeGen/MIR/X86/constant-pool.mir b/test/CodeGen/MIR/X86/constant-pool.mir index 57508d1c51d..8e5b9b57388 100644 --- a/test/CodeGen/MIR/X86/constant-pool.mir +++ b/test/CodeGen/MIR/X86/constant-pool.mir @@ -30,6 +30,15 @@ %f = fmul double %c, %e ret double %f } + + define double @test4(double %a, float %b) { + entry: + %c = fadd double %a, 3.250000e+00 + %d = fadd float %b, 6.250000e+00 + %e = fpext float %d to double + %f = fmul double %c, %e + ret double %f + } ... --- # CHECK: name: test @@ -116,3 +125,23 @@ body: - '%xmm0 = MULSDrr killed %xmm0, killed %xmm1' - 'RETQ %xmm0' ... +--- +# CHECK: name: test4 +name: test4 +constants: + - id: 0 + value: 'double 3.250000e+00' + - id: 1 + value: 'float 6.250000e+00' +body: + - id: 0 + name: entry + instructions: + # CHECK: %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.1 - 12, _ + # CHECK-NEXT: %xmm1 = ADDSSrm killed %xmm1, %rip, 1, _, %const.0 + 8, _ + - '%xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.1 - 12, _' + - '%xmm1 = ADDSSrm killed %xmm1, %rip, 1, _, %const.0 + 8, _' + - '%xmm1 = CVTSS2SDrr killed %xmm1' + - '%xmm0 = MULSDrr killed %xmm0, killed %xmm1' + - 'RETQ %xmm0' +... diff --git a/test/CodeGen/MIR/X86/expected-integer-after-offset-sign.mir b/test/CodeGen/MIR/X86/expected-integer-after-offset-sign.mir new file mode 100644 index 00000000000..5e84c277286 --- /dev/null +++ b/test/CodeGen/MIR/X86/expected-integer-after-offset-sign.mir @@ -0,0 +1,26 @@ +# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + @G = external global i32 + + define i32 @inc() { + entry: + %a = load i32, i32* @G + %b = add i32 %a, 1 + ret i32 %b + } + +... +--- +name: inc +body: + - id: 0 + name: entry + instructions: + # CHECK: [[@LINE+1]]:42: expected an integer literal after '+' + - '%rax = MOV64rm %rip, 1, _, @G + , _' + - '%eax = MOV32rm %rax, 1, _, 0, _' + - '%eax = INC32r %eax, implicit-def %eflags' + - 'RETQ %eax' +... diff --git a/test/CodeGen/MIR/X86/external-symbol-operands.mir b/test/CodeGen/MIR/X86/external-symbol-operands.mir index 78d66459af5..eeb93c8f21f 100644 --- a/test/CodeGen/MIR/X86/external-symbol-operands.mir +++ b/test/CodeGen/MIR/X86/external-symbol-operands.mir @@ -55,8 +55,12 @@ body: # CHECK-NEXT: CALL64pcrel32 $__stack_chk_fail.09-_, # CHECK-NEXT: CALL64pcrel32 $"__stack_chk_fail$", # CHECK-NEXT: CALL64pcrel32 $"$Quoted \09 External symbol \11 ", + # CHECK-NEXT: CALL64pcrel32 $__stack_chk_fail + 2, + # CHECK-NEXT: CALL64pcrel32 $" check stack - 20" - 20, - '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' + - 'CALL64pcrel32 $__stack_chk_fail + 2, csr_64, implicit %rsp, implicit-def %rsp' + - 'CALL64pcrel32 $" check stack - 20" - 20, csr_64, implicit %rsp, implicit-def %rsp' ... diff --git a/test/CodeGen/MIR/X86/global-value-operands.mir b/test/CodeGen/MIR/X86/global-value-operands.mir index 775a01ba003..251d1ff3617 100644 --- a/test/CodeGen/MIR/X86/global-value-operands.mir +++ b/test/CodeGen/MIR/X86/global-value-operands.mir @@ -42,6 +42,15 @@ ret i32 %a } + define i32 @test3() { + entry: + %a = load i32, i32* @.$0 + store i32 %a, i32* @-_- + %b = load i32, i32* @_-_a + store i32 %b, i32* @$.-B + ret i32 %b + } + ... --- # CHECK: name: inc @@ -100,3 +109,24 @@ body: - '%eax = MOV32rm killed %rax, 1, _, 0, _' - 'RETQ %eax' ... +--- +# CHECK: name: test3 +name: test3 +body: + - id: 0 + name: entry + instructions: + # CHECK: , @".$0", + # CHECK: , @-_-, + # CHECK: , @_-_a + 4, + # CHECK: , @"$.-B" - 8, + - '%rax = MOV64rm %rip, 1, _, @.$0 + 0, _' + - '%eax = MOV32rm killed %rax, 1, _, 0, _' + - '%rcx = MOV64rm %rip, 1, _, @-_- - 0, _' + - 'MOV32mr killed %rcx, 1, _, 0, _, killed %eax' + - '%rax = MOV64rm %rip, 1, _, @_-_a + 4, _' + - '%eax = MOV32rm killed %rax, 1, _, 0, _' + - '%rcx = MOV64rm %rip, 1, _, @$.-B - 8, _' + - 'MOV32mr killed %rcx, 1, _, 0, _, %eax' + - 'RETQ %eax' +... diff --git a/test/CodeGen/MIR/X86/large-offset-number-error.mir b/test/CodeGen/MIR/X86/large-offset-number-error.mir new file mode 100644 index 00000000000..54d8e41064a --- /dev/null +++ b/test/CodeGen/MIR/X86/large-offset-number-error.mir @@ -0,0 +1,26 @@ +# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + @G = external global i32 + + define i32 @inc() { + entry: + %a = load i32, i32* @G + %b = add i32 %a, 1 + ret i32 %b + } + +... +--- +name: inc +body: + - id: 0 + name: entry + instructions: + # CHECK: [[@LINE+1]]:42: expected 64-bit integer (too large) + - '%rax = MOV64rm %rip, 1, _, @G + 123456789123456789123456789, _' + - '%eax = MOV32rm %rax, 1, _, 0, _' + - '%eax = INC32r %eax implicit-def %eflags' + - 'RETQ %eax' +... -- 2.34.1