mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
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
This commit is contained in:
parent
82e3e48d52
commit
c225eda1f1
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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<ConstantFP>(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<unsigned>::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:
|
||||
|
@ -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;
|
||||
|
26
test/CodeGen/MIR/NVPTX/expected-floating-point-literal.mir
Normal file
26
test/CodeGen/MIR/NVPTX/expected-floating-point-literal.mir
Normal file
@ -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
|
||||
...
|
85
test/CodeGen/MIR/NVPTX/floating-point-immediate-operands.mir
Normal file
85
test/CodeGen/MIR/NVPTX/floating-point-immediate-operands.mir
Normal file
@ -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
|
||||
...
|
26
test/CodeGen/MIR/NVPTX/floating-point-invalid-type-error.mir
Normal file
26
test/CodeGen/MIR/NVPTX/floating-point-invalid-type-error.mir
Normal file
@ -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
|
||||
...
|
2
test/CodeGen/MIR/NVPTX/lit.local.cfg
Normal file
2
test/CodeGen/MIR/NVPTX/lit.local.cfg
Normal file
@ -0,0 +1,2 @@
|
||||
if not 'NVPTX' in config.root.targets:
|
||||
config.unsupported = True
|
Loading…
Reference in New Issue
Block a user