aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2016-06-03 18:26:07 +0200
committerMagnus Lång <[email protected]>2016-08-22 15:34:32 +0200
commita504c30efbc14381385a6ef911ba7296840f8cb7 (patch)
tree0985a90e08db7c2b90592a2db9a724cd0c7e6752 /lib/hipe
parentb7c2af9863a5410ce0be9c2995ea49746b207877 (diff)
downloadotp-a504c30efbc14381385a6ef911ba7296840f8cb7.tar.gz
otp-a504c30efbc14381385a6ef911ba7296840f8cb7.tar.bz2
otp-a504c30efbc14381385a6ef911ba7296840f8cb7.zip
hipe: Fix amd64 SSE2 encoding crash
Register allocation could transform something like fmove u32, d99 to fmove $rdx, 0x20($rsp) which is an invalid instruction.
Diffstat (limited to 'lib/hipe')
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl b/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
index 5451f1fe7d..b1f7bd7572 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
@@ -87,22 +87,29 @@ do_fp_unop(I, TempMap) ->
%%% Fix an fmove op.
do_fmove(I, TempMap) ->
#fmove{src=Src,dst=Dst} = I,
- case is_mem_opnd(Dst, TempMap) and is_mem_opnd(Src, TempMap) of
+ case
+ (is_mem_opnd(Src, TempMap) andalso is_mem_opnd(Dst, TempMap))
+ orelse (is_mem_opnd(Src, TempMap) andalso (not is_float_temp(Dst)))
+ orelse ((not is_float_temp(Src)) andalso is_mem_opnd(Dst, TempMap))
+ of
true ->
- Tmp = clone(Src),
+ Tmp = spill_temp(double),
{[#fmove{src=Src, dst=Tmp},I#fmove{src=Tmp,dst=Dst}],
true};
false ->
{[I], false}
end.
+is_float_temp(#x86_temp{type=Type}) -> Type =:= double;
+is_float_temp(#x86_mem{}) -> false.
+
%%% Check if an operand denotes a memory cell (mem or pseudo).
is_mem_opnd(Opnd, TempMap) ->
R =
case Opnd of
#x86_mem{} -> true;
- #x86_temp{} ->
+ #x86_temp{type=double} ->
Reg = hipe_x86:temp_reg(Opnd),
case hipe_x86:temp_is_allocatable(Opnd) of
true ->
@@ -176,6 +183,9 @@ clone(Dst) ->
#x86_mem{} -> hipe_x86:mem_type(Dst);
#x86_temp{} -> hipe_x86:temp_type(Dst)
end,
+ spill_temp(Type).
+
+spill_temp(Type) ->
hipe_x86:mk_new_temp(Type).
%%% Make a certain reg into a clone of Dst