Index: include/llvm/CodeGen/MachineInstr.h =================================================================== --- include/llvm/CodeGen/MachineInstr.h +++ include/llvm/CodeGen/MachineInstr.h @@ -97,8 +97,14 @@ // 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: Index: lib/CodeGen/MIRParser/MILexer.h =================================================================== --- lib/CodeGen/MIRParser/MILexer.h +++ lib/CodeGen/MIRParser/MILexer.h @@ -71,6 +71,9 @@ kw_contract, kw_afn, kw_reassoc, + kw_nuw, + kw_nsw, + kw_exact, kw_debug_location, kw_cfi_same_value, kw_cfi_offset, Index: lib/CodeGen/MIRParser/MILexer.cpp =================================================================== --- lib/CodeGen/MIRParser/MILexer.cpp +++ lib/CodeGen/MIRParser/MILexer.cpp @@ -202,6 +202,9 @@ .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) Index: lib/CodeGen/MIRParser/MIParser.cpp =================================================================== --- lib/CodeGen/MIRParser/MIParser.cpp +++ lib/CodeGen/MIRParser/MIParser.cpp @@ -963,7 +963,10 @@ 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 @@ 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(); } Index: lib/CodeGen/MIRPrinter.cpp =================================================================== --- lib/CodeGen/MIRPrinter.cpp +++ lib/CodeGen/MIRPrinter.cpp @@ -695,6 +695,12 @@ 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) Index: lib/CodeGen/MachineInstr.cpp =================================================================== --- lib/CodeGen/MachineInstr.cpp +++ lib/CodeGen/MachineInstr.cpp @@ -1479,6 +1479,12 @@ 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) Index: test/CodeGen/MIR/X86/copyIRflags.mir =================================================================== --- test/CodeGen/MIR/X86/copyIRflags.mir +++ test/CodeGen/MIR/X86/copyIRflags.mir @@ -8,11 +8,12 @@ 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