diff options
author | Magnus Lång <[email protected]> | 2015-11-20 14:39:48 +0100 |
---|---|---|
committer | Magnus Lång <[email protected]> | 2015-11-27 18:18:38 +0100 |
commit | bac7c55f9a9250f6edb57170530d567df6c92f29 (patch) | |
tree | f44973b5331cb4fd3840ba9d798bd947dc244f6b | |
parent | 148153eb16e873181ff6961f854105a240989265 (diff) | |
download | otp-bac7c55f9a9250f6edb57170530d567df6c92f29.tar.gz otp-bac7c55f9a9250f6edb57170530d567df6c92f29.tar.bz2 otp-bac7c55f9a9250f6edb57170530d567df6c92f29.zip |
hipe: Allow unsigned args in hipe_rtl_arith
hipe_rtl_arith is only used by hipe_rtl_ssa_const_prop, which applies it
to any RTL, including RTL where the intent is to do unsigned math. Since
signed and unsigned operations produce the same 2's complement result,
this change is harmless.
On 32-bit architectures it caused HiPE crashes when compiling code like
<<0:((1 bsl 32)-1)>>, because the size of the field is too large to fit
in a signed integer.
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_arith.inc | 15 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_arith_32.erl | 3 |
2 files changed, 6 insertions, 12 deletions
diff --git a/lib/hipe/rtl/hipe_rtl_arith.inc b/lib/hipe/rtl/hipe_rtl_arith.inc index 1f455f47ed..1dff56b074 100644 --- a/lib/hipe/rtl/hipe_rtl_arith.inc +++ b/lib/hipe/rtl/hipe_rtl_arith.inc @@ -30,13 +30,13 @@ %% Returns a tuple %% {Res, Sign, Zero, Overflow, Carry} %% Res will be a number in the range -%% MAX_SIGNED_INT >= Res >= MIN_SIGNED_INT +%% MAX_UNSIGNED_INT >= Res >= 0 %% The other four values are flags that are either true or false %% eval_alu(Op, Arg1, Arg2) - when Arg1 =< ?MAX_SIGNED_INT, + when Arg1 =< ?MAX_UNSIGNED_INT, Arg1 >= ?MIN_SIGNED_INT, - Arg2 =< ?MAX_SIGNED_INT, + Arg2 =< ?MAX_UNSIGNED_INT, Arg2 >= ?MIN_SIGNED_INT -> Sign1 = sign_bit(Arg1), @@ -111,7 +111,7 @@ eval_alu(Op, Arg1, Arg2) Res = N = Z = V = C = 0, ?EXIT({"unknown alu op", Op}) end, - {two_comp_to_erl(Res), N, Z, V, C}; + {Res, N, Z, V, C}; eval_alu(Op, Arg1, Arg2) -> ?EXIT({argument_overflow,Op,Arg1,Arg2}). @@ -162,16 +162,9 @@ eval_cond(Cond, Arg1, Arg2) -> sign_bit(Val) -> ((Val bsr ?SIGN_BIT) band 1) =:= 1. -two_comp_to_erl(V) -> - if V > ?MAX_SIGNED_INT -> - - ((?MAX_UNSIGNED_INT + 1) - V); - true -> V - end. - shiftmask(Arg) -> Setbits = ?BITS - Arg, (1 bsl Setbits) - 1. zero(Val) -> Val =:= 0. - diff --git a/lib/hipe/rtl/hipe_rtl_arith_32.erl b/lib/hipe/rtl/hipe_rtl_arith_32.erl index 572556be1c..d790a8b981 100644 --- a/lib/hipe/rtl/hipe_rtl_arith_32.erl +++ b/lib/hipe/rtl/hipe_rtl_arith_32.erl @@ -24,7 +24,8 @@ %% Filename : hipe_rtl_arith_32.erl %% Module : hipe_rtl_arith_32 %% Purpose : To implement 32-bit RTL-arithmetic -%% Notes : The arithmetic works on 32-bit signed integers. +%% Notes : The arithmetic works on 32-bit signed and unsigned +%% integers. %% The implementation is taken from the implementation %% of arithmetic on SPARC. %% XXX: This code is seldom used, and hence also |