diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index b52a8dafed..5461aada55 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -1586,6 +1586,7 @@ pub(crate) fn define( let x = &operand("x", Int); let y = &operand("y", Int); + // TODO(ryzokuken): Add documentation for unsigned overflow. ig.push( Inst::new( "icmp", diff --git a/cranelift/codegen/src/isa/arm32/mod.rs b/cranelift/codegen/src/isa/arm32/mod.rs index ced1b88767..ed5854593b 100644 --- a/cranelift/codegen/src/isa/arm32/mod.rs +++ b/cranelift/codegen/src/isa/arm32/mod.rs @@ -126,6 +126,14 @@ impl TargetIsa for Isa { fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) { emit_function(func, binemit::emit_inst, sink, self) } + + fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC { + ir::condcodes::IntCC::UnsignedLessThan + } + + fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC { + ir::condcodes::IntCC::UnsignedGreaterThanOrEqual + } } impl fmt::Display for Isa { diff --git a/cranelift/codegen/src/isa/arm64/mod.rs b/cranelift/codegen/src/isa/arm64/mod.rs index d787524a6a..71ae93c0fe 100644 --- a/cranelift/codegen/src/isa/arm64/mod.rs +++ b/cranelift/codegen/src/isa/arm64/mod.rs @@ -114,6 +114,14 @@ impl TargetIsa for Isa { fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) { emit_function(func, binemit::emit_inst, sink, self) } + + fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC { + ir::condcodes::IntCC::UnsignedLessThan + } + + fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC { + ir::condcodes::IntCC::UnsignedGreaterThanOrEqual + } } impl fmt::Display for Isa { diff --git a/cranelift/codegen/src/isa/mod.rs b/cranelift/codegen/src/isa/mod.rs index c36d29ce2b..6457eb9ad7 100644 --- a/cranelift/codegen/src/isa/mod.rs +++ b/cranelift/codegen/src/isa/mod.rs @@ -371,4 +371,10 @@ pub trait TargetIsa: fmt::Display + Sync { /// Emit a whole function into memory. fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut binemit::MemoryCodeSink); + + /// IntCC condition for Unsigned Addition Overflow (Carry). + fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC; + + /// IntCC condition for Unsigned Subtraction Overflow (Borrow/Carry). + fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC; } diff --git a/cranelift/codegen/src/isa/riscv/mod.rs b/cranelift/codegen/src/isa/riscv/mod.rs index 233e92a3bb..93ef3787f0 100644 --- a/cranelift/codegen/src/isa/riscv/mod.rs +++ b/cranelift/codegen/src/isa/riscv/mod.rs @@ -121,6 +121,14 @@ impl TargetIsa for Isa { fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) { emit_function(func, binemit::emit_inst, sink, self) } + + fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC { + unimplemented!() + } + + fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC { + unimplemented!() + } } #[cfg(test)] diff --git a/cranelift/codegen/src/isa/x86/mod.rs b/cranelift/codegen/src/isa/x86/mod.rs index 52ab055440..8136170cd7 100644 --- a/cranelift/codegen/src/isa/x86/mod.rs +++ b/cranelift/codegen/src/isa/x86/mod.rs @@ -142,6 +142,14 @@ impl TargetIsa for Isa { let _tt = timing::prologue_epilogue(); abi::prologue_epilogue(func, self) } + + fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC { + ir::condcodes::IntCC::UnsignedLessThan + } + + fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC { + ir::condcodes::IntCC::UnsignedLessThan + } } impl fmt::Display for Isa { diff --git a/cranelift/codegen/src/legalizer/heap.rs b/cranelift/codegen/src/legalizer/heap.rs index 332553e803..a6d9d9637d 100644 --- a/cranelift/codegen/src/legalizer/heap.rs +++ b/cranelift/codegen/src/legalizer/heap.rs @@ -83,7 +83,11 @@ fn dynamic_addr( // We need an overflow check for the adjusted offset. let access_size_val = pos.ins().iconst(offset_ty, access_size as i64); let (adj_offset, overflow) = pos.ins().iadd_ifcout(offset, access_size_val); - pos.ins().trapnz(overflow, ir::TrapCode::HeapOutOfBounds); + pos.ins().trapif( + isa.unsigned_add_overflow_condition(), + overflow, + ir::TrapCode::HeapOutOfBounds, + ); oob = pos .ins() .icmp(IntCC::UnsignedGreaterThan, adj_offset, bound);