Skip to content

[Bug Fix] Fixed dangling pointers that confuse Register Allocator in rare circumstances

Summary

This merge request fixes an error that can sometimes occur in the register allocator which results in bad code to be generated. This is caused by dangling pointers in an internal marker that, while themselves don't cause an error (since they're not dereferenced), confuses the register allocator that expects either nil or a different, specific pointer.

The dangling pointers were caused by instruction removal through the taicpu.is_same_reg_move method. The register allocator now scans nearby tai_regalloc markers to see if belong to the instruction about to be removed, and sets their assigned instruction to 'nil'.

Additionally, the register allocator would sometimes behave differently if certain debugging flags were enabled, or if -alrt (or part of it) was specified. The register allocator will now skip over these markers in the assembly list instead of stopping on them, especially as they wouldn't normally be present otherwise.

This merge request fixes #41270 (closed).

This merge request fixes #40012 (closed).

System

  • Processor architecture: Cross-platform

What is the current bug behavior?

In rare circumstances, the register allocator would get confused and potentially reallocate a register that is still in use. In the code example over at #41270 (closed) (replicated as a new test), this caused an access violation.

What is the behavior after applying this patch?

The register allocator should no longer make such a mistake.

Relevant logs and/or screenshots

For the test in question... before:

	...
# [32] h:=s+palu[i+i+0]; // <- ACCESS VIOLATION:  addsd xmm0,[rax*8+rax]
	movslq	%edx,%rax
	# Register edx released
	# Register rdx allocated
	movslq	%edx,%rdx
	# Register rax,rdx released
	# Register rax allocated
	leaq	(%rax,%rdx),%rax
	# Register xmm0,rax released
	# Register xmm0,rax allocated
	movq	-16(%rbp),%rax  // <- %rax is incorrectly reallocated here due to dangling pointers in the %xmm0 markers
	# Register rax released
	addsd	(%rax,%rax,8),%xmm0  // <- Access violation here
# Var h located in register xmm0
	# Register xmm0 released
	# Register xmm0 allocated
	# Register xmm0,r15d released
	# Register rdx allocated
# [33] freemem(t, nsr)
	movslq	%r15d,%rdx
	...

After:

	...
# [32] h:=s+palu[i+i+0]; // <- ACCESS VIOLATION:  addsd xmm0,[rax*8+rax]
	movslq	%edx,%rax
	# Register edx released
	# Register rdx allocated
	movslq	%edx,%rdx
	# Register rax,rdx released
	# Register rax allocated
	leaq	(%rax,%rdx),%rax
	# Register rdx allocated
	movq	-16(%rbp),%rdx  // <- %rax remains 'in use', and the allocator assigns %rdx instead
	# Register xmm0,rax,rdx released // <-- %xmm0 markers are better placed too
	# Register xmm0 allocated
	addsd	(%rdx,%rax,8),%xmm0 // <-- No more access violation!
	# Register xmm0 released
# Var h located in register xmm0
	# Register xmm0 allocated
	# Register xmm0,r15d released
	# Register rdx allocated
# [33] freemem(t, nsr)
	movslq	%r15d,%rdx
	...
Edited by J. Gareth "Kit" Moreton

Merge request reports

Loading