summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Leroy <xavierleroy@users.noreply.github.com>2021-09-11 11:49:07 +0200
committerXavier Leroy <xavier.leroy@college-de-france.fr>2021-09-11 11:49:43 +0200
commitff21a7abeebcbe326a9f04d9308e18cb9b8ea65b (patch)
treef8e9b9771f6ce63353721229187ba3a909a7d79c
parent717a669cb997cbc40b33889ec7020d95666a33dc (diff)
downloadocaml-ff21a7abeebcbe326a9f04d9308e18cb9b8ea65b.tar.gz
AMD64 integer multiply immediate cannot write result to a stack location (#10628)
Force reload into a register if needed. This was correctly done in the i386 port. Fixes: #10626 (cherry picked from commit 531bb0400eb1328c84314a813dcc1521113e6275)
-rw-r--r--Changes5
-rw-r--r--asmcomp/amd64/reload.ml6
2 files changed, 11 insertions, 0 deletions
diff --git a/Changes b/Changes
index ebb5bd6dc9..6f55838878 100644
--- a/Changes
+++ b/Changes
@@ -643,6 +643,11 @@ OCaml 4.12, maintenance version
ID when a thread starts.
(David Allsopp, Nicolás Ojeda Bär, review by Xavier Leroy)
+- #10626, #10628: Wrong reloading of the x86-64 instruction for
+ integer multiplication by a constant, causing the assembler to
+ reject the ocamlopt-generated code.
+ (Xavier Leroy, report by Dave Aitken, review by Vincent Laviron)
+
OCaml 4.12.0 (24 February 2021)
-------------------------------
diff --git a/asmcomp/amd64/reload.ml b/asmcomp/amd64/reload.ml
index 8939fa0338..1f4cadc391 100644
--- a/asmcomp/amd64/reload.ml
+++ b/asmcomp/amd64/reload.ml
@@ -40,6 +40,7 @@ open Mach
Iintop(others) R R S
or S S R
Iintop_imm(Iadd, n)/lea R R
+ Iintop_imm(Imul, n) R R
Iintop_imm(others) S S
Inegf...Idivf R R S
Ifloatofint R S
@@ -74,6 +75,11 @@ method! reload_operation op arg res =
(* This add will be turned into a lea; args and results must be
in registers *)
super#reload_operation op arg res
+ | Iintop_imm(Imul, _) ->
+ (* The result (= the argument) must be a register (#10626) *)
+ if stackp arg.(0)
+ then (let r = self#makereg arg.(0) in ([|r|], [|r|]))
+ else (arg, res)
| Iintop(Imulh | Idiv | Imod | Ilsl | Ilsr | Iasr)
| Iintop_imm(_, _) ->
(* The argument(s) and results can be either in register or on stack *)