@@ -76,6 +76,24 @@ class LLVM_IntArithmeticOpWithOverflowFlag<string mnemonic, string instName,
7676 "$res = builder.Create" # instName #
7777 "($lhs, $rhs, /*Name=*/\"\", op.hasNoUnsignedWrap(), op.hasNoSignedWrap());";
7878}
79+ class LLVM_IntArithmeticOpWithExactFlag<string mnemonic, string instName,
80+ list<Trait> traits = []> :
81+ LLVM_ArithmeticOpBase<AnySignlessInteger, mnemonic, instName,
82+ !listconcat([DeclareOpInterfaceMethods<ExactFlagInterface>], traits)> {
83+ let arguments = !con(commonArgs, (ins UnitAttr:$isExact));
84+
85+ string mlirBuilder = [{
86+ auto op = $_builder.create<$_qualCppClassName>($_location, $lhs, $rhs);
87+ moduleImport.setExactFlag(inst, op);
88+ $res = op;
89+ }];
90+ let assemblyFormat = [{
91+ (`exact` $isExact^)? $lhs `,` $rhs custom<LLVMOpAttrs>(attr-dict) `:` type($res)
92+ }];
93+ string llvmBuilder =
94+ "$res = builder.Create" # instName #
95+ "($lhs, $rhs, /*Name=*/\"\", op.getIsExact());";
96+ }
7997class LLVM_FloatArithmeticOp<string mnemonic, string instName,
8098 list<Trait> traits = []> :
8199 LLVM_ArithmeticOpBase<LLVM_AnyFloat, mnemonic, instName,
@@ -116,8 +134,8 @@ def LLVM_AddOp : LLVM_IntArithmeticOpWithOverflowFlag<"add", "Add",
116134def LLVM_SubOp : LLVM_IntArithmeticOpWithOverflowFlag<"sub", "Sub", []>;
117135def LLVM_MulOp : LLVM_IntArithmeticOpWithOverflowFlag<"mul", "Mul",
118136 [Commutative]>;
119- def LLVM_UDivOp : LLVM_IntArithmeticOp <"udiv", "UDiv">;
120- def LLVM_SDivOp : LLVM_IntArithmeticOp <"sdiv", "SDiv">;
137+ def LLVM_UDivOp : LLVM_IntArithmeticOpWithExactFlag <"udiv", "UDiv">;
138+ def LLVM_SDivOp : LLVM_IntArithmeticOpWithExactFlag <"sdiv", "SDiv">;
121139def LLVM_URemOp : LLVM_IntArithmeticOp<"urem", "URem">;
122140def LLVM_SRemOp : LLVM_IntArithmeticOp<"srem", "SRem">;
123141def LLVM_AndOp : LLVM_IntArithmeticOp<"and", "And">;
@@ -128,8 +146,8 @@ def LLVM_XOrOp : LLVM_IntArithmeticOp<"xor", "Xor">;
128146def LLVM_ShlOp : LLVM_IntArithmeticOpWithOverflowFlag<"shl", "Shl", []> {
129147 let hasFolder = 1;
130148}
131- def LLVM_LShrOp : LLVM_IntArithmeticOp <"lshr", "LShr">;
132- def LLVM_AShrOp : LLVM_IntArithmeticOp <"ashr", "AShr">;
149+ def LLVM_LShrOp : LLVM_IntArithmeticOpWithExactFlag <"lshr", "LShr">;
150+ def LLVM_AShrOp : LLVM_IntArithmeticOpWithExactFlag <"ashr", "AShr">;
133151
134152// Base class for compare operations. A compare operation takes two operands
135153// of the same type and returns a boolean result. If the operands are
0 commit comments