@@ -940,24 +940,16 @@ end;
940
940
define sign-extend overflow side-effect-free stateless dynamic-extent &primitive-descriptor primitive-machine-word-shift-left-signal-overflow
941
941
(x :: <raw-machine-word>, shift :: <raw-machine-word>)
942
942
=> (result :: <raw-machine-word>);
943
- ins--if (be, ins--icmp-eq(be, x, 0 ))
944
- x
943
+ let result = ins--shl(be, x, shift);
944
+ // Shift the result back by the same amount to see if any bits were lost
945
+ let unshift = ins--ashr(be, result, shift);
946
+ let overflow = ins--icmp-ne(be, x, unshift);
947
+ ins--if (be, op--unlikely(be, overflow))
948
+ // Signal <arithmetic-overflow-error>
949
+ op--overflow-trap(be);
945
950
ins--else
946
- // Count the leading bits that are the same as the sign bit
947
- let x-negative? = ins--icmp-slt(be, x, 0 );
948
- let x-lognot = ins--xor(be, x, -1 );
949
- let x-hat = ins--select(be, x-negative?, x-lognot, x);
950
- let zeroes = ins--call-intrinsic(be, "llvm.ctlz" , vector (x-hat, $llvm-false));
951
-
952
- // We can shift without overflow if it is by fewer bits than that
953
- let overflow = ins--icmp-uge(be, shift, zeroes);
954
- ins--if (be, op--unlikely(be, overflow))
955
- // Signal <arithmetic-overflow-error>
956
- op--overflow-trap(be);
957
- ins--else
958
- ins--shl(be, x, shift)
959
- end ins--if;
960
- end ins--if;
951
+ result
952
+ end ins--if
961
953
end ;
962
954
963
955
define side-effect-free stateless dynamic-extent &primitive-descriptor primitive-machine-word-double-floor/-quotient
0 commit comments