GHC doesnt' notice that `narrowWordFOO (x .&. (2^FOO-1))` is just `narrowWordFOO x`.
```hs
{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dhex-word-literals -O2 #-}
{-# LANGUAGE TypeApplications #-}
module NarrowWord where
import Data.Word
import Data.Bits
smallWord_foo :: Word64 -> Word64
smallWord_foo x = fromIntegral @Word16 $ fromIntegral (x .&. 0xFFFF)
smallWord_bar :: Word64 -> Word64
smallWord_bar x = fromIntegral @Word16 $ fromIntegral x
test :: Bool
test =
let w = 72430412501
in smallWord_foo w == smallWord_bar w
```
```hs
-- RHS size: {terms: 7, types: 3, coercions: 0, joins: 0/0}
smallWord_bar :: Word64 -> Word64
[GblId,
Arity=1,
Caf=NoCafRefs,
Str=<S(S),1*U(U)>m,
Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
Tmpl= \ (x_a1so [Occ=Once!] :: Word64) ->
case x_a1so of { GHC.Word.W64# x#_a2Mw [Occ=Once] ->
GHC.Word.W64# (GHC.Prim.narrow16Word# x#_a2Mw)
}}]
smallWord_bar
= \ (x_a1so :: Word64) ->
case x_a1so of { GHC.Word.W64# x#_a2Mw ->
GHC.Word.W64# (GHC.Prim.narrow16Word# x#_a2Mw)
}
-- RHS size: {terms: 9, types: 3, coercions: 0, joins: 0/0}
smallWord_foo :: Word64 -> Word64
[GblId,
Arity=1,
Caf=NoCafRefs,
Str=<S(S),1*U(U)>m,
Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
Tmpl= \ (x_a1hU [Occ=Once!] :: Word64) ->
case x_a1hU of { GHC.Word.W64# x#_a30a [Occ=Once] ->
GHC.Word.W64#
(GHC.Prim.narrow16Word# (GHC.Prim.and# x#_a30a 0xffff##))
}}]
smallWord_foo
= \ (x_a1hU :: Word64) ->
case x_a1hU of { GHC.Word.W64# x#_a30a ->
GHC.Word.W64#
(GHC.Prim.narrow16Word# (GHC.Prim.and# x#_a30a 0xffff##))
}
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
test :: Bool
[GblId,
Caf=NoCafRefs,
Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)
Tmpl= GHC.Types.True}]
test = GHC.Types.True
```
For Word8, Word16, Word32, Word64 and Int8, Int16, Int32, Int64, I would expect GHC to never produce the `and`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC doesnt' notice that (narrowWordFOO (x .&. FOO)) is just `x`.","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dhex-word-literals -O2 #-}\r\n{-# LANGUAGE TypeApplications #-}\r\nmodule NarrowWord where\r\n\r\nimport Data.Word\r\nimport Data.Bits\r\n\r\n\r\nsmallWord_foo :: Word64 -> Word64\r\nsmallWord_foo x = fromIntegral @Word16 $ fromIntegral (x .&. 0xFFFF)\r\n\r\nsmallWord_bar :: Word64 -> Word64\r\nsmallWord_bar x = fromIntegral @Word16 $ fromIntegral x\r\n\r\ntest :: Bool\r\ntest =\r\n let w = 72430412501\r\n in smallWord_foo w == smallWord_bar w\r\n}}}\r\n\r\n{{{#!hs\r\n-- RHS size: {terms: 7, types: 3, coercions: 0, joins: 0/0}\r\nsmallWord_bar :: Word64 -> Word64\r\n[GblId,\r\n Arity=1,\r\n Caf=NoCafRefs,\r\n Str=<S(S),1*U(U)>m,\r\n Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True,\r\n Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)\r\n Tmpl= \\ (x_a1so [Occ=Once!] :: Word64) ->\r\n case x_a1so of { GHC.Word.W64# x#_a2Mw [Occ=Once] ->\r\n GHC.Word.W64# (GHC.Prim.narrow16Word# x#_a2Mw)\r\n }}]\r\nsmallWord_bar\r\n = \\ (x_a1so :: Word64) ->\r\n case x_a1so of { GHC.Word.W64# x#_a2Mw ->\r\n GHC.Word.W64# (GHC.Prim.narrow16Word# x#_a2Mw)\r\n }\r\n\r\n-- RHS size: {terms: 9, types: 3, coercions: 0, joins: 0/0}\r\nsmallWord_foo :: Word64 -> Word64\r\n[GblId,\r\n Arity=1,\r\n Caf=NoCafRefs,\r\n Str=<S(S),1*U(U)>m,\r\n Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True,\r\n Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)\r\n Tmpl= \\ (x_a1hU [Occ=Once!] :: Word64) ->\r\n case x_a1hU of { GHC.Word.W64# x#_a30a [Occ=Once] ->\r\n GHC.Word.W64#\r\n (GHC.Prim.narrow16Word# (GHC.Prim.and# x#_a30a 0xffff##))\r\n }}]\r\nsmallWord_foo\r\n = \\ (x_a1hU :: Word64) ->\r\n case x_a1hU of { GHC.Word.W64# x#_a30a ->\r\n GHC.Word.W64#\r\n (GHC.Prim.narrow16Word# (GHC.Prim.and# x#_a30a 0xffff##))\r\n }\r\n\r\n-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}\r\ntest :: Bool\r\n[GblId,\r\n Caf=NoCafRefs,\r\n Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,\r\n WorkFree=True, Expandable=True,\r\n Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)\r\n Tmpl= GHC.Types.True}]\r\ntest = GHC.Types.True\r\n}}}\r\n\r\nFor Word8, Word16, Word32, Word64 and Int8, Int16, Int32, Int64, I would expect GHC to never produce the {{{and}}}.","type_of_failure":"OtherFailure","blocking":[]} -->
issue