Skip to content

Commit 451d966

Browse files
committed
builder: fix checked_binop for signed addition/subtraction.
1 parent 39eec00 commit 451d966

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

crates/rustc_codegen_spirv/src/builder/builder_methods.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,28 +1748,34 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
17481748
};
17491749

17501750
// adopted partially from https://github.com/ziglang/zig/blob/master/src/codegen/spirv.zig
1751+
// FIXME(eddyb) ^^ find a working a permalink, and also inform them
1752+
// of the difference between these two approaches:
1753+
// - broken: https://alive2.llvm.org/ce/z/Q3Pchi
1754+
// - correct: https://alive2.llvm.org/ce/z/aWvThi
17511755

17521756
// when adding, overflow could happen if
17531757
// - rhs is positive and result < lhs; or
1754-
// - rhs is negative and result > lhs
1755-
// this is equivalent to (rhs < 0) == (result > lhs)
1758+
// - rhs is negative and result >= lhs
1759+
// (`result == lhs` impossible, `>=` used as it's `!(result < lhs)`)
1760+
// this is equivalent to (rhs < 0) == (result >= lhs)
17561761
//
17571762
// when subtracting, overflow happens if
17581763
// - rhs is positive and result > lhs; or
1759-
// - rhs is negative and result < lhs
1760-
// this is equivalent to (rhs < 0) == (result < lhs)
1764+
// - rhs is negative and result <= lhs
1765+
// (`result == lhs` impossible, `<=` used as it's `!(result > lhs)`)
1766+
// this is equivalent to (rhs < 0) == (result <= lhs)
17611767
let rhs_lt_zero = self.icmp(IntPredicate::IntSLT, rhs, self.constant_int(rhs.ty, 0));
1762-
let result_gt_lhs = self.icmp(
1768+
let result_ge_lhs = self.icmp(
17631769
match oop {
1764-
OverflowOp::Add => IntPredicate::IntSGT,
1765-
OverflowOp::Sub => IntPredicate::IntSLT,
1770+
OverflowOp::Add => IntPredicate::IntSGE,
1771+
OverflowOp::Sub => IntPredicate::IntSLE,
17661772
OverflowOp::Mul => unreachable!(),
17671773
},
17681774
result,
17691775
lhs,
17701776
);
17711777

1772-
let overflowed = self.icmp(IntPredicate::IntEQ, rhs_lt_zero, result_gt_lhs);
1778+
let overflowed = self.icmp(IntPredicate::IntEQ, rhs_lt_zero, result_ge_lhs);
17731779

17741780
return (result, overflowed);
17751781
}

0 commit comments

Comments
 (0)