Skip to content

Commit a515b3a

Browse files
authored
Merge pull request #1369 from housel/left-shift-signal-overflow-simplified
dfmc-llvm-back-end: Simplify left shift overflow detection
2 parents 60244fe + cfe48dd commit a515b3a

File tree

1 file changed

+9
-17
lines changed

1 file changed

+9
-17
lines changed

sources/dfmc/llvm-back-end/llvm-primitives-machine-word.dylan

+9-17
Original file line numberDiff line numberDiff line change
@@ -940,24 +940,16 @@ end;
940940
define sign-extend overflow side-effect-free stateless dynamic-extent &primitive-descriptor primitive-machine-word-shift-left-signal-overflow
941941
(x :: <raw-machine-word>, shift :: <raw-machine-word>)
942942
=> (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);
945950
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
961953
end;
962954

963955
define side-effect-free stateless dynamic-extent &primitive-descriptor primitive-machine-word-double-floor/-quotient

0 commit comments

Comments
 (0)