Commit 7e43211
authored
riscv64: Fix
This commit fixes a mistake from #11583 where the implementation of
`uadd_overflow` on riscv64 was not correct for some inputs. This fix
generates the same codegen as `uadd_overflow_trap` which is to
zero-extend both inputs, perform a 64-bit add, and use the 33rd bit as
the overflow flag.
This sequence does notably differ from what LLVM generates. For example
this input function
#[unsafe(no_mangle)]
pub fn uadd_overflow(a: u64, b: u64) -> (u32, bool) {
(a as u32).overflowing_add(b as u32)
}
generates:
uadd_overflow:
addw a0, a0, a1
sext.w a1, a1
sltu a1, a0, a1
ret
While this is probably correct I find it tough to reason about how
`addw` produces a sign-extended result, `sext.w` sign-extends one of the
operands, and then an unsigned comparison is used to generate the
overflow flag for an unsigned addition. Overall I felt it was easier to
just match the `uadd_overflow_trap` codegen.uadd_overflow for 32-bit integers (#12951)1 parent 2a50190 commit 7e43211
2 files changed
Lines changed: 6 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
330 | 330 | | |
331 | 331 | | |
332 | 332 | | |
333 | | - | |
334 | | - | |
335 | | - | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
336 | 337 | | |
337 | 338 | | |
338 | 339 | | |
| |||
347 | 348 | | |
348 | 349 | | |
349 | 350 | | |
350 | | - | |
| 351 | + | |
351 | 352 | | |
352 | 353 | | |
353 | 354 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
0 commit comments