diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index 10b30b69471927fa7e87280ad60007a6becca6a1..c3403ea47d5b6dafb7ef5fe204f3c395a5014895 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -97,8 +97,14 @@ public: // contraction operations like fma. FmAfn = 1 << 9, // Instruction may map to Fast math // instrinsic approximation. - FmReassoc = 1 << 10 // Instruction supports Fast math + FmReassoc = 1 << 10, // Instruction supports Fast math // reassociation of operand order. + NoUWrap = 1 << 11, // Instruction supports binary operator + // no unsigned wrap. + NoSWrap = 1 << 12, // Instruction supports binary operator + // no signed wrap. + IsExact = 1 << 13 // Instruction supports division is + // known to be exact. }; private: diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp index e3f19f011ce6c8ea802f736558528c02cf2bb8d0..f7cc94e34a59e7e151b136a856ea9c931bd98300 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -202,6 +202,9 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case("contract", MIToken::kw_contract) .Case("afn", MIToken::kw_afn) .Case("reassoc", MIToken::kw_reassoc) + .Case("nuw" , MIToken::kw_nuw) + .Case("nsw" , MIToken::kw_nsw) + .Case("exact" , MIToken::kw_exact) .Case("debug-location", MIToken::kw_debug_location) .Case("same_value", MIToken::kw_cfi_same_value) .Case("offset", MIToken::kw_cfi_offset) diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h index d2dc5511b25dfd5e0a3aa1d9d0ba930baa34fc9e..dffa4f745444e03f4b4ca8f86fae7a0222dd5979 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -71,6 +71,9 @@ struct MIToken { kw_contract, kw_afn, kw_reassoc, + kw_nuw, + kw_nsw, + kw_exact, kw_debug_location, kw_cfi_same_value, kw_cfi_offset, diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 7ba75c130844400a544f5557e64232fd7c73509b..5c6a41af97adc043f7914f5d6dd9bd045e2c80e0 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -963,7 +963,10 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { Token.is(MIToken::kw_arcp) || Token.is(MIToken::kw_contract) || Token.is(MIToken::kw_afn) || - Token.is(MIToken::kw_reassoc)) { + Token.is(MIToken::kw_reassoc) || + Token.is(MIToken::kw_nuw) || + Token.is(MIToken::kw_nsw) || + Token.is(MIToken::kw_exact)) { // Mine frame and fast math flags if (Token.is(MIToken::kw_frame_setup)) Flags |= MachineInstr::FrameSetup; @@ -983,6 +986,12 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { Flags |= MachineInstr::FmAfn; if (Token.is(MIToken::kw_reassoc)) Flags |= MachineInstr::FmReassoc; + if (Token.is(MIToken::kw_nuw)) + Flags |= MachineInstr::NoUWrap; + if (Token.is(MIToken::kw_nsw)) + Flags |= MachineInstr::NoSWrap; + if (Token.is(MIToken::kw_exact)) + Flags |= MachineInstr::IsExact; lex(); } diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp index 67c54631fa6b852ad04e19efa9cfe960eaf399b9..20533f9095459160c6aec58232a6649bb89824f1 100644 --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -695,6 +695,12 @@ void MIPrinter::print(const MachineInstr &MI) { OS << "afn "; if (MI.getFlag(MachineInstr::FmReassoc)) OS << "reassoc "; + if (MI.getFlag(MachineInstr::NoUWrap)) + OS << "nuw "; + if (MI.getFlag(MachineInstr::NoSWrap)) + OS << "nsw "; + if (MI.getFlag(MachineInstr::IsExact)) + OS << "exact "; OS << TII->getName(MI.getOpcode()); if (I < E) diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 4c0d53ce9aa3bf755ff6e5e2e728ed759de7de77..37e23aee00045108e8305f0fde1af27c7b325479 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -1479,6 +1479,12 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, OS << "afn "; if (getFlag(MachineInstr::FmReassoc)) OS << "reassoc "; + if (getFlag(MachineInstr::NoUWrap)) + OS << "nuw "; + if (getFlag(MachineInstr::NoSWrap)) + OS << "nsw "; + if (getFlag(MachineInstr::IsExact)) + OS << "exact "; // Print the opcode name. if (TII) diff --git a/llvm/test/CodeGen/MIR/X86/copyIRflags.mir b/llvm/test/CodeGen/MIR/X86/copyIRflags.mir index a562ef6d025e5f08827476e17a5d5959d7f8c0c3..27eb9feb92bae4376a17b6affec9307165dea082 100644 --- a/llvm/test/CodeGen/MIR/X86/copyIRflags.mir +++ b/llvm/test/CodeGen/MIR/X86/copyIRflags.mir @@ -8,11 +8,12 @@ body: | bb.0.entry: liveins: $eax - $eax = ADD32rr $eax, killed $eax, implicit-def dead $eflags - ; CHECK: $eax = ADD32rr $eax, killed $eax, implicit-def dead $eflags - $eax = ADD32rr $eax, killed $eax, implicit-def dead $eflags - ; CHECK: $eax = SAR32ri $eax, 1, implicit-def dead $eflags - $eax = SAR32ri $eax, 1, implicit-def dead $eflags + ; CHECK: $eax = nsw ADD32rr $eax, killed $eax, implicit-def dead $eflags + $eax = nsw ADD32rr $eax, killed $eax, implicit-def dead $eflags + ; CHECK: $eax = nuw ADD32rr $eax, killed $eax, implicit-def dead $eflags + $eax = nuw ADD32rr $eax, killed $eax, implicit-def dead $eflags + ; CHECK: $eax = exact SAR32ri $eax, 1, implicit-def dead $eflags + $eax = exact SAR32ri $eax, 1, implicit-def dead $eflags ; CHECK: RET 0, $eax RET 0, $eax