From: Alex Lorenz Date: Fri, 31 Jul 2015 20:49:21 +0000 (+0000) Subject: MIR Serialization: Serialize the floating point immediate machine operands. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=c225eda1f1cfb4dc46cea886af8830464ee4eb01 MIR Serialization: Serialize the floating point immediate machine operands. Reviewers: Duncan P. N. Exon Smith git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243780 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/MIRParser/MILexer.cpp b/lib/CodeGen/MIRParser/MILexer.cpp index 3c0dc4c0ded..2104f002b1f 100644 --- a/lib/CodeGen/MIRParser/MILexer.cpp +++ b/lib/CodeGen/MIRParser/MILexer.cpp @@ -150,6 +150,12 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case(".cfi_def_cfa", MIToken::kw_cfi_def_cfa) .Case("blockaddress", MIToken::kw_blockaddress) .Case("target-index", MIToken::kw_target_index) + .Case("half", MIToken::kw_half) + .Case("float", MIToken::kw_float) + .Case("double", MIToken::kw_double) + .Case("x86_fp80", MIToken::kw_x86_fp80) + .Case("fp128", MIToken::kw_fp128) + .Case("ppc_fp128", MIToken::kw_ppc_fp128) .Default(MIToken::Identifier); } @@ -308,13 +314,48 @@ static Cursor maybeLexExternalSymbol( /*PrefixLength=*/1, ErrorCallback); } -static Cursor maybeLexIntegerLiteral(Cursor C, MIToken &Token) { +static bool isValidHexFloatingPointPrefix(char C) { + return C == 'H' || C == 'K' || C == 'L' || C == 'M'; +} + +static Cursor maybeLexHexFloatingPointLiteral(Cursor C, MIToken &Token) { + if (C.peek() != '0' || C.peek(1) != 'x') + return None; + Cursor Range = C; + C.advance(2); // Skip '0x' + if (isValidHexFloatingPointPrefix(C.peek())) + C.advance(); + while (isxdigit(C.peek())) + C.advance(); + Token = MIToken(MIToken::FloatingPointLiteral, Range.upto(C)); + return C; +} + +static Cursor lexFloatingPointLiteral(Cursor Range, Cursor C, MIToken &Token) { + C.advance(); + // Skip over [0-9]*([eE][-+]?[0-9]+)? + while (isdigit(C.peek())) + C.advance(); + if ((C.peek() == 'e' || C.peek() == 'E') && + (isdigit(C.peek(1)) || + ((C.peek(1) == '-' || C.peek(1) == '+') && isdigit(C.peek(2))))) { + C.advance(2); + while (isdigit(C.peek())) + C.advance(); + } + Token = MIToken(MIToken::FloatingPointLiteral, Range.upto(C)); + return C; +} + +static Cursor maybeLexNumericalLiteral(Cursor C, MIToken &Token) { if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1)))) return None; auto Range = C; C.advance(); while (isdigit(C.peek())) C.advance(); + if (C.peek() == '.') + return lexFloatingPointLiteral(Range, C, Token); StringRef StrVal = Range.upto(C); Token = MIToken(MIToken::IntegerLiteral, StrVal, APSInt(StrVal)); return C; @@ -378,7 +419,9 @@ StringRef llvm::lexMIToken( return R.remaining(); if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback)) return R.remaining(); - if (Cursor R = maybeLexIntegerLiteral(C, Token)) + if (Cursor R = maybeLexHexFloatingPointLiteral(C, Token)) + return R.remaining(); + if (Cursor R = maybeLexNumericalLiteral(C, Token)) return R.remaining(); if (Cursor R = maybeLexSymbol(C, Token)) return R.remaining(); diff --git a/lib/CodeGen/MIRParser/MILexer.h b/lib/CodeGen/MIRParser/MILexer.h index 31c3575bba9..2b06f13c9db 100644 --- a/lib/CodeGen/MIRParser/MILexer.h +++ b/lib/CodeGen/MIRParser/MILexer.h @@ -54,6 +54,12 @@ struct MIToken { kw_cfi_def_cfa, kw_blockaddress, kw_target_index, + kw_half, + kw_float, + kw_double, + kw_x86_fp80, + kw_fp128, + kw_ppc_fp128, // Identifier tokens Identifier, @@ -69,6 +75,7 @@ struct MIToken { // Other tokens IntegerLiteral, + FloatingPointLiteral, VirtualRegister, ConstantPoolItem, JumpTableIndex, diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index c71eeb99fca..da2a01366fd 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -14,6 +14,7 @@ #include "MIParser.h" #include "MILexer.h" #include "llvm/ADT/StringMap.h" +#include "llvm/AsmParser/Parser.h" #include "llvm/AsmParser/SlotMapping.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" @@ -113,6 +114,7 @@ public: bool parseSubRegisterIndex(unsigned &SubReg); bool parseRegisterOperand(MachineOperand &Dest, bool IsDef = false); bool parseImmediateOperand(MachineOperand &Dest); + bool parseFPImmediateOperand(MachineOperand &Dest); bool parseMBBReference(MachineBasicBlock *&MBB); bool parseMBBOperand(MachineOperand &Dest); bool parseStackObjectOperand(MachineOperand &Dest); @@ -528,6 +530,22 @@ bool MIParser::parseImmediateOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) { + auto Loc = Token.location(); + lex(); + if (Token.isNot(MIToken::FloatingPointLiteral)) + return error("expected a floating point literal"); + auto Source = StringRef(Loc, Token.stringValue().end() - Loc).str(); + lex(); + SMDiagnostic Err; + const Constant *C = + parseConstantValue(Source.c_str(), Err, *MF.getFunction()->getParent()); + if (!C) + return error(Loc + Err.getColumnNo(), Err.getMessage()); + Dest = MachineOperand::CreateFPImm(cast(C)); + return false; +} + bool MIParser::getUnsigned(unsigned &Result) { assert(Token.hasIntegerValue() && "Expected a token with an integer value"); const uint64_t Limit = uint64_t(std::numeric_limits::max()) + 1; @@ -860,6 +878,13 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) { return parseRegisterOperand(Dest); case MIToken::IntegerLiteral: return parseImmediateOperand(Dest); + case MIToken::kw_half: + case MIToken::kw_float: + case MIToken::kw_double: + case MIToken::kw_x86_fp80: + case MIToken::kw_fp128: + case MIToken::kw_ppc_fp128: + return parseFPImmediateOperand(Dest); case MIToken::MachineBasicBlock: return parseMBBOperand(Dest); case MIToken::StackObject: diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index f34cef7bcb4..664a0f532e9 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -513,6 +513,9 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { case MachineOperand::MO_Immediate: OS << Op.getImm(); break; + case MachineOperand::MO_FPImmediate: + Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); + break; case MachineOperand::MO_MachineBasicBlock: printMBBReference(*Op.getMBB()); break; diff --git a/test/CodeGen/MIR/NVPTX/expected-floating-point-literal.mir b/test/CodeGen/MIR/NVPTX/expected-floating-point-literal.mir new file mode 100644 index 00000000000..1a746ce802b --- /dev/null +++ b/test/CodeGen/MIR/NVPTX/expected-floating-point-literal.mir @@ -0,0 +1,26 @@ +# RUN: not llc -march=nvptx -mcpu=sm_20 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + define float @test(float %k) { + entry: + %0 = fadd float %k, 3.250000e+00 + ret float %0 + } + +... +--- +name: test +registers: + - { id: 0, class: float32regs } + - { id: 1, class: float32regs } +body: + - id: 0 + name: entry + instructions: + - '%0 = LD_f32_avar 0, 4, 1, 2, 32, $test_param_0' +# CHECK: [[@LINE+1]]:38: expected a floating point literal + - '%1 = FADD_rnf32ri %0, float 3' + - 'StoreRetvalF32 %1, 0' + - Return +... diff --git a/test/CodeGen/MIR/NVPTX/floating-point-immediate-operands.mir b/test/CodeGen/MIR/NVPTX/floating-point-immediate-operands.mir new file mode 100644 index 00000000000..3b2ae0f99ee --- /dev/null +++ b/test/CodeGen/MIR/NVPTX/floating-point-immediate-operands.mir @@ -0,0 +1,85 @@ +# RUN: llc -march=nvptx -mcpu=sm_20 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s +# This test ensures that the MIR parser parses floating point constant operands +# correctly. + +--- | + + define float @test(float %k, i32 %i) { + entry: + %0 = fpext float %k to double + %1 = fadd double %0, 3.250000e+00 + %2 = fptrunc double %1 to float + %3 = sitofp i32 %i to float + %4 = fadd float %3, 6.250000e+00 + %5 = fmul float %4, %2 + ret float %5 + } + + define float @test2(float %k, i32 %i) { + entry: + %0 = fpext float %k to double + %1 = fadd double %0, 0x7FF8000000000000 + %2 = fptrunc double %1 to float + %3 = sitofp i32 %i to float + %4 = fadd float %3, 0x7FF8000000000000 + %5 = fmul float %4, %2 + ret float %5 + } + +... +--- +name: test +registers: + - { id: 0, class: float32regs } + - { id: 1, class: float64regs } + - { id: 2, class: int32regs } + - { id: 3, class: float64regs } + - { id: 4, class: float32regs } + - { id: 5, class: float32regs } + - { id: 6, class: float32regs } + - { id: 7, class: float32regs } +body: + - id: 0 + name: entry + instructions: + - '%0 = LD_f32_avar 0, 4, 1, 2, 32, $test_param_0' + - '%1 = CVT_f64_f32 %0, 0' + - '%2 = LD_i32_avar 0, 4, 1, 0, 32, $test_param_1' +# CHECK: %3 = FADD_rnf64ri %1, double 3.250000e+00 + - '%3 = FADD_rnf64ri %1, double 3.250000e+00' + - '%4 = CVT_f32_f64 %3, 5' + - '%5 = CVT_f32_s32 %2, 5' +# CHECK: %6 = FADD_rnf32ri %5, float 6.250000e+00 + - '%6 = FADD_rnf32ri %5, float 6.250000e+00' + - '%7 = FMUL_rnf32rr %6, %4' + - 'StoreRetvalF32 %7, 0' + - Return +... +--- +name: test2 +registers: + - { id: 0, class: float32regs } + - { id: 1, class: float64regs } + - { id: 2, class: int32regs } + - { id: 3, class: float64regs } + - { id: 4, class: float32regs } + - { id: 5, class: float32regs } + - { id: 6, class: float32regs } + - { id: 7, class: float32regs } +body: + - id: 0 + name: entry + instructions: + - '%0 = LD_f32_avar 0, 4, 1, 2, 32, $test2_param_0' + - '%1 = CVT_f64_f32 %0, 0' + - '%2 = LD_i32_avar 0, 4, 1, 0, 32, $test2_param_1' +# CHECK: %3 = FADD_rnf64ri %1, double 0x7FF8000000000000 + - '%3 = FADD_rnf64ri %1, double 0x7FF8000000000000' + - '%4 = CVT_f32_f64 %3, 5' + - '%5 = CVT_f32_s32 %2, 5' +# CHECK: %6 = FADD_rnf32ri %5, float 0x7FF8000000000000 + - '%6 = FADD_rnf32ri %5, float 0x7FF8000000000000' + - '%7 = FMUL_rnf32rr %6, %4' + - 'StoreRetvalF32 %7, 0' + - Return +... diff --git a/test/CodeGen/MIR/NVPTX/floating-point-invalid-type-error.mir b/test/CodeGen/MIR/NVPTX/floating-point-invalid-type-error.mir new file mode 100644 index 00000000000..810fa15bedd --- /dev/null +++ b/test/CodeGen/MIR/NVPTX/floating-point-invalid-type-error.mir @@ -0,0 +1,26 @@ +# RUN: not llc -march=nvptx -mcpu=sm_20 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + define float @test(float %k) { + entry: + %0 = fadd float %k, 3.250000e+00 + ret float %0 + } + +... +--- +name: test +registers: + - { id: 0, class: float32regs } + - { id: 1, class: float32regs } +body: + - id: 0 + name: entry + instructions: + - '%0 = LD_f32_avar 0, 4, 1, 2, 32, $test_param_0' +# CHECK: [[@LINE+1]]:38: floating point constant does not have type 'float' + - '%1 = FADD_rnf32ri %0, float 0xH3C00' + - 'StoreRetvalF32 %1, 0' + - Return +... diff --git a/test/CodeGen/MIR/NVPTX/lit.local.cfg b/test/CodeGen/MIR/NVPTX/lit.local.cfg new file mode 100644 index 00000000000..2cb98eb371b --- /dev/null +++ b/test/CodeGen/MIR/NVPTX/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'NVPTX' in config.root.targets: + config.unsupported = True