]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: absorb InvertFlags into Noov comparisons
authorKeith Randall <khr@golang.org>
Wed, 6 Sep 2023 20:06:58 +0000 (13:06 -0700)
committerKeith Randall <khr@golang.org>
Thu, 7 Sep 2023 15:14:39 +0000 (15:14 +0000)
Unfortunately, there isn't a single op that provides the resulting
computation.
At least, I couldn't find one.

Fixes #62469

Change-Id: I236f3965b827aaeb3d70ef9fe89be66b116494f5
Reviewed-on: https://go-review.googlesource.com/c/go/+/526276
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@google.com>
src/cmd/compile/internal/ssa/_gen/ARM64.rules
src/cmd/compile/internal/ssa/rewriteARM64.go
test/fixedbugs/issue62469.go [new file with mode: 0644]

index 4a99771e3b87585ec1e6f2f1df5d24b59fb82a95..1719312fbd47b820cd4c99a1cb780939a268addf 100644 (file)
 (GreaterEqualU (FlagConstant [fc])) => (MOVDconst [b2i(fc.uge())])
 
 // absorb InvertFlags into boolean values
-(Equal         (InvertFlags x)) => (Equal x)
-(NotEqual      (InvertFlags x)) => (NotEqual x)
-(LessThan      (InvertFlags x)) => (GreaterThan x)
-(LessThanU     (InvertFlags x)) => (GreaterThanU x)
-(GreaterThan   (InvertFlags x)) => (LessThan x)
-(GreaterThanU  (InvertFlags x)) => (LessThanU x)
-(LessEqual     (InvertFlags x)) => (GreaterEqual x)
-(LessEqualU    (InvertFlags x)) => (GreaterEqualU x)
-(GreaterEqual  (InvertFlags x)) => (LessEqual x)
-(GreaterEqualU (InvertFlags x)) => (LessEqualU x)
-(LessThanF     (InvertFlags x)) => (GreaterThanF x)
-(LessEqualF    (InvertFlags x)) => (GreaterEqualF x)
-(GreaterThanF  (InvertFlags x)) => (LessThanF x)
-(GreaterEqualF (InvertFlags x)) => (LessEqualF x)
+(Equal            (InvertFlags x)) => (Equal x)
+(NotEqual         (InvertFlags x)) => (NotEqual x)
+(LessThan         (InvertFlags x)) => (GreaterThan x)
+(LessThanU        (InvertFlags x)) => (GreaterThanU x)
+(GreaterThan      (InvertFlags x)) => (LessThan x)
+(GreaterThanU     (InvertFlags x)) => (LessThanU x)
+(LessEqual        (InvertFlags x)) => (GreaterEqual x)
+(LessEqualU       (InvertFlags x)) => (GreaterEqualU x)
+(GreaterEqual     (InvertFlags x)) => (LessEqual x)
+(GreaterEqualU    (InvertFlags x)) => (LessEqualU x)
+(LessThanF        (InvertFlags x)) => (GreaterThanF x)
+(LessEqualF       (InvertFlags x)) => (GreaterEqualF x)
+(GreaterThanF     (InvertFlags x)) => (LessThanF x)
+(GreaterEqualF    (InvertFlags x)) => (LessEqualF x)
+(LessThanNoov     (InvertFlags x)) => (BIC (GreaterEqualNoov <typ.Bool> x) (Equal <typ.Bool> x))
+(GreaterEqualNoov (InvertFlags x)) => (OR (LessThanNoov <typ.Bool> x) (Equal <typ.Bool> x))
 
 // Boolean-generating instructions (NOTE: NOT all boolean Values) always
 // zero upper bit of the register; no need to zero-extend
index 84274bd506f6cd064ea8d1a27a69c98ed7861665..caeed8b6b9e53555998e5b14739a5ce768b65996 100644 (file)
@@ -154,6 +154,8 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpARM64GreaterEqual(v)
        case OpARM64GreaterEqualF:
                return rewriteValueARM64_OpARM64GreaterEqualF(v)
+       case OpARM64GreaterEqualNoov:
+               return rewriteValueARM64_OpARM64GreaterEqualNoov(v)
        case OpARM64GreaterEqualU:
                return rewriteValueARM64_OpARM64GreaterEqualU(v)
        case OpARM64GreaterThan:
@@ -174,6 +176,8 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpARM64LessThan(v)
        case OpARM64LessThanF:
                return rewriteValueARM64_OpARM64LessThanF(v)
+       case OpARM64LessThanNoov:
+               return rewriteValueARM64_OpARM64LessThanNoov(v)
        case OpARM64LessThanU:
                return rewriteValueARM64_OpARM64LessThanU(v)
        case OpARM64MADD:
@@ -5965,6 +5969,27 @@ func rewriteValueARM64_OpARM64GreaterEqualF(v *Value) bool {
        }
        return false
 }
+func rewriteValueARM64_OpARM64GreaterEqualNoov(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (GreaterEqualNoov (InvertFlags x))
+       // result: (OR (LessThanNoov <typ.Bool> x) (Equal <typ.Bool> x))
+       for {
+               if v_0.Op != OpARM64InvertFlags {
+                       break
+               }
+               x := v_0.Args[0]
+               v.reset(OpARM64OR)
+               v0 := b.NewValue0(v.Pos, OpARM64LessThanNoov, typ.Bool)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpARM64Equal, typ.Bool)
+               v1.AddArg(x)
+               v.AddArg2(v0, v1)
+               return true
+       }
+       return false
+}
 func rewriteValueARM64_OpARM64GreaterEqualU(v *Value) bool {
        v_0 := v.Args[0]
        // match: (GreaterEqualU (FlagConstant [fc]))
@@ -6679,6 +6704,27 @@ func rewriteValueARM64_OpARM64LessThanF(v *Value) bool {
        }
        return false
 }
+func rewriteValueARM64_OpARM64LessThanNoov(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
+       // match: (LessThanNoov (InvertFlags x))
+       // result: (BIC (GreaterEqualNoov <typ.Bool> x) (Equal <typ.Bool> x))
+       for {
+               if v_0.Op != OpARM64InvertFlags {
+                       break
+               }
+               x := v_0.Args[0]
+               v.reset(OpARM64BIC)
+               v0 := b.NewValue0(v.Pos, OpARM64GreaterEqualNoov, typ.Bool)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpARM64Equal, typ.Bool)
+               v1.AddArg(x)
+               v.AddArg2(v0, v1)
+               return true
+       }
+       return false
+}
 func rewriteValueARM64_OpARM64LessThanU(v *Value) bool {
        v_0 := v.Args[0]
        // match: (LessThanU (FlagConstant [fc]))
diff --git a/test/fixedbugs/issue62469.go b/test/fixedbugs/issue62469.go
new file mode 100644 (file)
index 0000000..d850ccb
--- /dev/null
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func sign(p1, p2, p3 point) bool {
+       return (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y) < 0
+}
+
+type point struct {
+       x, y int
+}