Open
Description
Codegen for division in general needs to generate code to panic if the division will panic (e.g. divide by zero or integer overflow). In the case of constants, however, it looks like rustc almost optimizes debug codegen but not quite. For example this code:
#[no_mangle]
pub extern fn foo(a: i32) -> i32 {
a / 256
}
generates this IR in debug mode:
define i32 @foo(i32 %a) unnamed_addr #0 !dbg !6 {
start:
%a.dbg.spill = alloca i32, align 4
store i32 %a, i32* %a.dbg.spill, align 4
call void @llvm.dbg.declare(metadata i32* %a.dbg.spill, metadata !12, metadata !DIExpression()), !dbg !13
%_4 = icmp eq i32 %a, -2147483648, !dbg !14
%_5 = and i1 false, %_4, !dbg !14
%0 = call i1 @llvm.expect.i1(i1 %_5, i1 false), !dbg !14
br i1 %0, label %panic, label %bb1, !dbg !14
bb1: ; preds = %start
%1 = sdiv i32 %a, 256, !dbg !14
ret i32 %1, !dbg !15
panic: ; preds = %start
; call core::panicking::panic
call void @_ZN4core9panicking5panic17h8a9eda1e10298363E([0 x i8]* noalias nonnull readonly align 1 bitcast ([31 x i8]* @str.0 to [0 x i8]*), i64 31, %"core::panic::Location"* noalias readonly align 8 dereferenceable(24) bitcast (<{ i8*, [16 x i8] }>* @anon.670bbfb7b436af44f45c978390c94a0e.1 to %"core::panic::Location"*)), !dbg !14
unreachable, !dbg !14
}
It looks like rustc is "smart enough" to generate %_5 = and i1 false, %_4, !dbg !14
to realize the rhs is not negative one and it's not zero, but it's not quite smart enough to know that false && x
is always false
, so it still generates a branch to panic.