Index: llvm/trunk/include/llvm/CodeGen/MachineInstr.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h @@ -80,7 +80,21 @@ FrameDestroy = 1 << 1, // Instruction is used as a part of // function frame destruction code. BundledPred = 1 << 2, // Instruction has bundled predecessors. - BundledSucc = 1 << 3 // Instruction has bundled successors. + BundledSucc = 1 << 3, // Instruction has bundled successors. + FmNoNans = 1 << 4, // Instruction does not support Fast + // math nan values. + FmNoInfs = 1 << 5, // Instruction does not support Fast + // math infinity values. + FmNsz = 1 << 6, // Instruction is not required to retain + // signed zero values. + FmArcp = 1 << 7, // Instruction supports Fast math + // reciprocal approximations. + FmContract = 1 << 8, // Instruction supports Fast math + // contraction operations like fma. + FmAfn = 1 << 9, // Instruction may map to Fast math + // instrinsic approximation. + FmReassoc = 1 << 10 // Instruction supports Fast math + // reassociation of operand order. }; private: @@ -93,7 +107,7 @@ using OperandCapacity = ArrayRecycler::Capacity; OperandCapacity CapOperands; // Capacity of the Operands array. - uint8_t Flags = 0; // Various bits of additional + uint16_t Flags = 0; // Various bits of additional // information about machine // instruction. @@ -186,7 +200,7 @@ /// Set a MI flag. void setFlag(MIFlag Flag) { - Flags |= (uint8_t)Flag; + Flags |= (uint16_t)Flag; } void setFlags(unsigned flags) { @@ -197,7 +211,7 @@ /// clearFlag - Clear a MI flag. void clearFlag(MIFlag Flag) { - Flags &= ~((uint8_t)Flag); + Flags &= ~((uint16_t)Flag); } /// Return true if MI is in a bundle (but not the first MI in a bundle). Index: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h +++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h @@ -64,6 +64,13 @@ kw_tied_def, kw_frame_setup, kw_frame_destroy, + kw_nnan, + kw_ninf, + kw_nsz, + kw_arcp, + kw_contract, + kw_afn, + kw_reassoc, kw_debug_location, kw_cfi_same_value, kw_cfi_offset, Index: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp @@ -212,6 +212,13 @@ .Case("tied-def", MIToken::kw_tied_def) .Case("frame-setup", MIToken::kw_frame_setup) .Case("frame-destroy", MIToken::kw_frame_destroy) + .Case("nnan", MIToken::kw_nnan) + .Case("ninf", MIToken::kw_ninf) + .Case("nsz", MIToken::kw_nsz) + .Case("arcp", MIToken::kw_arcp) + .Case("contract", MIToken::kw_contract) + .Case("afn", MIToken::kw_afn) + .Case("reassoc", MIToken::kw_reassoc) .Case("debug-location", MIToken::kw_debug_location) .Case("same_value", MIToken::kw_cfi_same_value) .Case("offset", MIToken::kw_cfi_offset) Index: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp @@ -936,13 +936,36 @@ } bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { - // Allow both: - // * frame-setup frame-destroy OPCODE - // * frame-destroy frame-setup OPCODE + // Allow frame and fast math flags for OPCODE while (Token.is(MIToken::kw_frame_setup) || - Token.is(MIToken::kw_frame_destroy)) { - Flags |= Token.is(MIToken::kw_frame_setup) ? MachineInstr::FrameSetup - : MachineInstr::FrameDestroy; + Token.is(MIToken::kw_frame_destroy) || + Token.is(MIToken::kw_nnan) || + Token.is(MIToken::kw_ninf) || + Token.is(MIToken::kw_nsz) || + Token.is(MIToken::kw_arcp) || + Token.is(MIToken::kw_contract) || + Token.is(MIToken::kw_afn) || + Token.is(MIToken::kw_reassoc)) { + // Mine frame and fast math flags + if (Token.is(MIToken::kw_frame_setup)) + Flags |= MachineInstr::FrameSetup; + if (Token.is(MIToken::kw_frame_destroy)) + Flags |= MachineInstr::FrameDestroy; + if (Token.is(MIToken::kw_nnan)) + Flags |= MachineInstr::FmNoNans; + if (Token.is(MIToken::kw_ninf)) + Flags |= MachineInstr::FmNoInfs; + if (Token.is(MIToken::kw_nsz)) + Flags |= MachineInstr::FmNsz; + if (Token.is(MIToken::kw_arcp)) + Flags |= MachineInstr::FmArcp; + if (Token.is(MIToken::kw_contract)) + Flags |= MachineInstr::FmContract; + if (Token.is(MIToken::kw_afn)) + Flags |= MachineInstr::FmAfn; + if (Token.is(MIToken::kw_reassoc)) + Flags |= MachineInstr::FmReassoc; + lex(); } if (Token.isNot(MIToken::Identifier)) Index: llvm/trunk/lib/CodeGen/MIRPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRPrinter.cpp +++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp @@ -680,6 +680,20 @@ OS << "frame-setup "; if (MI.getFlag(MachineInstr::FrameDestroy)) OS << "frame-destroy "; + if (MI.getFlag(MachineInstr::FmNoNans)) + OS << "nnan "; + if (MI.getFlag(MachineInstr::FmNoInfs)) + OS << "ninf "; + if (MI.getFlag(MachineInstr::FmNsz)) + OS << "nsz "; + if (MI.getFlag(MachineInstr::FmArcp)) + OS << "arcp "; + if (MI.getFlag(MachineInstr::FmContract)) + OS << "contract "; + if (MI.getFlag(MachineInstr::FmAfn)) + OS << "afn "; + if (MI.getFlag(MachineInstr::FmReassoc)) + OS << "reassoc "; OS << TII->getName(MI.getOpcode()); if (I < E) Index: llvm/trunk/lib/CodeGen/MachineInstr.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp @@ -1302,6 +1302,20 @@ OS << "frame-setup "; if (getFlag(MachineInstr::FrameDestroy)) OS << "frame-destroy "; + if (getFlag(MachineInstr::FmNoNans)) + OS << "nnan "; + if (getFlag(MachineInstr::FmNoInfs)) + OS << "ninf "; + if (getFlag(MachineInstr::FmNsz)) + OS << "nsz "; + if (getFlag(MachineInstr::FmArcp)) + OS << "arcp "; + if (getFlag(MachineInstr::FmContract)) + OS << "contract "; + if (getFlag(MachineInstr::FmAfn)) + OS << "afn "; + if (getFlag(MachineInstr::FmReassoc)) + OS << "reassoc "; // Print the opcode name. if (TII) Index: llvm/trunk/test/CodeGen/MIR/X86/fastmath.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/X86/fastmath.mir +++ llvm/trunk/test/CodeGen/MIR/X86/fastmath.mir @@ -0,0 +1,36 @@ +# RUN: llc -march=x86-64 -run-pass none -o - %s | FileCheck %s +# This test ensures that the MIR parser parses the fast math instruction flags. + +... +--- +name: baz +body: | + bb.0.entry: + liveins: $xmm0 + + ; CHECK: %0:fr32 = COPY $xmm0 + %0:fr32 = COPY $xmm0 + ; CHECK: %1:fr32 = nnan VMULSSrr %0, %0 + %1:fr32 = nnan VMULSSrr %0, %0 + ; CHECK: %2:fr32 = ninf VMULSSrr %1, %1 + %2:fr32 = ninf VMULSSrr %1, %1 + ; CHECK: %3:fr32 = nsz VMULSSrr %2, %2 + %3:fr32 = nsz VMULSSrr %2, %2 + ; CHECK: %4:fr32 = arcp VMULSSrr %3, %3 + %4:fr32 = arcp VMULSSrr %3, %3 + ; CHECK: %5:fr32 = contract VMULSSrr %4, %4 + %5:fr32 = contract VMULSSrr %4, %4 + ; CHECK: %6:fr32 = afn VMULSSrr %5, %5 + %6:fr32 = afn VMULSSrr %5, %5 + ; CHECK: %7:fr32 = reassoc VMULSSrr %6, %6 + %7:fr32 = reassoc VMULSSrr %6, %6 + ; CHECK: %8:fr32 = nsz arcp contract afn reassoc VMULSSrr %7, %7 + %8:fr32 = nsz arcp contract afn reassoc VMULSSrr %7, %7 + ; CHECK: %9:fr32 = contract afn reassoc VMULSSrr %8, %8 + %9:fr32 = contract afn reassoc VMULSSrr %8, %8 + ; CHECK: $xmm0 = COPY %9 + $xmm0 = COPY %9 + ; CHECK: RET 0, $xmm0 + RET 0, $xmm0 + +...