NCG: Use 32bit-comparisons when operating on pointer tags.
Summary
I came across this pointer check in Cmm:
cGv: // global
call (I64[R1])(R1) returns to cGu, args: 8, res: 8, upd: 8;
cGu: // global
if (R1 & 7 != 1) goto cGz; else goto cGy;
Which turns into this assembly:
movq %rbx,%rax
andl $7,%eax
cmpq $1,%rax
je .LcGy
.LcGz:
Using cmpq wastes a bit here for the 64bit encoding when the 32bit encoding would do.
I think the issue is that we generate the literal 1 as 64bit wide number resulting in a 64bit operation being used.
To reproduce:
module M where
{-# NOINLINE incMaybe #-}
incMaybe :: Maybe Int -> Int
incMaybe (Just x) = x + 1
incMaybe Nothing = 0
Compile with ghc A.hs -O2 -ddump-cmm -ddump-asm -dno-typeable-binds -fforce-recomp -ddump-to-file -fno-worker-wrapper -dcmm-lint
Environment
- GHC version used:
Optional:
- Operating System:
- System Architecture: