]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: simplify intrinsification of BitLen16 and BitLen8
authorJoel Sing <joel@sing.id.au>
Sat, 22 Feb 2025 13:02:27 +0000 (00:02 +1100)
committerJoel Sing <joel@sing.id.au>
Wed, 26 Feb 2025 10:02:07 +0000 (02:02 -0800)
Decompose BitLen16 and BitLen8 within the SSA rules for architectures that
support BitLen32 or BitLen64, rather than having a custom intrinsic.

Change-Id: Ie4188ce69d1021e63cec27a8e7418efb0714812b
Reviewed-on: https://go-review.googlesource.com/c/go/+/651817
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Joel Sing <joel@sing.id.au>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
15 files changed:
src/cmd/compile/internal/ssa/_gen/ARM.rules
src/cmd/compile/internal/ssa/_gen/ARM64.rules
src/cmd/compile/internal/ssa/_gen/LOONG64.rules
src/cmd/compile/internal/ssa/_gen/MIPS.rules
src/cmd/compile/internal/ssa/_gen/PPC64.rules
src/cmd/compile/internal/ssa/_gen/S390X.rules
src/cmd/compile/internal/ssa/_gen/Wasm.rules
src/cmd/compile/internal/ssa/rewriteARM.go
src/cmd/compile/internal/ssa/rewriteARM64.go
src/cmd/compile/internal/ssa/rewriteLOONG64.go
src/cmd/compile/internal/ssa/rewriteMIPS.go
src/cmd/compile/internal/ssa/rewritePPC64.go
src/cmd/compile/internal/ssa/rewriteS390X.go
src/cmd/compile/internal/ssa/rewriteWasm.go
src/cmd/compile/internal/ssagen/intrinsics.go

index a3bb2c312f9c16f5907827c55c211ab8f92206dd..63535a4b29d5c23db21ef52682bf108d02ff8da7 100644 (file)
@@ -80,6 +80,7 @@
 
 // bit length
 (BitLen32 <t> x) => (RSBconst [32] (CLZ <t> x))
+(BitLen(16|8) x) => (BitLen32 (ZeroExt(16|8)to32 x))
 
 // byte swap for ARMv5
 // let (a, b, c, d) be the bytes of x from high to low
index 3696e17d9ce957d9cbf48739795efaa9c46bb176..8618c24ebf816ba61299637b710c1de0b221b153 100644 (file)
 
 (BitLen64 x) => (SUB (MOVDconst [64]) (CLZ <typ.Int> x))
 (BitLen32 x) => (SUB (MOVDconst [32]) (CLZW <typ.Int> x))
+(BitLen(16|8) x) => (BitLen64 (ZeroExt(16|8)to64 x))
 
 (Bswap64 ...) => (REV ...)
 (Bswap32 ...) => (REVW ...)
index 00a0a84f33425362c4d8a27e037ed4b034f974af..e285f9fe275876e1482f8fe3af0e5800545ac397 100644 (file)
 
 (BitLen64 <t> x) => (NEGV <t> (SUBVconst <t> [64] (CLZV <t> x)))
 (BitLen32 <t> x) => (NEGV <t> (SUBVconst <t> [32] (CLZW <t> x)))
+(BitLen(16|8) x) => (BitLen64 (ZeroExt(16|8)to64 x))
 (Bswap(16|32|64) ...) => (REVB(2H|2W|V) ...)
 (BitRev8 ...) => (BITREV4B ...)
 (BitRev16 <t> x) => (REVB2H (BITREV4B <t> x))
index f4e0467ea001b18bd4cdf235a0b199658d9d3fc1..9a48164f55a27eade3a590cbaa2db746d6c6a9f7 100644 (file)
 
 // bit length
 (BitLen32 <t> x) => (SUB (MOVWconst [32]) (CLZ <t> x))
+(BitLen(16|8) x) => (BitLen32 (ZeroExt(16|8)to32 x))
 
 // boolean ops -- booleans are represented with 0=false, 1=true
 (AndB ...) => (AND ...)
index feef6ee52a9564e8406de3c220412079bcc7873f..768e37406f6209e0f14547ec36313ccbb501933a 100644 (file)
 
 (BitLen64 x) => (SUBFCconst [64] (CNTLZD <typ.Int> x))
 (BitLen32 x) => (SUBFCconst [32] (CNTLZW <typ.Int> x))
+(BitLen(16|8) x) => (BitLen64 (ZeroExt(16|8)to64 x))
 
 (PopCount64 ...) => (POPCNTD ...)
 (PopCount(32|16|8) x) => (POPCNT(W|W|B) (MOV(W|H|B)Zreg x))
index 462cf8f70111e195f62adac1e310c2ec31fecd19..3a903af5d066a2d5070f8041d1871b553a1fdd7f 100644 (file)
@@ -89,6 +89,7 @@
 (Ctz32 <t> x) => (SUB (MOVDconst [64]) (FLOGR (MOVWZreg (ANDW <t> (SUBWconst <t> [1] x) (NOTW <t> x)))))
 
 (BitLen64 x) => (SUB (MOVDconst [64]) (FLOGR x))
+(BitLen(32|16|8) x) => (BitLen64 (ZeroExt(32|16|8)to64 x))
 
 // POPCNT treats the input register as a vector of 8 bytes, producing
 // a population count for each individual byte. For inputs larger than
index 08cadabe0ea4c24b73ef48bd35bf484f9a389ade..f3bd8d8b4f18f1c812ee00b8606beacffe7e5fba 100644 (file)
 (Ctz(64|32|16|8)NonZero ...) => (I64Ctz ...)
 
 (BitLen64 x) => (I64Sub (I64Const [64]) (I64Clz x))
+(BitLen(32|16|8) x) => (BitLen64 (ZeroExt(32|16|8)to64 x))
 
 (PopCount64 ...) => (I64Popcnt ...)
 (PopCount32 x) => (I64Popcnt (ZeroExt32to64 x))
index 8dfa9ab6d6f20a09c4b27c05301359af3feea168..f958acba05a19e7d01c1d83ea23b825e6f4d9706 100644 (file)
@@ -466,8 +466,12 @@ func rewriteValueARM(v *Value) bool {
                return true
        case OpAvg32u:
                return rewriteValueARM_OpAvg32u(v)
+       case OpBitLen16:
+               return rewriteValueARM_OpBitLen16(v)
        case OpBitLen32:
                return rewriteValueARM_OpBitLen32(v)
+       case OpBitLen8:
+               return rewriteValueARM_OpBitLen8(v)
        case OpBswap32:
                return rewriteValueARM_OpBswap32(v)
        case OpClosureCall:
@@ -13070,6 +13074,21 @@ func rewriteValueARM_OpAvg32u(v *Value) bool {
                return true
        }
 }
+func rewriteValueARM_OpBitLen16(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen16 x)
+       // result: (BitLen32 (ZeroExt16to32 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen32)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpBitLen32(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
@@ -13086,6 +13105,21 @@ func rewriteValueARM_OpBitLen32(v *Value) bool {
                return true
        }
 }
+func rewriteValueARM_OpBitLen8(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen8 x)
+       // result: (BitLen32 (ZeroExt8to32 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen32)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpBswap32(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
index def0003764d3c5d24639ac2a27d0aa7ebb7b30b4..909414ee17ee7d7b6cc28edbf891ff032c463e45 100644 (file)
@@ -563,10 +563,14 @@ func rewriteValueARM64(v *Value) bool {
                return true
        case OpAvg64u:
                return rewriteValueARM64_OpAvg64u(v)
+       case OpBitLen16:
+               return rewriteValueARM64_OpBitLen16(v)
        case OpBitLen32:
                return rewriteValueARM64_OpBitLen32(v)
        case OpBitLen64:
                return rewriteValueARM64_OpBitLen64(v)
+       case OpBitLen8:
+               return rewriteValueARM64_OpBitLen8(v)
        case OpBitRev16:
                return rewriteValueARM64_OpBitRev16(v)
        case OpBitRev32:
@@ -18350,6 +18354,21 @@ func rewriteValueARM64_OpAvg64u(v *Value) bool {
                return true
        }
 }
+func rewriteValueARM64_OpBitLen16(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen16 x)
+       // result: (BitLen64 (ZeroExt16to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM64_OpBitLen32(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
@@ -18384,6 +18403,21 @@ func rewriteValueARM64_OpBitLen64(v *Value) bool {
                return true
        }
 }
+func rewriteValueARM64_OpBitLen8(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen8 x)
+       // result: (BitLen64 (ZeroExt8to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM64_OpBitRev16(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
index ab39040de196e00b402990e824a17510adb81860..ba0ea088d49bc7de5844edf84bffc61c8ecb1978 100644 (file)
@@ -129,10 +129,14 @@ func rewriteValueLOONG64(v *Value) bool {
                return true
        case OpAvg64u:
                return rewriteValueLOONG64_OpAvg64u(v)
+       case OpBitLen16:
+               return rewriteValueLOONG64_OpBitLen16(v)
        case OpBitLen32:
                return rewriteValueLOONG64_OpBitLen32(v)
        case OpBitLen64:
                return rewriteValueLOONG64_OpBitLen64(v)
+       case OpBitLen8:
+               return rewriteValueLOONG64_OpBitLen8(v)
        case OpBitRev16:
                return rewriteValueLOONG64_OpBitRev16(v)
        case OpBitRev32:
@@ -995,6 +999,21 @@ func rewriteValueLOONG64_OpAvg64u(v *Value) bool {
                return true
        }
 }
+func rewriteValueLOONG64_OpBitLen16(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen16 x)
+       // result: (BitLen64 (ZeroExt16to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueLOONG64_OpBitLen32(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
@@ -1033,6 +1052,21 @@ func rewriteValueLOONG64_OpBitLen64(v *Value) bool {
                return true
        }
 }
+func rewriteValueLOONG64_OpBitLen8(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen8 x)
+       // result: (BitLen64 (ZeroExt8to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueLOONG64_OpBitRev16(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
index 045ebb955af871b3419cd9fb06518545374ef6da..5b95549486987303c47d29ed01488073f1df880a 100644 (file)
@@ -82,8 +82,12 @@ func rewriteValueMIPS(v *Value) bool {
                return true
        case OpAvg32u:
                return rewriteValueMIPS_OpAvg32u(v)
+       case OpBitLen16:
+               return rewriteValueMIPS_OpBitLen16(v)
        case OpBitLen32:
                return rewriteValueMIPS_OpBitLen32(v)
+       case OpBitLen8:
+               return rewriteValueMIPS_OpBitLen8(v)
        case OpClosureCall:
                v.Op = OpMIPSCALLclosure
                return true
@@ -792,6 +796,21 @@ func rewriteValueMIPS_OpAvg32u(v *Value) bool {
                return true
        }
 }
+func rewriteValueMIPS_OpBitLen16(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen16 x)
+       // result: (BitLen32 (ZeroExt16to32 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen32)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueMIPS_OpBitLen32(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
@@ -810,6 +829,21 @@ func rewriteValueMIPS_OpBitLen32(v *Value) bool {
                return true
        }
 }
+func rewriteValueMIPS_OpBitLen8(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen8 x)
+       // result: (BitLen32 (ZeroExt8to32 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen32)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueMIPS_OpCom16(v *Value) bool {
        v_0 := v.Args[0]
        // match: (Com16 x)
index 4e3b8a5cc686abf98da8a62fe864c00e834fcb68..e900ebe0be2bcfbfb1bd53a65ac1e57a7a750ab9 100644 (file)
@@ -106,10 +106,14 @@ func rewriteValuePPC64(v *Value) bool {
                return rewriteValuePPC64_OpAtomicStoreRel64(v)
        case OpAvg64u:
                return rewriteValuePPC64_OpAvg64u(v)
+       case OpBitLen16:
+               return rewriteValuePPC64_OpBitLen16(v)
        case OpBitLen32:
                return rewriteValuePPC64_OpBitLen32(v)
        case OpBitLen64:
                return rewriteValuePPC64_OpBitLen64(v)
+       case OpBitLen8:
+               return rewriteValuePPC64_OpBitLen8(v)
        case OpBswap16:
                return rewriteValuePPC64_OpBswap16(v)
        case OpBswap32:
@@ -1123,6 +1127,21 @@ func rewriteValuePPC64_OpAvg64u(v *Value) bool {
                return true
        }
 }
+func rewriteValuePPC64_OpBitLen16(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen16 x)
+       // result: (BitLen64 (ZeroExt16to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValuePPC64_OpBitLen32(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
@@ -1155,6 +1174,21 @@ func rewriteValuePPC64_OpBitLen64(v *Value) bool {
                return true
        }
 }
+func rewriteValuePPC64_OpBitLen8(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen8 x)
+       // result: (BitLen64 (ZeroExt8to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValuePPC64_OpBswap16(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
index 1816d2e27eeb3cd68d598dc4f328f12e45bf0dc5..357b17f8fd8c584b0c76ff8c14cea509ea0d2d0e 100644 (file)
@@ -88,8 +88,14 @@ func rewriteValueS390X(v *Value) bool {
                return rewriteValueS390X_OpAtomicStoreRel32(v)
        case OpAvg64u:
                return rewriteValueS390X_OpAvg64u(v)
+       case OpBitLen16:
+               return rewriteValueS390X_OpBitLen16(v)
+       case OpBitLen32:
+               return rewriteValueS390X_OpBitLen32(v)
        case OpBitLen64:
                return rewriteValueS390X_OpBitLen64(v)
+       case OpBitLen8:
+               return rewriteValueS390X_OpBitLen8(v)
        case OpBswap16:
                return rewriteValueS390X_OpBswap16(v)
        case OpBswap32:
@@ -1261,6 +1267,36 @@ func rewriteValueS390X_OpAvg64u(v *Value) bool {
                return true
        }
 }
+func rewriteValueS390X_OpBitLen16(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen16 x)
+       // result: (BitLen64 (ZeroExt16to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueS390X_OpBitLen32(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen32 x)
+       // result: (BitLen64 (ZeroExt32to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueS390X_OpBitLen64(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
@@ -1278,6 +1314,21 @@ func rewriteValueS390X_OpBitLen64(v *Value) bool {
                return true
        }
 }
+func rewriteValueS390X_OpBitLen8(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen8 x)
+       // result: (BitLen64 (ZeroExt8to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueS390X_OpBswap16(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
index e0d753185f6649f10a2b50a431978ec7f3bf0c50..c3c5528aaa6ab4690f3351e8331056d124a2e876 100644 (file)
@@ -49,8 +49,14 @@ func rewriteValueWasm(v *Value) bool {
        case OpAndB:
                v.Op = OpWasmI64And
                return true
+       case OpBitLen16:
+               return rewriteValueWasm_OpBitLen16(v)
+       case OpBitLen32:
+               return rewriteValueWasm_OpBitLen32(v)
        case OpBitLen64:
                return rewriteValueWasm_OpBitLen64(v)
+       case OpBitLen8:
+               return rewriteValueWasm_OpBitLen8(v)
        case OpCeil:
                v.Op = OpWasmF64Ceil
                return true
@@ -679,6 +685,36 @@ func rewriteValueWasm_OpAddr(v *Value) bool {
                return true
        }
 }
+func rewriteValueWasm_OpBitLen16(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen16 x)
+       // result: (BitLen64 (ZeroExt16to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueWasm_OpBitLen32(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen32 x)
+       // result: (BitLen64 (ZeroExt32to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueWasm_OpBitLen64(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
@@ -696,6 +732,21 @@ func rewriteValueWasm_OpBitLen64(v *Value) bool {
                return true
        }
 }
+func rewriteValueWasm_OpBitLen8(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (BitLen8 x)
+       // result: (BitLen64 (ZeroExt8to64 x))
+       for {
+               x := v_0
+               v.reset(OpBitLen64)
+               v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueWasm_OpCom16(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
index e4da86db51ad8b2ca143290c75dab28d47484067..39d070a09057ff8426101dcafec9dc3ce6a79e3f 100644 (file)
@@ -963,51 +963,22 @@ func initIntrinsics(cfg *intrinsicBuildConfig) {
                func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
                        return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], args[0])
                },
-               sys.AMD64, sys.ARM64, sys.ARM, sys.Loong64, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+               sys.AMD64, sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.PPC64, sys.S390X, sys.Wasm)
        addF("math/bits", "Len32",
                func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
                        return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], args[0])
                },
-               sys.AMD64, sys.ARM64, sys.Loong64, sys.PPC64)
-       addF("math/bits", "Len32",
-               func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
-                       if s.config.PtrSize == 4 {
-                               return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], args[0])
-                       }
-                       x := s.newValue1(ssa.OpZeroExt32to64, types.Types[types.TUINT64], args[0])
-                       return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
-               },
-               sys.ARM, sys.S390X, sys.MIPS, sys.Wasm)
-       addF("math/bits", "Len16",
-               func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
-                       if s.config.PtrSize == 4 {
-                               x := s.newValue1(ssa.OpZeroExt16to32, types.Types[types.TUINT32], args[0])
-                               return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], x)
-                       }
-                       x := s.newValue1(ssa.OpZeroExt16to64, types.Types[types.TUINT64], args[0])
-                       return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
-               },
-               sys.ARM64, sys.ARM, sys.Loong64, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+               sys.AMD64, sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.PPC64, sys.S390X, sys.Wasm)
        addF("math/bits", "Len16",
                func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
                        return s.newValue1(ssa.OpBitLen16, types.Types[types.TINT], args[0])
                },
-               sys.AMD64)
-       addF("math/bits", "Len8",
-               func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
-                       if s.config.PtrSize == 4 {
-                               x := s.newValue1(ssa.OpZeroExt8to32, types.Types[types.TUINT32], args[0])
-                               return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], x)
-                       }
-                       x := s.newValue1(ssa.OpZeroExt8to64, types.Types[types.TUINT64], args[0])
-                       return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
-               },
-               sys.ARM64, sys.ARM, sys.Loong64, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+               sys.AMD64, sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.PPC64, sys.S390X, sys.Wasm)
        addF("math/bits", "Len8",
                func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
                        return s.newValue1(ssa.OpBitLen8, types.Types[types.TINT], args[0])
                },
-               sys.AMD64)
+               sys.AMD64, sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.PPC64, sys.S390X, sys.Wasm)
        addF("math/bits", "Len",
                func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
                        if s.config.PtrSize == 4 {
@@ -1015,7 +986,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) {
                        }
                        return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], args[0])
                },
-               sys.AMD64, sys.ARM64, sys.ARM, sys.Loong64, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
+               sys.AMD64, sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.PPC64, sys.S390X, sys.Wasm)
        // LeadingZeros is handled because it trivially calls Len.
        addF("math/bits", "Reverse64",
                func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {