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

remove ASM div64_32() implementation #2220

Merged
merged 2 commits into from
Mar 4, 2025
Merged

Conversation

fabiangreffrath
Copy link
Owner

@fabiangreffrath fabiangreffrath commented Mar 3, 2025

  • Prone to miscompilation
  • Only helps with very old PCs
  • Really only helps with voxel rendering

Fixes #2219

src/m_fixed.h Outdated
@@ -38,8 +38,8 @@
{
return a / b;
}
int32_t lo = a;
int32_t hi = a >> 32;
volatile int32_t lo = a;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about int32_t lo = (int32_t) a;?
It seems to be another case of UB that will differ in various versions of compilers.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From Linux kernel:

	union {
		u64 v64;
		u32 v32[2];
	} d = { dividend };
	u32 upper;

	upper = d.v32[1];

https://github.com/torvalds/linux/blob/7eb172143d5508b4da468ed59ee857c6e5e01da6/arch/x86/include/asm/div64.h#L45C2-L52C15

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried this, same crash.

--- a/src/m_fixed.h
+++ b/src/m_fixed.h
@@ -38,8 +38,14 @@
       {
           return a / b;
       }
-      int32_t lo = a;
-      int32_t hi = a >> 32;
+      union {
+          int64_t v64;
+          int32_t v32[2];
+      } d = {a};
+
+      int32_t lo = d.v32[0];
+      int32_t hi = d.v32[1];
+
       asm("idivl %[divisor]" : "+a" (lo), "+d" (hi) : [divisor] "r" (b));
       return lo;
   }

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about int32_t lo = (int32_t) a;?

Same crash.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the problem is that a and b are both input and output variables to the asm() call. However, the issue is very compiler specific. Ubuntu-latest uses gcc-11.2 and I cannot reproduce it with gcc-14.2 on my main system with the exact same build flags. Also, it is optimization specific and won't occur with gcc-11.2 in a debug build with -O0.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I don't understand why volatile works, some kind of miscompilation? I think we should just remove the GCC version of div64_32.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminds me of this bug, where we also never really understood what was going on:

3c526e7

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a miscompilation with Clang -O3. May be fixed in newer versions of the compiler.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's possible the same thing happens here with gcc-11.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I suggest to remove the GCC version of div64_32. It helps only for old CPUs and is only noticeable with voxels (we have very few FixedDiv in other code).

@MrAlaux
Copy link
Collaborator

MrAlaux commented Mar 3, 2025

The original reporter tried this and said that it fixed the crash.

* Prone to miscompilation
* Only helps with very old PCs
* Really only helps with voxel rendering
@fabiangreffrath fabiangreffrath changed the title declare lo and hi in div64_32() as volatile remove ASM div64_32() implementation Mar 4, 2025
@fabiangreffrath fabiangreffrath merged commit b89a6ae into master Mar 4, 2025
8 checks passed
@fabiangreffrath fabiangreffrath deleted the volatile_div64_32 branch March 4, 2025 12:02
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

Successfully merging this pull request may close these issues.

Voxels crash in Linux
3 participants