Skip to content

Commit 603c5fc

Browse files
committed
const folding: use checked operations and allow bailing
1 parent 280bac8 commit 603c5fc

File tree

1 file changed

+46
-39
lines changed

1 file changed

+46
-39
lines changed

crates/rustc_codegen_spirv/src/builder/builder_methods.rs

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,18 @@ macro_rules! simple_op {
105105
if let Some(const_lhs) = self.try_get_const_value(lhs)
106106
&& let Some(const_rhs) = self.try_get_const_value(rhs)
107107
{
108-
#[allow(unreachable_patterns)]
109-
match (const_lhs, const_rhs) {
108+
let result = (|| Some(match (const_lhs, const_rhs) {
110109
$(
111-
(ConstValue::Unsigned($int_lhs), ConstValue::Unsigned($int_rhs)) => return self.const_uint_big(result_type, $fold_int),
112-
(ConstValue::Signed($int_lhs), ConstValue::Signed($int_rhs)) => return self.const_uint_big(result_type, $fold_int as u128),
110+
(ConstValue::Unsigned($int_lhs), ConstValue::Unsigned($int_rhs)) => $fold_int,
111+
(ConstValue::Signed($int_lhs), ConstValue::Signed($int_rhs)) => $fold_int as u128,
113112
)?
114-
$((ConstValue::Unsigned($uint_lhs), ConstValue::Unsigned($uint_rhs)) => return self.const_uint_big(result_type, $fold_uint), )?
115-
$((ConstValue::Signed($sint_lhs), ConstValue::Signed($sint_rhs)) => return self.const_uint_big(result_type, $fold_sint as u128), )?
116-
$((ConstValue::Bool($bool_lhs), ConstValue::Bool($bool_rhs)) => return self.const_uint_big(result_type, ($fold_bool).into()), )?
117-
_ => (),
113+
$((ConstValue::Unsigned($uint_lhs), ConstValue::Unsigned($uint_rhs)) => $fold_uint,)?
114+
$((ConstValue::Signed($sint_lhs), ConstValue::Signed($sint_rhs)) => $fold_sint as u128, )?
115+
$((ConstValue::Bool($bool_lhs), ConstValue::Bool($bool_rhs)) => ($fold_bool).into(), )?
116+
_ => return None,
117+
}))();
118+
if let Some(result) = result {
119+
return self.const_uint_big(result_type, result);
118120
}
119121
}
120122
)?
@@ -172,23 +174,25 @@ macro_rules! simple_shift_op {
172174
if let Some(const_lhs) = self.try_get_const_value(lhs)
173175
&& let Some(const_rhs) = self.try_get_const_value(rhs)
174176
{
175-
#[allow(unreachable_patterns)]
176-
match (const_lhs, const_rhs) {
177+
let result = (|| Some(match (const_lhs, const_rhs) {
177178
$(
178-
(ConstValue::Unsigned($int_lhs), ConstValue::Unsigned($int_rhs)) => return self.const_uint_big(result_type, $fold_int),
179-
(ConstValue::Unsigned($int_lhs), ConstValue::Signed($int_rhs)) => return self.const_uint_big(result_type, $fold_int),
180-
(ConstValue::Signed($int_lhs), ConstValue::Unsigned($int_rhs)) => return self.const_uint_big(result_type, $fold_int as u128),
181-
(ConstValue::Signed($int_lhs), ConstValue::Signed($int_rhs)) => return self.const_uint_big(result_type, $fold_int as u128),
179+
(ConstValue::Unsigned($int_lhs), ConstValue::Unsigned($int_rhs)) => $fold_int,
180+
(ConstValue::Unsigned($int_lhs), ConstValue::Signed($int_rhs)) => $fold_int,
181+
(ConstValue::Signed($int_lhs), ConstValue::Unsigned($int_rhs)) => $fold_int as u128,
182+
(ConstValue::Signed($int_lhs), ConstValue::Signed($int_rhs)) => $fold_int as u128,
182183
)?
183184
$(
184-
(ConstValue::Unsigned($uint_lhs), ConstValue::Unsigned($uint_rhs)) => return self.const_uint_big(result_type, $fold_uint),
185-
(ConstValue::Unsigned($uint_lhs), ConstValue::Signed($uint_rhs)) => return self.const_uint_big(result_type, $fold_uint),
185+
(ConstValue::Unsigned($uint_lhs), ConstValue::Unsigned($uint_rhs)) => $fold_uint,
186+
(ConstValue::Unsigned($uint_lhs), ConstValue::Signed($uint_rhs)) => $fold_uint,
186187
)?
187188
$(
188-
(ConstValue::Signed($sint_lhs), ConstValue::Unsigned($sint_rhs)) => return self.const_uint_big(result_type, $fold_sint as u128),
189-
(ConstValue::Signed($sint_lhs), ConstValue::Signed($sint_rhs)) => return self.const_uint_big(result_type, $fold_sint as u128),
189+
(ConstValue::Signed($sint_lhs), ConstValue::Unsigned($sint_rhs)) => $fold_sint as u128,
190+
(ConstValue::Signed($sint_lhs), ConstValue::Signed($sint_rhs)) => $fold_sint as u128,
190191
)?
191-
_ => (),
192+
_ => return None,
193+
}))();
194+
if let Some(result) = result {
195+
return self.const_uint_big(result_type, result);
192196
}
193197
}
194198
)?
@@ -238,15 +242,18 @@ macro_rules! simple_uni_op {
238242
$(
239243
#[allow(unreachable_patterns, clippy::collapsible_match)]
240244
if let Some(const_val) = self.try_get_const_value(val) {
241-
match const_val {
245+
let result = (|| Some(match (const_val) {
242246
$(
243-
ConstValue::Unsigned($int_val) => return self.const_uint_big(result_type, $fold_int),
244-
ConstValue::Signed($int_val) => return self.const_uint_big(result_type, $fold_int as u128),
247+
ConstValue::Unsigned($int_val) => $fold_int,
248+
ConstValue::Signed($int_val) => $fold_int as u128,
245249
)?
246-
$(ConstValue::Unsigned($uint_val) => return self.const_uint_big(result_type, $fold_uint), )?
247-
$(ConstValue::Signed($sint_val) => return self.const_uint_big(result_type, $fold_sint as u128), )?
248-
$(ConstValue::Bool($bool_val) => return self.const_uint_big(result_type, ($fold_bool).into()), )?
249-
_ => (),
250+
$(ConstValue::Unsigned($uint_val) => $fold_uint, )?
251+
$(ConstValue::Signed($sint_val) => $fold_sint as u128, )?
252+
$(ConstValue::Bool($bool_val) => ($fold_bool).into(), )?
253+
_ => return None,
254+
}))();
255+
if let Some(result) = result {
256+
return self.const_uint_big(result_type, result);
250257
}
251258
}
252259
)?
@@ -1538,7 +1545,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
15381545
add,
15391546
int: i_add,
15401547
fold_const {
1541-
int(a, b) => a.wrapping_add(b);
1548+
int(a, b) => a.checked_add(b)?;
15421549
}
15431550
}
15441551
// FIXME(eddyb) try to annotate the SPIR-V for `fast` and `algebraic`.
@@ -1549,7 +1556,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
15491556
sub,
15501557
int: i_sub,
15511558
fold_const {
1552-
int(a, b) => a.wrapping_sub(b);
1559+
int(a, b) => a.checked_sub(b)?;
15531560
}
15541561
}
15551562
simple_op! {fsub, float: f_sub}
@@ -1559,7 +1566,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
15591566
mul,
15601567
int: i_mul,
15611568
fold_const {
1562-
int(a, b) => a.wrapping_mul(b);
1569+
int(a, b) => a.checked_mul(b)?;
15631570
}
15641571
}
15651572
simple_op! {fmul, float: f_mul}
@@ -1569,7 +1576,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
15691576
udiv,
15701577
uint: u_div,
15711578
fold_const {
1572-
uint(a, b) => a.wrapping_div(b);
1579+
uint(a, b) => a.checked_div(b)?;
15731580
}
15741581
}
15751582
// Note: exactudiv is UB when there's a remainder, so it's valid to implement as a normal div.
@@ -1578,22 +1585,22 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
15781585
exactudiv,
15791586
uint: u_div,
15801587
fold_const {
1581-
uint(a, b) => a.wrapping_div(b);
1588+
uint(a, b) => a.checked_div(b)?;
15821589
}
15831590
}
15841591
simple_op! {
15851592
sdiv,
15861593
sint: s_div,
15871594
fold_const {
1588-
sint(a, b) => a.wrapping_div(b);
1595+
sint(a, b) => a.checked_div(b)?;
15891596
}
15901597
}
15911598
// Same note and TODO as exactudiv
15921599
simple_op! {
15931600
exactsdiv,
15941601
sint: s_div,
15951602
fold_const {
1596-
sint(a, b) => a.wrapping_div(b);
1603+
sint(a, b) => a.checked_div(b)?;
15971604
}
15981605
}
15991606
simple_op! {fdiv, float: f_div}
@@ -1603,14 +1610,14 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
16031610
urem,
16041611
uint: u_mod,
16051612
fold_const {
1606-
uint(a, b) => a.wrapping_rem(b);
1613+
uint(a, b) => a.checked_rem(b)?;
16071614
}
16081615
}
16091616
simple_op! {
16101617
srem,
16111618
sint: s_rem,
16121619
fold_const {
1613-
sint(a, b) => a.wrapping_rem(b);
1620+
sint(a, b) => a.checked_rem(b)?;
16141621
}
16151622
}
16161623
simple_op! {frem, float: f_rem}
@@ -1620,28 +1627,28 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
16201627
shl,
16211628
int: shift_left_logical,
16221629
fold_const {
1623-
int(a, b) => a.wrapping_shl(b as u32);
1630+
int(a, b) => a.checked_shl(b as u32)?;
16241631
}
16251632
}
16261633
simple_shift_op! {
16271634
lshr,
16281635
uint: shift_right_logical,
16291636
fold_const {
1630-
uint(a, b) => a.wrapping_shr(b as u32);
1637+
uint(a, b) => a.checked_shr(b as u32)?;
16311638
}
16321639
}
16331640
simple_shift_op! {
16341641
ashr,
16351642
sint: shift_right_arithmetic,
16361643
fold_const {
1637-
sint(a, b) => a.wrapping_shr(b as u32);
1644+
sint(a, b) => a.checked_shr(b as u32)?;
16381645
}
16391646
}
16401647
simple_uni_op! {
16411648
neg,
16421649
sint: s_negate,
16431650
fold_const {
1644-
sint(a) => a.wrapping_neg();
1651+
sint(a) => a.checked_neg()?;
16451652
}
16461653
}
16471654
simple_uni_op! {fneg, float: f_negate}

0 commit comments

Comments
 (0)