@@ -208,86 +208,29 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
208
208
209
209
let ( res, has_overflow) = match bin_op {
210
210
BinOp :: Add => {
211
- /*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs);
212
- (val, c_out)*/
213
- // FIXME(CraneStation/cranelift#849) legalize iadd_cout for i8 and i16
214
- let val = fx. bcx . ins ( ) . iadd ( lhs, rhs) ;
215
- let has_overflow = if !signed {
216
- fx. bcx . ins ( ) . icmp ( IntCC :: UnsignedLessThan , val, lhs)
211
+ if !signed {
212
+ fx. bcx . ins ( ) . uadd_overflow ( lhs, rhs)
217
213
} else {
218
- let rhs_is_negative = fx. bcx . ins ( ) . icmp_imm ( IntCC :: SignedLessThan , rhs, 0 ) ;
219
- let slt = fx. bcx . ins ( ) . icmp ( IntCC :: SignedLessThan , val, lhs) ;
220
- fx. bcx . ins ( ) . bxor ( rhs_is_negative, slt)
221
- } ;
222
- ( val, has_overflow)
214
+ fx. bcx . ins ( ) . sadd_overflow ( lhs, rhs)
215
+ }
223
216
}
224
217
BinOp :: Sub => {
225
- /*let (val, b_out) = fx.bcx.ins().isub_bout(lhs, rhs);
226
- (val, b_out)*/
227
- // FIXME(CraneStation/cranelift#849) legalize isub_bout for i8 and i16
228
- let val = fx. bcx . ins ( ) . isub ( lhs, rhs) ;
229
- let has_overflow = if !signed {
230
- fx. bcx . ins ( ) . icmp ( IntCC :: UnsignedGreaterThan , val, lhs)
218
+ if !signed {
219
+ fx. bcx . ins ( ) . usub_overflow ( lhs, rhs)
231
220
} else {
232
- let rhs_is_negative = fx. bcx . ins ( ) . icmp_imm ( IntCC :: SignedLessThan , rhs, 0 ) ;
233
- let sgt = fx. bcx . ins ( ) . icmp ( IntCC :: SignedGreaterThan , val, lhs) ;
234
- fx. bcx . ins ( ) . bxor ( rhs_is_negative, sgt)
235
- } ;
236
- ( val, has_overflow)
221
+ fx. bcx . ins ( ) . ssub_overflow ( lhs, rhs)
222
+ }
237
223
}
238
224
BinOp :: Mul => {
239
- let ty = fx. bcx . func . dfg . value_type ( lhs) ;
240
- match ty {
241
- types:: I8 | types:: I16 | types:: I32 if !signed => {
242
- let lhs = fx. bcx . ins ( ) . uextend ( ty. double_width ( ) . unwrap ( ) , lhs) ;
243
- let rhs = fx. bcx . ins ( ) . uextend ( ty. double_width ( ) . unwrap ( ) , rhs) ;
244
- let val = fx. bcx . ins ( ) . imul ( lhs, rhs) ;
245
- let has_overflow = fx. bcx . ins ( ) . icmp_imm (
246
- IntCC :: UnsignedGreaterThan ,
247
- val,
248
- ( 1 << ty. bits ( ) ) - 1 ,
249
- ) ;
250
- let val = fx. bcx . ins ( ) . ireduce ( ty, val) ;
251
- ( val, has_overflow)
252
- }
253
- types:: I8 | types:: I16 | types:: I32 if signed => {
254
- let lhs = fx. bcx . ins ( ) . sextend ( ty. double_width ( ) . unwrap ( ) , lhs) ;
255
- let rhs = fx. bcx . ins ( ) . sextend ( ty. double_width ( ) . unwrap ( ) , rhs) ;
256
- let val = fx. bcx . ins ( ) . imul ( lhs, rhs) ;
257
- let has_underflow =
258
- fx. bcx . ins ( ) . icmp_imm ( IntCC :: SignedLessThan , val, -( 1 << ( ty. bits ( ) - 1 ) ) ) ;
259
- let has_overflow = fx. bcx . ins ( ) . icmp_imm (
260
- IntCC :: SignedGreaterThan ,
261
- val,
262
- ( 1 << ( ty. bits ( ) - 1 ) ) - 1 ,
263
- ) ;
264
- let val = fx. bcx . ins ( ) . ireduce ( ty, val) ;
265
- ( val, fx. bcx . ins ( ) . bor ( has_underflow, has_overflow) )
266
- }
267
- types:: I64 => {
268
- let val = fx. bcx . ins ( ) . imul ( lhs, rhs) ;
269
- let has_overflow = if !signed {
270
- let val_hi = fx. bcx . ins ( ) . umulhi ( lhs, rhs) ;
271
- fx. bcx . ins ( ) . icmp_imm ( IntCC :: NotEqual , val_hi, 0 )
272
- } else {
273
- // Based on LLVM's instruction sequence for compiling
274
- // a.checked_mul(b).is_some() to riscv64gc:
275
- // mulh a2, a0, a1
276
- // mul a0, a0, a1
277
- // srai a0, a0, 63
278
- // xor a0, a0, a2
279
- // snez a0, a0
280
- let val_hi = fx. bcx . ins ( ) . smulhi ( lhs, rhs) ;
281
- let val_sign = fx. bcx . ins ( ) . sshr_imm ( val, i64:: from ( ty. bits ( ) - 1 ) ) ;
282
- let xor = fx. bcx . ins ( ) . bxor ( val_hi, val_sign) ;
283
- fx. bcx . ins ( ) . icmp_imm ( IntCC :: NotEqual , xor, 0 )
284
- } ;
285
- ( val, has_overflow)
286
- }
287
- types:: I128 => {
288
- unreachable ! ( "i128 should have been handled by codegen_i128::maybe_codegen" )
289
- }
290
- _ => unreachable ! ( "invalid non-integer type {}" , ty) ,
225
+ assert_ne ! (
226
+ fx. bcx. func. dfg. value_type( lhs) ,
227
+ types:: I128 ,
228
+ "i128 should have been handled by codegen_i128::maybe_codegen"
229
+ ) ;
230
+ if !signed {
231
+ fx. bcx . ins ( ) . umul_overflow ( lhs, rhs)
232
+ } else {
233
+ fx. bcx . ins ( ) . smul_overflow ( lhs, rhs)
291
234
}
292
235
}
293
236
_ => bug ! ( "binop {:?} on checked int/uint lhs: {:?} rhs: {:?}" , bin_op, in_lhs, in_rhs) ,
0 commit comments