]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: merge ANDconst and UBFX into UBFX on arm64
authorfanzha02 <fannie.zhang@arm.com>
Tue, 3 Nov 2020 09:31:04 +0000 (17:31 +0800)
committerFannie Zhang <Fannie.Zhang@arm.com>
Fri, 25 Mar 2022 01:24:44 +0000 (01:24 +0000)
Add a new rewrite rule to merge ANDconst and UBFX into
UBFX.

Add test cases.

Change-Id: I24d6442d0c956d7ce092c3a3858d4a3a41771670
Reviewed-on: https://go-review.googlesource.com/c/go/+/377054
Trust: Fannie Zhang <Fannie.Zhang@arm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/rewriteARM64.go
test/codegen/bitfield.go

index be8be4ebe3215dddbf266b4536c0e235e4a18c09..1163ae837b1ca03379b04b1a7b088108c5ad07a8 100644 (file)
 // (x & ac) >> sc
 (SRLconst [sc] (ANDconst [ac] x)) && isARM64BFMask(sc, ac, sc)
        => (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
-
+// merge ANDconst and ubfx into ubfx
+(ANDconst [c] (UBFX [bfc] x)) && isARM64BFMask(0, c, 0) =>
+       (UBFX [armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0)))] x)
+(UBFX [bfc] (ANDconst [c] x)) && isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb() + bfc.getARM64BFwidth() <= arm64BFWidth(c, 0) =>
+       (UBFX [bfc] x)
 // merge ubfx and zerso-extension into ubfx
 (MOVWUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 32 => (UBFX [bfc] x)
 (MOVHUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 16 => (UBFX [bfc] x)
index c5f53e55072efd3df5d33a865c2c39275d798390..2ed1c0a04a4c79815329d97c119d5247c1b2a1ed 100644 (file)
@@ -2283,6 +2283,24 @@ func rewriteValueARM64_OpARM64ANDconst(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (ANDconst [c] (UBFX [bfc] x))
+       // cond: isARM64BFMask(0, c, 0)
+       // result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0)))] x)
+       for {
+               c := auxIntToInt64(v.AuxInt)
+               if v_0.Op != OpARM64UBFX {
+                       break
+               }
+               bfc := auxIntToArm64BitField(v_0.AuxInt)
+               x := v_0.Args[0]
+               if !(isARM64BFMask(0, c, 0)) {
+                       break
+               }
+               v.reset(OpARM64UBFX)
+               v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0))))
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValueARM64_OpARM64ANDshiftLL(v *Value) bool {
@@ -21802,6 +21820,24 @@ func rewriteValueARM64_OpARM64UBFIZ(v *Value) bool {
 }
 func rewriteValueARM64_OpARM64UBFX(v *Value) bool {
        v_0 := v.Args[0]
+       // match: (UBFX [bfc] (ANDconst [c] x))
+       // cond: isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb() + bfc.getARM64BFwidth() <= arm64BFWidth(c, 0)
+       // result: (UBFX [bfc] x)
+       for {
+               bfc := auxIntToArm64BitField(v.AuxInt)
+               if v_0.Op != OpARM64ANDconst {
+                       break
+               }
+               c := auxIntToInt64(v_0.AuxInt)
+               x := v_0.Args[0]
+               if !(isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb()+bfc.getARM64BFwidth() <= arm64BFWidth(c, 0)) {
+                       break
+               }
+               v.reset(OpARM64UBFX)
+               v.AuxInt = arm64BitFieldToAuxInt(bfc)
+               v.AddArg(x)
+               return true
+       }
        // match: (UBFX [bfc] (SRLconst [sc] x))
        // cond: sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64
        // result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth())] x)
index 8327da6cf8b414f3fbd6daf3d35ff0457704eef0..11f31ecf25f8a0cd145bf1705ce847ebf8a13c64 100644 (file)
@@ -321,6 +321,12 @@ func ubfx15(x uint64) bool {
        return false
 }
 
+// merge ANDconst and ubfx into ubfx
+func ubfx16(x uint64) uint64 {
+       // arm64:"UBFX\t[$]4, R[0-9]+, [$]6",-"AND\t[$]63"
+       return ((x >> 3) & 0xfff) >> 1 & 0x3f
+}
+
 // Check that we don't emit comparisons for constant shifts.
 //go:nosplit
 func shift_no_cmp(x int) int {