Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hashlink floating point exception with remainder operator #730

Open
PXshadow opened this issue Dec 7, 2024 · 5 comments
Open

Hashlink floating point exception with remainder operator #730

PXshadow opened this issue Dec 7, 2024 · 5 comments

Comments

@PXshadow
Copy link

PXshadow commented Dec 7, 2024

function main() {
	var x = (-1 << 31);
	var y = -1;
	trace(x % y);
}

Haxe nightly: c4868e5
Hashlink: 1.14.0

@Apprentice-Alchemist
Copy link
Contributor

In this case floating point exception actually means integer overflow.
This is an edge case that needs to be worked around either in genhl or in the JIT.

@yuxiaomao
Copy link
Collaborator

I confirm that it's an integer overflow, and can be reproduce with hl/c too if the optimization is disabled.
This is indeed an edge case :(

https://wiki.sei.cmu.edu/confluence/display/c/INT33-C.+Ensure+that+division+and+remainder+operations+do+not+result+in+divide-by-zero+errors
Overflow can occur during a remainder operation when the dividend is equal to the minimum (negative) value for the signed integer type and the divisor is equal to −1.

@ncannasse
Copy link
Member

Interesting, that's a new class of exception that I just learnt.
In 32 bits it only occurs with these two values exactly, so I guess the best choice is to generate HL/C + JIT code to test divide by (-1) after we checked 0 and if it's the case perform a IMULT instead of a IDIV.

@yuxiaomao
Copy link
Collaborator

I can't see a case where % -1 does not return 0, except when overflow occurs; so I'm going to say : r = (b == 0 || b == -1) ? 0 : a % b in HLC(haxe)/JIT(hashlink)

@yuxiaomao
Copy link
Collaborator

Nicolas explained to me x)

OSMod: r = (b == 0 || b == -1) ? 0 : a % b
OSDiv: r = (b == 0 || b == -1) ? a * b : a / b with IMUL

OSDiv can be triggered with the following code:

static function main() {
	var x = -1 << 31;
	var y = -1;
	var z = Std.int(x / y);
	trace(z);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants