diff --git a/src/FastExpressionCompiler/FastExpressionCompiler.cs b/src/FastExpressionCompiler/FastExpressionCompiler.cs index 7780f141..53fdbf17 100644 --- a/src/FastExpressionCompiler/FastExpressionCompiler.cs +++ b/src/FastExpressionCompiler/FastExpressionCompiler.cs @@ -5929,7 +5929,7 @@ private static bool TryEmitArithmeticOperation(Type leftType, Type rightType, Ex ExpressionType.Multiply => OpCodes.Mul, ExpressionType.MultiplyChecked => exprType.IsUnsigned() ? OpCodes.Mul_Ovf_Un : OpCodes.Mul_Ovf, ExpressionType.Divide => OpCodes.Div, - ExpressionType.Modulo => OpCodes.Rem, + ExpressionType.Modulo => exprType.IsUnsigned() ? OpCodes.Rem_Un : OpCodes.Rem, ExpressionType.And => OpCodes.And, ExpressionType.Or => OpCodes.Or, ExpressionType.ExclusiveOr => OpCodes.Xor, diff --git a/test/FastExpressionCompiler.UnitTests/ArithmeticOperationsTests.cs b/test/FastExpressionCompiler.UnitTests/ArithmeticOperationsTests.cs index 1883430a..b6554942 100644 --- a/test/FastExpressionCompiler.UnitTests/ArithmeticOperationsTests.cs +++ b/test/FastExpressionCompiler.UnitTests/ArithmeticOperationsTests.cs @@ -1,5 +1,6 @@ using System; using System.Numerics; +using System.Reflection.Emit; #if LIGHT_EXPRESSION using static FastExpressionCompiler.LightExpression.Expression; @@ -18,6 +19,7 @@ public int Run() Can_modulus_custom_in_Action(); Can_add_string_and_not_string(); Can_modulus_custom(); + Can_modulus_with_unsigned_block_local_variable(); Can_sum_bytes_converted_to_ints(); Can_sum_signed_bytes_converted_to_ints(); Can_sum_all_primitive_numeric_types_that_define_binary_operator_add(); @@ -47,7 +49,7 @@ public int Run() Can_calculate_arithmetic_operation_with_vectors(); Can_add_strings(); - return 29; + return 30; } public void Can_sum_bytes_converted_to_ints() @@ -229,6 +231,31 @@ public void Can_modulus() Asserts.AreEqual(1, f(7, 6)); } + public void Can_modulus_with_unsigned_block_local_variable() + { + var b = Parameter(typeof(uint), "b"); + var a = Variable(typeof(uint), "a"); + var expr = Lambda>( + Block(new[] { a }, + Assign(a, Constant(0x80000000u)), + Modulo(a, b)), + b); + + var fs = expr.CompileSys(); + var ff = expr.CompileFast(true, CompilerFlags.EnableDelegateDebugInfo); + + Asserts.AreEqual(2u, fs(3u)); + Asserts.AreEqual(2u, ff(3u)); + ff.AssertOpCodes( + OpCodes.Ldc_I4, + OpCodes.Stloc_0, + OpCodes.Ldloc_0, + OpCodes.Ldarg_1, + OpCodes.Rem_Un, + OpCodes.Ret + ); + } + public void Can_bit_or_1() {