quot with a power of two is not optimized to a shift
The follow code:
module Test where
f :: Int -> Int
f n = n `quot` 2
results in the following core:
Test.f :: GHC.Types.Int -> GHC.Types.Int
Test.f =
\ (n_aeH :: GHC.Types.Int) ->
case n_aeH of _ { GHC.Types.I# ww_aiQ ->
GHC.Types.I# (GHC.Prim.quotInt# ww_aiQ 2)
}
which in turn generates this Cmm
sjI_ret()
{ Just sjI_info:
const 0;
const 32;
}
cjX:
Hp = Hp + 16;
if (Hp > I64[BaseReg + 144]) goto ck3;
_sjH::I64 = %MO_S_Quot_W64(I64[R1 + 7], 2);
I64[Hp - 8] = PicBaseReg + GHC.Types.I#_con_info;
I64[Hp + 0] = _sjH::I64;
R1 = Hp - 7;
Sp = Sp + 8;
jump (I64[Sp + 0]); // [R1]
ck1: jump (I64[BaseReg - 16]); // [R1]
ck3:
I64[BaseReg + 192] = 16;
goto ck1;
}
which finally ends up as this assembly:
sjI_info:
_cjX:
addq $16,%r12
cmpq 144(%r13),%r12
ja _ck3
movl $2,%ecx
movq 7(%rbx),%rax
cqto
idivq %rcx
movq %rax,%rbx
leaq GHC.Types.I#_con_info(%rip),%rax
movq %rax,-8(%r12)
movq %rbx,0(%r12)
leaq -7(%r12),%rbx
addq $8,%rbp
jmp *0(%rbp)
Ideally this should have turned into a shift, not a division. compiler/nativeGen/X86/CodeGen.hs
lacks any peephole optimizations for division.
Trac metadata
Trac field | Value |
---|---|
Version | 7.8.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |