summary refs log tree commit diff
path: root/amd64
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2021-06-16 20:27:49 -0700
committerQuentin Carbonneaux <quentin@c9x.me>2021-06-17 22:16:42 +0200
commit6d9ee1389572ae985f6a39bb99dbd10cdf42c123 (patch)
tree18d0ad17085f2fd6702d168d676a7716eafafae2 /amd64
parente0b94a3d6ade2f99ded481318e9e6d9f16953662 (diff)
downloadroux-6d9ee1389572ae985f6a39bb99dbd10cdf42c123.tar.gz
amd64: fix conditional jump when compare is swapped and used elsewhere
selcmp may potentially swap the arguments and return 1 indicating
that the opposite operation should be used. However, if the compare
result is used for a conditional jump as well as elsewhere, the
original compare op is used instead of the opposite.

To fix this, add a check to see whether the opposite compare should
be used, regardless of whether selcmp() is done now, or later on
during sel().

Bug report and test case from Charlie Stanton.
Diffstat (limited to 'amd64')
-rw-r--r--amd64/isel.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/amd64/isel.c b/amd64/isel.c
index 56e4cf3..5f84561 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -383,9 +383,10 @@ seljmp(Blk *b, Fn *fn)
 		b->jmp.type = Jjf + Cine;
 	}
 	else if (iscmp(fi->op, &k, &c)) {
+		if (rtype(fi->arg[0]) == RCon)
+			c = cmpop(c);
 		if (t->nuse == 1) {
-			if (selcmp(fi->arg, k, fn))
-				c = cmpop(c);
+			selcmp(fi->arg, k, fn);
 			*fi = (Ins){.op = Onop};
 		}
 		b->jmp.type = Jjf + c;