Skip to content

Commit 7dbafcf

Browse files
authored
Merge pull request #522 from dadhi/copilot/fix-modulo-instruction-issue
Emit `rem.un` for unsigned modulo expressions
2 parents 64141ec + 70d2be2 commit 7dbafcf

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5929,7 +5929,7 @@ private static bool TryEmitArithmeticOperation(Type leftType, Type rightType, Ex
59295929
ExpressionType.Multiply => OpCodes.Mul,
59305930
ExpressionType.MultiplyChecked => exprType.IsUnsigned() ? OpCodes.Mul_Ovf_Un : OpCodes.Mul_Ovf,
59315931
ExpressionType.Divide => OpCodes.Div,
5932-
ExpressionType.Modulo => OpCodes.Rem,
5932+
ExpressionType.Modulo => exprType.IsUnsigned() ? OpCodes.Rem_Un : OpCodes.Rem,
59335933
ExpressionType.And => OpCodes.And,
59345934
ExpressionType.Or => OpCodes.Or,
59355935
ExpressionType.ExclusiveOr => OpCodes.Xor,

test/FastExpressionCompiler.UnitTests/ArithmeticOperationsTests.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Numerics;
3+
using System.Reflection.Emit;
34

45
#if LIGHT_EXPRESSION
56
using static FastExpressionCompiler.LightExpression.Expression;
@@ -18,6 +19,7 @@ public int Run()
1819
Can_modulus_custom_in_Action();
1920
Can_add_string_and_not_string();
2021
Can_modulus_custom();
22+
Can_modulus_with_unsigned_block_local_variable();
2123
Can_sum_bytes_converted_to_ints();
2224
Can_sum_signed_bytes_converted_to_ints();
2325
Can_sum_all_primitive_numeric_types_that_define_binary_operator_add();
@@ -47,7 +49,7 @@ public int Run()
4749
Can_calculate_arithmetic_operation_with_vectors();
4850
Can_add_strings();
4951

50-
return 29;
52+
return 30;
5153
}
5254

5355
public void Can_sum_bytes_converted_to_ints()
@@ -229,6 +231,31 @@ public void Can_modulus()
229231
Asserts.AreEqual(1, f(7, 6));
230232
}
231233

234+
public void Can_modulus_with_unsigned_block_local_variable()
235+
{
236+
var b = Parameter(typeof(uint), "b");
237+
var a = Variable(typeof(uint), "a");
238+
var expr = Lambda<Func<uint, uint>>(
239+
Block(new[] { a },
240+
Assign(a, Constant(0x80000000u)),
241+
Modulo(a, b)),
242+
b);
243+
244+
var fs = expr.CompileSys();
245+
var ff = expr.CompileFast(true, CompilerFlags.EnableDelegateDebugInfo);
246+
247+
Asserts.AreEqual(2u, fs(3u));
248+
Asserts.AreEqual(2u, ff(3u));
249+
ff.AssertOpCodes(
250+
OpCodes.Ldc_I4,
251+
OpCodes.Stloc_0,
252+
OpCodes.Ldloc_0,
253+
OpCodes.Ldarg_1,
254+
OpCodes.Rem_Un,
255+
OpCodes.Ret
256+
);
257+
}
258+
232259

233260
public void Can_bit_or_1()
234261
{

0 commit comments

Comments
 (0)