Skip to content

[x86 / Bug Fix] "StcClcSet(c)2Mov" optimisation now checks to see if the destination register is in use (Fixes #40659)

J. Gareth "Kit" Moreton requested to merge CuriousKit/optimisations:i40659 into main

Summary

This merge request fixes an issue with the recently added STC/CLC optimisations where SETcc instructions were shortcutted without actually checking to see if the destination register was in use in between, thus causing unpredictable behaviour.

This fixes issue #40659 (closed).

System

  • Processor architecture: i386, x86_64

What is the current bug behavior?

Some projects, notably Lazarus, fail to work properly under -O2 and above.

What is the behavior after applying this patch?

Lazarus should now work correctly.

Relevant logs and/or screenshots

One example appears in the packages as well in the fpexprpars unit (x86_64-win64 -O4) - before:

.section .text.n_fpexprpars$_$tfpexpressionscanner_$__$$_isdigit$ansichar$tnumberkind$$boolean,"ax"
	...
.Lj218:
	movzbl	%dl,%eax
	cmpl	$46,%eax
	movb	$1,%al
	je	.Lj217
	subl	$48,%eax ; <-- %eax has been corrupted by the "movb $1,%al" instruction above
	cmpl	$10,%eax
	setcb	%al
	ret

After - the optimisation is not made and so %eax is no longer corrupted:

.section .text.n_fpexprpars$_$tfpexpressionscanner_$__$$_isdigit$ansichar$tnumberkind$$boolean,"ax"
	...
.Lj218:
	movzbl	%dl,%eax
	cmpl	$46,%eax
	stc
	je	.Lj222
	subl	$48,%eax
	cmpl	$10,%eax
.Lj222:
	setcb	%al
	ret
Edited by J. Gareth "Kit" Moreton

Merge request reports