Bug 315084 (MONO60056) - [PATCH] BIGMUL does not handle signs correctly
Summary: [PATCH] BIGMUL does not handle signs correctly
Status: RESOLVED FIXED
Alias: MONO60056
Product: Mono: Runtime
Classification: Mono
Component: misc (show other bugs)
Version: unspecified
Hardware: Other All
: P3 - Medium : Critical
Target Milestone: ---
Assignee: Mono Bugs
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-06-11 23:12 UTC by Sebastien Pouliot
Modified: 2007-09-15 21:24 UTC (History)
1 user (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
Patch (797 bytes, patch)
2004-06-12 07:25 UTC, Thomas Wiest
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 18:41:58 UTC


---- Reported by sebastien@ximian.com 2004-06-11 16:12:05 MST ----

Description of Problem:
Multiplying a long with a negative integer results in a big positive
integer. There are no (visible) overflow involved.


Steps to reproduce the problem:
1. Compile the following source

using System;
class T {
	static void Main () {
		int seconds = -59;
		Console.Out.WriteLine ("{0} * {1} == {2}", TimeSpan.TicksPerSecond,
seconds, (TimeSpan.TicksPerSecond * seconds));
	}
}

2. Execute


Actual Results (Mono):

10000000 * -59 == 42949672370000000


Expected Results:

10000000 * -59 == -590000000


How often does this happen? 
Always


Additional Information:
The same binary gives the right result when executed by the MS runtime.



---- Additional Comments From bmaurer@users.sf.net 2004-06-12 00:11:30 MST ----

Simpler:

class T {
	static void Main () {
		const long a = 1;
		int b = -59;
		
		System.Console.WriteLine (a * b);
	}
}
Gives:
4294967237




---- Additional Comments From bmaurer@users.sf.net 2004-06-12 00:12:51 MST ----

nb: 4294967237 == 0xFFFFFFC5. We want 0xFFFFFFFFFFFFFFC5.

I think we need cdq in here somewhere...



---- Additional Comments From bmaurer@users.sf.net 2004-06-12 00:19:27 MST ----

converting method T:Main ()
creating vars
creating locals
locals done
method to IR T:Main ()
converting (in B2: stack: 0) IL_0000: ldc.i4.s  -59
converting (in B2: stack: 1) IL_0002: stloc.1   
converting (in B2: stack: 0) IL_0003: ldc.i4.1  
converting (in B2: stack: 1) IL_0004: conv.u8   
converting (in B2: stack: 1) IL_0005: ldloc.1   
converting (in B2: stack: 2) IL_0006: conv.i8   
converting (in B2: stack: 2) IL_0007: mul       
converting (in B2: stack: 1) IL_0008: call      0x0a000002
converting (in B2: stack: 0) IL_000d: ret       
REGION BB0 IL_0000 ID_FFFFFFFF
REGION BB3 IL_0000 ID_FFFFFFFF
REGION BB2 IL_000d ID_FFFFFFFF
REGION BB1 IL_0000 ID_FFFFFFFF
block merge triggered 3 -> 2
br removal triggered 3 -> 1
REGVAR 1 C3 R7
DUMP BLOCK 0:
DUMP BLOCK 3:
 (stind.i8 regoffset[-0x10(%ebp)] i8const[0])
 (stind.i4 regvar[%edi] iconst[0])
 (stind.i4 regvar[%edi] iconst[-59])
 (stind.i8 regoffset[-0x18(%ebp)] (op_bigmul_un iconst[1] (ldind.i4
regvar[%edi])))
 (outarg (ldind.i8 regoffset[-0x18(%ebp)]))
 voidcall[WriteLine]
 nop

...

  15:	bf 00 00 00 00       	mov    edi,0x0
  1a:	bf c5 ff ff ff       	mov    edi,0xffffffc5
  1f:	b8 01 00 00 00       	mov    eax,0x1
  24:	8b cf                	mov    ecx,edi
  26:	f7 e1                	mul    ecx



---- Additional Comments From bmaurer@users.sf.net 2004-06-12 00:25:59 MST ----

Created an attachment (id=166244)
Patch




---- Additional Comments From bmaurer@users.sf.net 2004-06-12 00:27:46 MST ----

This patch makes the BIGMUL code require that the two operands of the
multiply use the same conversion op. E.g, ((ulong) x) * ((long) y)
will need to use the long path.



---- Additional Comments From bmaurer@users.sf.net 2004-06-12 12:55:45 MST ----

FIXED in cvs.

Imported an attachment (id=166244)