[go] cmd/compile: use immediates for uint8/uint16 bitwise ops on PPC64

12 views
Skip to first unread message

Jayanth Krishnamurthy (Gerrit)

unread,
Sep 15, 2025, 6:49:18 PMSep 15
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Jayanth Krishnamurthy has uploaded the change for review

Commit message

cmd/compile: use immediates for uint8/uint16  bitwise ops on PPC64

On PPC64, bitwise operations (AND, OR, XOR) on uint8/uint16 with
constants such as 1<<15 were materializing the constant with MOVD,
often as a negative value (e.g., MOVD $-32768). This led to extra
instructions compared to uint32/uint64 cases, which correctly used
immediate forms.

This CL adds latelower rewrite rules so that uint8/uint16 AND, OR, and XOR with
constants that fit in 16 bits (unsigned or sign-extended) are lowered
to immediate instructions (andi., ori, xori). The constant is always
zero-extended to match the result width (8 or 16 bits). Rules are
restricted to unsigned types to avoid sign-extension issues.

Also adds regression tests under test/codegen to ensure that these
operations use ANDCC/OR/XOR immediates and do not materialize constants
via MOVD.
Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
Cq-Include-Trybots: luci.golang.try:gotip-linux-ppc64_power10,gotip-linux-ppc64_power8,gotip-linux-ppc64le_power8,gotip-linux-ppc64le_power9,gotip-linux-ppc64le_power10

Change diff

diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules b/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules
index 15e6f72..9438485 100644
--- a/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules
@@ -18,8 +18,21 @@
(SETBC [1] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [1] (MOVDconst [1]) cmp)
(SETBCR [1] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [5] (MOVDconst [1]) cmp)

-// The upper bits of the smaller than register values is undefined. Take advantage of that.
-(AND <t> x:(MOVDconst [m]) n) && t.Size() <= 2 => (ANDconst [int64(int16(m))] n)
+// Sub-word bitwise operations on PPC64 (uint8/uint16).
+// Use immediate forms (andi., ori, xori) for 16-bit constants instead of
+// materializing constants (e.g., -32768 for 1<<15). Constants must fit in
+// 16 bits (unsigned or sign-extended). Results are zero-extended to type
+// width (8 or 16 bits). Upper bits are undefined. Commute rules handle
+// left-constant cases (e.g., (1<<15) & v).
+
+(AND <t> x:(MOVDconst [m]) n)&& t.Size() == 1 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m ) => (Select0 (ANDCCconst [int64(uint64(m) & 0x00FF)] n))
+(AND <t> x:(MOVDconst [m]) n)&& t.Size() == 2 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m ) => (Select0 (ANDCCconst [int64(uint64(m) & 0xFFFF)] n))
+(OR <t> x:(MOVDconst [m]) n)&& t.Size() == 1 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m ) => (ORconst [int64(uint64(m) & 0x00FF)] n)
+(OR <t> x:(MOVDconst [m]) n)&& t.Size() == 2 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m ) => (ORconst [int64(uint64(m) & 0xFFFF)] n)
+(XOR <t> x:(MOVDconst [m]) n)&& t.Size() == 1 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m ) => (XORconst [int64(uint64(m) & 0x00FF)] n)
+(XOR <t> x:(MOVDconst [m]) n)&& t.Size() == 2 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m )=> (XORconst [int64(uint64(m) & 0xFFFF)] n)
+
+

// Convert simple bit masks to an equivalent rldic[lr] if possible.
(AND x:(MOVDconst [m]) n) && isPPC64ValidShiftMask(m) => (RLDICL [encodePPC64RotateMask(0,m,64)] n)
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64latelower.go b/src/cmd/compile/internal/ssa/rewritePPC64latelower.go
index 18c0528..5bde605 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64latelower.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64latelower.go
@@ -3,6 +3,7 @@
package ssa

import "internal/buildcfg"
+import "cmd/compile/internal/types"

func rewriteValuePPC64latelower(v *Value) bool {
switch v.Op {
@@ -16,6 +17,8 @@
return rewriteValuePPC64latelower_OpPPC64CMPconst(v)
case OpPPC64ISEL:
return rewriteValuePPC64latelower_OpPPC64ISEL(v)
+ case OpPPC64OR:
+ return rewriteValuePPC64latelower_OpPPC64OR(v)
case OpPPC64RLDICL:
return rewriteValuePPC64latelower_OpPPC64RLDICL(v)
case OpPPC64RLDICLCC:
@@ -24,6 +27,8 @@
return rewriteValuePPC64latelower_OpPPC64SETBC(v)
case OpPPC64SETBCR:
return rewriteValuePPC64latelower_OpPPC64SETBCR(v)
+ case OpPPC64XOR:
+ return rewriteValuePPC64latelower_OpPPC64XOR(v)
}
return false
}
@@ -55,9 +60,11 @@
func rewriteValuePPC64latelower_OpPPC64AND(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
// match: (AND <t> x:(MOVDconst [m]) n)
- // cond: t.Size() <= 2
- // result: (ANDconst [int64(int16(m))] n)
+ // cond: t.Size() == 1 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m )
+ // result: (Select0 (ANDCCconst [int64(uint64(m) & 0x00FF)] n))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -67,12 +74,38 @@
}
m := auxIntToInt64(x.AuxInt)
n := v_1
- if !(t.Size() <= 2) {
+ if !(t.Size() == 1 && ((uint64(m)&^0xFFFF) == 0 || int64(int16(m)) == m)) {
continue
}
- v.reset(OpPPC64ANDconst)
- v.AuxInt = int64ToAuxInt(int64(int16(m)))
- v.AddArg(n)
+ v.reset(OpSelect0)
+ v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+ v0.AuxInt = int64ToAuxInt(int64(uint64(m) & 0x00FF))
+ v0.AddArg(n)
+ v.AddArg(v0)
+ return true
+ }
+ break
+ }
+ // match: (AND <t> x:(MOVDconst [m]) n)
+ // cond: t.Size() == 2 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m )
+ // result: (Select0 (ANDCCconst [int64(uint64(m) & 0xFFFF)] n))
+ for {
+ t := v.Type
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ x := v_0
+ if x.Op != OpPPC64MOVDconst {
+ continue
+ }
+ m := auxIntToInt64(x.AuxInt)
+ n := v_1
+ if !(t.Size() == 2 && ((uint64(m)&^0xFFFF) == 0 || int64(int16(m)) == m)) {
+ continue
+ }
+ v.reset(OpSelect0)
+ v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+ v0.AuxInt = int64ToAuxInt(int64(uint64(m) & 0xFFFF))
+ v0.AddArg(n)
+ v.AddArg(v0)
return true
}
break
@@ -656,6 +689,55 @@
}
return false
}
+func rewriteValuePPC64latelower_OpPPC64OR(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (OR <t> x:(MOVDconst [m]) n)
+ // cond: t.Size() == 1 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m )
+ // result: (ORconst [int64(uint64(m) & 0x00FF)] n)
+ for {
+ t := v.Type
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ x := v_0
+ if x.Op != OpPPC64MOVDconst {
+ continue
+ }
+ m := auxIntToInt64(x.AuxInt)
+ n := v_1
+ if !(t.Size() == 1 && ((uint64(m)&^0xFFFF) == 0 || int64(int16(m)) == m)) {
+ continue
+ }
+ v.reset(OpPPC64ORconst)
+ v.AuxInt = int64ToAuxInt(int64(uint64(m) & 0x00FF))
+ v.AddArg(n)
+ return true
+ }
+ break
+ }
+ // match: (OR <t> x:(MOVDconst [m]) n)
+ // cond: t.Size() == 2 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m )
+ // result: (ORconst [int64(uint64(m) & 0xFFFF)] n)
+ for {
+ t := v.Type
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ x := v_0
+ if x.Op != OpPPC64MOVDconst {
+ continue
+ }
+ m := auxIntToInt64(x.AuxInt)
+ n := v_1
+ if !(t.Size() == 2 && ((uint64(m)&^0xFFFF) == 0 || int64(int16(m)) == m)) {
+ continue
+ }
+ v.reset(OpPPC64ORconst)
+ v.AuxInt = int64ToAuxInt(int64(uint64(m) & 0xFFFF))
+ v.AddArg(n)
+ return true
+ }
+ break
+ }
+ return false
+}
func rewriteValuePPC64latelower_OpPPC64RLDICL(v *Value) bool {
v_0 := v.Args[0]
// match: (RLDICL [em] x:(SRDconst [s] a))
@@ -817,6 +899,55 @@
}
return false
}
+func rewriteValuePPC64latelower_OpPPC64XOR(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (XOR <t> x:(MOVDconst [m]) n)
+ // cond: t.Size() == 1 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m )
+ // result: (XORconst [int64(uint64(m) & 0x00FF)] n)
+ for {
+ t := v.Type
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ x := v_0
+ if x.Op != OpPPC64MOVDconst {
+ continue
+ }
+ m := auxIntToInt64(x.AuxInt)
+ n := v_1
+ if !(t.Size() == 1 && ((uint64(m)&^0xFFFF) == 0 || int64(int16(m)) == m)) {
+ continue
+ }
+ v.reset(OpPPC64XORconst)
+ v.AuxInt = int64ToAuxInt(int64(uint64(m) & 0x00FF))
+ v.AddArg(n)
+ return true
+ }
+ break
+ }
+ // match: (XOR <t> x:(MOVDconst [m]) n)
+ // cond: t.Size() == 2 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m )
+ // result: (XORconst [int64(uint64(m) & 0xFFFF)] n)
+ for {
+ t := v.Type
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ x := v_0
+ if x.Op != OpPPC64MOVDconst {
+ continue
+ }
+ m := auxIntToInt64(x.AuxInt)
+ n := v_1
+ if !(t.Size() == 2 && ((uint64(m)&^0xFFFF) == 0 || int64(int16(m)) == m)) {
+ continue
+ }
+ v.reset(OpPPC64XORconst)
+ v.AuxInt = int64ToAuxInt(int64(uint64(m) & 0xFFFF))
+ v.AddArg(n)
+ return true
+ }
+ break
+ }
+ return false
+}
func rewriteBlockPPC64latelower(b *Block) bool {
return false
}
diff --git a/test/codegen/subword_andorxor.go b/test/codegen/subword_andorxor.go
new file mode 100644
index 0000000..c3c8e8e
--- /dev/null
+++ b/test/codegen/subword_andorxor.go
@@ -0,0 +1,59 @@
+// asmcheck
+
+// Copyright 2025 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.
+// Codegen test for PPC64 sub-word AND/OR/XOR immediates.
+
+package codegen
+
+//go:noinline
+func U16And(v uint16) uint16 {
+ // ppc64x:-"^MOVD\t\\$-?32768"
+ // ppc64x:"^ANDCC\t\\$32768, R[0-9]+, R[0-9]+"
+ return v & (1 << 15)
+}
+
+//go:noinline
+func U16Or(v uint16) uint16 {
+ // ppc64x:-"^MOVD\t\\$-?32768"
+ // ppc64x:"^(OR|ORI)\t\\$32768, R[0-9]+, R[0-9]+"
+ return v | (1 << 15)
+}
+
+//go:noinline
+func U16Xor(v uint16) uint16 {
+ // ppc64x:-"^MOVD\t\\$-?32768"
+ // ppc64x:"^(XOR|XORI)\t\\$32768, R[0-9]+, R[0-9]+"
+ return v ^ (1 << 15)
+}
+
+//go:noinline
+func U8And(v uint8) uint8 {
+ // ppc64x:-"^MOVD\t\\$-?128"
+ // ppc64x:"^ANDCC\t\\$128, R[0-9]+, R[0-9]+"
+ return v & (1 << 7)
+}
+
+//go:noinline
+func U8Or(v uint8) uint8 {
+ // ppc64x:-"^MOVD\t\\$-?128"
+ // ppc64x:"^(OR|ORI)\t\\$128, R[0-9]+, R[0-9]+"
+ return v | (1 << 7)
+}
+
+//go:noinline
+func U8Xor(v uint8) uint8 {
+ // ppc64x:-"^MOVD\t\\$-?128"
+ // ppc64x:"^(XOR|XORI)\t\\$128, R[0-9]+, R[0-9]+"
+ return v ^ (1 << 7)
+}
+
+// --- 32-bit AND sanity (ANDCC with limm16 is still expected) ---
+
+//go:noinline
+func U32And(v uint32) uint32 {
+ // ppc64x:-"^MOVD\t\\$-?32768"
+ // ppc64x:"^ANDCC\t\\$32768, R[0-9]+, R[0-9]+"
+ return v & (1 << 15)
+}
\ No newline at end of file

Change information

Files:
  • M src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules
  • M src/cmd/compile/internal/ssa/rewritePPC64latelower.go
  • A test/codegen/subword_andorxor.go
Change size: M
Delta: 3 files changed, 211 insertions(+), 8 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
Gerrit-Change-Number: 704015
Gerrit-PatchSet: 1
Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Jayanth Krishnamurthy (Gerrit)

unread,
Sep 15, 2025, 6:50:44 PMSep 15
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Jayanth Krishnamurthy voted Run-TryBot+1

Run-TryBot+1
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedLegacy-TryBots-Pass
    • requirement satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
    Gerrit-Change-Number: 704015
    Gerrit-PatchSet: 1
    Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
    Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
    Gerrit-Comment-Date: Mon, 15 Sep 2025 22:50:36 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Jayanth Krishnamurthy (Gerrit)

    unread,
    Sep 15, 2025, 6:51:19 PMSep 15
    to goph...@pubsubhelper.golang.org, Gopher Robot, golang-co...@googlegroups.com

    Jayanth Krishnamurthy voted

    Commit-Queue+1
    Run-TryBot+0
    Open in Gerrit

    Related details

    Attention set is empty
    Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
      Gerrit-Change-Number: 704015
      Gerrit-PatchSet: 1
      Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
      Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
      Gerrit-CC: Gopher Robot <go...@golang.org>
      Gerrit-Comment-Date: Mon, 15 Sep 2025 22:51:11 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: Yes
      unsatisfied_requirement
      open
      diffy

      Jayanth Krishnamurthy (Gerrit)

      unread,
      Sep 15, 2025, 7:15:28 PMSep 15
      to goph...@pubsubhelper.golang.org, Go LUCI, Gopher Robot, golang-co...@googlegroups.com

      Jayanth Krishnamurthy voted Commit-Queue+1

      Commit-Queue+1
      Open in Gerrit

      Related details

      Attention set is empty
      Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement is not satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        • requirement satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
        Gerrit-Change-Number: 704015
        Gerrit-PatchSet: 1
        Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
        Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
        Gerrit-CC: Gopher Robot <go...@golang.org>
        Gerrit-Comment-Date: Mon, 15 Sep 2025 23:15:19 +0000
        Gerrit-HasComments: No
        Gerrit-Has-Labels: Yes
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Paul Murphy (Gerrit)

        unread,
        Sep 16, 2025, 9:37:48 AMSep 16
        to Jayanth Krishnamurthy, goph...@pubsubhelper.golang.org, Go LUCI, Gopher Robot, golang-co...@googlegroups.com
        Attention needed from Jayanth Krishnamurthy

        Paul Murphy added 1 comment

        File src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules
        Line 28, Patchset 1 (Latest):(AND <t> x:(MOVDconst [m]) n)&& t.Size() == 1 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m ) => (Select0 (ANDCCconst [int64(uint64(m) & 0x00FF)] n))
        Paul Murphy . unresolved

        I think algebraic rules should be in the first lowering pass. latelower is intended for rules which require (or are substantially simplified) by running the first lower pass to completion.

        As noted, smaller-than-register types are sign extended. Likewise, those upper x bits are generally ignored. However, the lowering rules also merge explicit sign/zero extensions into more complex operations. Thus, a bit of care and testing is needed when testing.

        Why not something like `(MOVDconst t [x] && t.size() == 2 && uint64(x) > 0xFFFF) => (MOVDconst t [x&0xFFFF])` and let the existing rules run?

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Jayanth Krishnamurthy
        Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement is not satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        • requirement satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
        Gerrit-Change-Number: 704015
        Gerrit-PatchSet: 1
        Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
        Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
        Gerrit-Reviewer: Paul Murphy <paum...@redhat.com>
        Gerrit-CC: Gopher Robot <go...@golang.org>
        Gerrit-Attention: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
        Gerrit-Comment-Date: Tue, 16 Sep 2025 13:37:44 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Paul Murphy (Gerrit)

        unread,
        Sep 16, 2025, 9:47:34 AMSep 16
        to Jayanth Krishnamurthy, goph...@pubsubhelper.golang.org, Go LUCI, Gopher Robot, golang-co...@googlegroups.com
        Attention needed from Jayanth Krishnamurthy

        Paul Murphy added 1 comment

        File test/codegen/subword_andorxor.go
        Line 20, Patchset 1 (Latest): // ppc64x:"^(OR|ORI)\t\\$32768, R[0-9]+, R[0-9]+"
        Paul Murphy . unresolved

        Are the immediate form instructions not consistently decoding in OR or ORI? Likewise for XOR.

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Jayanth Krishnamurthy
        Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement is not satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        • requirement satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
        Gerrit-Change-Number: 704015
        Gerrit-PatchSet: 1
        Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
        Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
        Gerrit-Reviewer: Paul Murphy <paum...@redhat.com>
        Gerrit-CC: Gopher Robot <go...@golang.org>
        Gerrit-Attention: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
        Gerrit-Comment-Date: Tue, 16 Sep 2025 13:47:31 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Jayanth Krishnamurthy (Gerrit)

        unread,
        Oct 6, 2025, 2:52:59 PMOct 6
        to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
        Attention needed from Jayanth Krishnamurthy

        Jayanth Krishnamurthy uploaded new patchset

        Jayanth Krishnamurthy uploaded patch set #2 to this change.
        Following approvals got outdated and were removed:
        • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
        Open in Gerrit

        Related details

        Attention is currently required from:
        • Jayanth Krishnamurthy
        Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
          Gerrit-Change-Number: 704015
          Gerrit-PatchSet: 2
          unsatisfied_requirement
          open
          diffy

          Jayanth Krishnamurthy (Gerrit)

          unread,
          Oct 6, 2025, 3:15:16 PMOct 6
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
          Attention needed from Jayanth Krishnamurthy

          Jayanth Krishnamurthy uploaded new patchset

          Jayanth Krishnamurthy uploaded patch set #3 to this change.
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Jayanth Krishnamurthy
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
          Gerrit-Change-Number: 704015
          Gerrit-PatchSet: 3
          unsatisfied_requirement
          open
          diffy

          Jayanth Krishnamurthy (Gerrit)

          unread,
          Oct 6, 2025, 11:52:24 PMOct 6
          to goph...@pubsubhelper.golang.org, Paul Murphy, Go LUCI, Gopher Robot, golang-co...@googlegroups.com
          Attention needed from Paul Murphy

          Jayanth Krishnamurthy voted and added 2 comments

          Votes added by Jayanth Krishnamurthy

          Commit-Queue+1

          2 comments

          File src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules
          Line 28, Patchset 1:(AND <t> x:(MOVDconst [m]) n)&& t.Size() == 1 && ( (uint64(m) &^ 0xFFFF) == 0 || int64(int16(m)) == m ) => (Select0 (ANDCCconst [int64(uint64(m) & 0x00FF)] n))
          Paul Murphy . resolved

          I think algebraic rules should be in the first lowering pass. latelower is intended for rules which require (or are substantially simplified) by running the first lower pass to completion.

          As noted, smaller-than-register types are sign extended. Likewise, those upper x bits are generally ignored. However, the lowering rules also merge explicit sign/zero extensions into more complex operations. Thus, a bit of care and testing is needed when testing.

          Why not something like `(MOVDconst t [x] && t.size() == 2 && uint64(x) > 0xFFFF) => (MOVDconst t [x&0xFFFF])` and let the existing rules run?

          Jayanth Krishnamurthy

          Thanks for the suggestion! I agree this is an algebraic cleanup better suited to the first lowering pass.

          However, applying a blanket rule like the above, could alter semantics for signed 16-bit constants (e.g., int16(-1) → 65535), since the first lowering also merges sign and zero extensions. I plan to move this logic to an earlier pass but restrict normalization to unsigned small types (uint8/uint16), ensuring correctness while still allowing existing ANDCCconst, ORconst, and XORconst rules to pick up the folded form naturally.

          The existing codegen test (subword_andorxor.go) will continue to verify that no MOVD $-32768 or $-128 sequences are emitted.

          File test/codegen/subword_andorxor.go
          Line 20, Patchset 1: // ppc64x:"^(OR|ORI)\t\\$32768, R[0-9]+, R[0-9]+"
          Paul Murphy . resolved

          Are the immediate form instructions not consistently decoding in OR or ORI? Likewise for XOR.

          Jayanth Krishnamurthy

          Yes — the issue affected all three bitwise ops (AND, OR, XOR) on uint8/uint16.
          In each case, constants like 1<<15 or 1<<7 were materialized via MOVD (e.g., $-32768 or $-128) instead of using the immediate forms (andi., ori, xori).
          The fix normalizes unsigned 8/16-bit constants early so all three ops now correctly use immediate forms.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Paul Murphy
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
          Gerrit-Change-Number: 704015
          Gerrit-PatchSet: 4
          Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
          Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
          Gerrit-Reviewer: Paul Murphy <paum...@redhat.com>
          Gerrit-CC: Gopher Robot <go...@golang.org>
          Gerrit-Attention: Paul Murphy <paum...@redhat.com>
          Gerrit-Comment-Date: Tue, 07 Oct 2025 03:52:16 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: Yes
          Comment-In-Reply-To: Paul Murphy <paum...@redhat.com>
          unsatisfied_requirement
          open
          diffy

          Jayanth Krishnamurthy (Gerrit)

          unread,
          Oct 6, 2025, 11:53:18 PMOct 6
          to goph...@pubsubhelper.golang.org, Paul Murphy, Go LUCI, Gopher Robot, golang-co...@googlegroups.com
          Attention needed from Paul Murphy

          Jayanth Krishnamurthy added 1 comment

          Patchset-level comments
          File-level comment, Patchset 1:
          Gopher Robot . resolved

          TryBots beginning. Status page: https://farmer.golang.org/try?commit=1922ced0

          Jayanth Krishnamurthy

          Acknowledged

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Paul Murphy
          Submit Requirements:
            • requirement is not satisfiedCode-Review
            • requirement satisfiedNo-Unresolved-Comments
            • requirement is not satisfiedReview-Enforcement
            • requirement is not satisfiedTryBots-Pass
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: comment
            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
            Gerrit-Change-Number: 704015
            Gerrit-PatchSet: 4
            Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
            Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
            Gerrit-Reviewer: Paul Murphy <paum...@redhat.com>
            Gerrit-CC: Gopher Robot <go...@golang.org>
            Gerrit-Attention: Paul Murphy <paum...@redhat.com>
            Gerrit-Comment-Date: Tue, 07 Oct 2025 03:53:12 +0000
            Gerrit-HasComments: Yes
            Gerrit-Has-Labels: No
            Comment-In-Reply-To: Gopher Robot <go...@golang.org>
            unsatisfied_requirement
            satisfied_requirement
            open
            diffy

            Paul Murphy (Gerrit)

            unread,
            Oct 7, 2025, 9:53:58 AMOct 7
            to Jayanth Krishnamurthy, goph...@pubsubhelper.golang.org, Go LUCI, Archana Ravindar, Gopher Robot, golang-co...@googlegroups.com
            Attention needed from Archana Ravindar and Jayanth Krishnamurthy

            Paul Murphy added 2 comments

            Patchset-level comments
            File-level comment, Patchset 4 (Latest):
            Paul Murphy . resolved

            @jayanth.kr...@ibm.com have you run any codegen tests to see how this changes/improves the instruction counts?

            File src/cmd/compile/internal/ssa/_gen/PPC64.rules
            Line 145, Patchset 4 (Latest):(MOVDconst <t> [x]) && t.Size() == 1 && t.IsUnsigned() && (uint64(x) &^ 0xFF) != 0 => (MOVDconst <t> [x & 0xFF])
            Paul Murphy . unresolved

            Is there any difference to codegen if you were to further specialize the following rule instead?

            ```(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])```

            Open in Gerrit

            Related details

            Attention is currently required from:
            • Archana Ravindar
            • Jayanth Krishnamurthy
            Submit Requirements:
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              • requirement satisfiedTryBots-Pass
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: go
              Gerrit-Branch: master
              Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
              Gerrit-Change-Number: 704015
              Gerrit-PatchSet: 4
              Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
              Gerrit-Reviewer: Archana Ravindar <arav...@redhat.com>
              Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
              Gerrit-Reviewer: Paul Murphy <paum...@redhat.com>
              Gerrit-CC: Gopher Robot <go...@golang.org>
              Gerrit-Attention: Archana Ravindar <arav...@redhat.com>
              Gerrit-Attention: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
              Gerrit-Comment-Date: Tue, 07 Oct 2025 13:53:53 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              unsatisfied_requirement
              satisfied_requirement
              open
              diffy

              Jayanth Krishnamurthy (Gerrit)

              unread,
              Oct 10, 2025, 11:21:33 AMOct 10
              to goph...@pubsubhelper.golang.org, Go LUCI, Archana Ravindar, Paul Murphy, Gopher Robot, golang-co...@googlegroups.com
              Attention needed from Archana Ravindar and Paul Murphy

              Jayanth Krishnamurthy added 2 comments

              Patchset-level comments
              Paul Murphy . resolved

              @jayanth.kr...@ibm.com have you run any codegen tests to see how this changes/improves the instruction counts?

              Jayanth Krishnamurthy

              Yes — I verified codegen before and after the change using both the new targeted test and standalone disassembly. Before (current tip, without normalization):
              uint8/uint16 OR/XOR emitted two instructions, e.g. MOVD $-32768, R4
              OR/XOR R4, R3, R3. (likewise $-128 for 8-bit). uint8/uint16 AND sometimes also materialized a MOVD constant. After (with this CL):
              All three ops fold to single-instruction immediate forms:
              ANDCC $32768, R3, R3
              OR $32768, R3, R3
              XOR $32768, R3, R3
              ANDCC $128, R3, R3
              OR $128, R3, R3
              XOR $128, R3, R3
              No MOVD $-32768 or $-128 appear anywhere.
              Instruction count reduced by one per affected operation.

              File src/cmd/compile/internal/ssa/_gen/PPC64.rules
              Line 145, Patchset 4 (Latest):(MOVDconst <t> [x]) && t.Size() == 1 && t.IsUnsigned() && (uint64(x) &^ 0xFF) != 0 => (MOVDconst <t> [x & 0xFF])
              Paul Murphy . unresolved

              Is there any difference to codegen if you were to further specialize the following rule instead?

              ```(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])```

              Jayanth Krishnamurthy

              Thanks, that’s a good point — I looked into that path.
              The suggested rule may move all constant forms into 64-bit space early, without regard to type width or signedness. If we specialize it to truncate val for unsigned 8/16-bit types, that may silently reinterpret constants (e.g., uint16(0x8000) → 0x8000, but int16(-1) → 0xFFFF), which may break signed semantics and interact with zero/sign-extension merges later in lowering.

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Archana Ravindar
              • Paul Murphy
              Submit Requirements:
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              • requirement satisfiedTryBots-Pass
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: go
              Gerrit-Branch: master
              Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
              Gerrit-Change-Number: 704015
              Gerrit-PatchSet: 4
              Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
              Gerrit-Reviewer: Archana Ravindar <arav...@redhat.com>
              Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
              Gerrit-Reviewer: Paul Murphy <paum...@redhat.com>
              Gerrit-CC: Gopher Robot <go...@golang.org>
              Gerrit-Attention: Archana Ravindar <arav...@redhat.com>
              Gerrit-Attention: Paul Murphy <paum...@redhat.com>
              Gerrit-Comment-Date: Fri, 10 Oct 2025 15:21:23 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              Comment-In-Reply-To: Paul Murphy <paum...@redhat.com>
              unsatisfied_requirement
              satisfied_requirement
              open
              diffy

              Jayanth Krishnamurthy (Gerrit)

              unread,
              Nov 11, 2025, 3:06:56 PM (2 days ago) Nov 11
              to goph...@pubsubhelper.golang.org, Go LUCI, Archana Ravindar, Paul Murphy, Gopher Robot, golang-co...@googlegroups.com
              Attention needed from Archana Ravindar and Paul Murphy

              Jayanth Krishnamurthy added 1 comment

              File src/cmd/compile/internal/ssa/_gen/PPC64.rules
              Line 145, Patchset 4 (Latest):(MOVDconst <t> [x]) && t.Size() == 1 && t.IsUnsigned() && (uint64(x) &^ 0xFF) != 0 => (MOVDconst <t> [x & 0xFF])
              Paul Murphy . resolved

              Is there any difference to codegen if you were to further specialize the following rule instead?

              ```(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])```

              Jayanth Krishnamurthy

              Thanks, that’s a good point — I looked into that path.
              The suggested rule may move all constant forms into 64-bit space early, without regard to type width or signedness. If we specialize it to truncate val for unsigned 8/16-bit types, that may silently reinterpret constants (e.g., uint16(0x8000) → 0x8000, but int16(-1) → 0xFFFF), which may break signed semantics and interact with zero/sign-extension merges later in lowering.

              Jayanth Krishnamurthy

              Marked as resolved.

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Archana Ravindar
              • Paul Murphy
              Submit Requirements:
                • requirement is not satisfiedCode-Review
                • requirement satisfiedNo-Unresolved-Comments
                • requirement is not satisfiedReview-Enforcement
                • requirement satisfiedTryBots-Pass
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: comment
                Gerrit-Project: go
                Gerrit-Branch: master
                Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
                Gerrit-Change-Number: 704015
                Gerrit-PatchSet: 4
                Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
                Gerrit-Reviewer: Archana Ravindar <arav...@redhat.com>
                Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
                Gerrit-Reviewer: Paul Murphy <paum...@redhat.com>
                Gerrit-CC: Gopher Robot <go...@golang.org>
                Gerrit-Attention: Archana Ravindar <arav...@redhat.com>
                Gerrit-Attention: Paul Murphy <paum...@redhat.com>
                Gerrit-Comment-Date: Tue, 11 Nov 2025 20:06:48 +0000
                Gerrit-HasComments: Yes
                Gerrit-Has-Labels: No
                Comment-In-Reply-To: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
                Comment-In-Reply-To: Paul Murphy <paum...@redhat.com>
                unsatisfied_requirement
                satisfied_requirement
                open
                diffy

                Paul Murphy (Gerrit)

                unread,
                Nov 11, 2025, 4:20:37 PM (2 days ago) Nov 11
                to Jayanth Krishnamurthy, goph...@pubsubhelper.golang.org, Go LUCI, Archana Ravindar, Gopher Robot, golang-co...@googlegroups.com
                Attention needed from Archana Ravindar and Jayanth Krishnamurthy

                Paul Murphy added 3 comments

                Patchset-level comments
                Paul Murphy . resolved

                This is a change I had

                File src/cmd/compile/internal/ssa/_gen/PPC64.rules
                Line 145, Patchset 4 (Latest):(MOVDconst <t> [x]) && t.Size() == 1 && t.IsUnsigned() && (uint64(x) &^ 0xFF) != 0 => (MOVDconst <t> [x & 0xFF])
                Paul Murphy . unresolved

                Is there any difference to codegen if you were to further specialize the following rule instead?

                ```(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])```

                Jayanth Krishnamurthy

                Thanks, that’s a good point — I looked into that path.
                The suggested rule may move all constant forms into 64-bit space early, without regard to type width or signedness. If we specialize it to truncate val for unsigned 8/16-bit types, that may silently reinterpret constants (e.g., uint16(0x8000) → 0x8000, but int16(-1) → 0xFFFF), which may break signed semantics and interact with zero/sign-extension merges later in lowering.

                Jayanth Krishnamurthy

                Marked as resolved.

                Paul Murphy

                Note, this will regress codegen for SI constant using ops, like addi and subfic. Values >= 0x8000 will into split two instructions.


                I think this should be more surgical. Only simplify those instructions which use a UI (e.g xori/ori/andi) constant.

                File test/codegen/subword_andorxor.go
                Line 1, Patchset 4 (Latest):// asmcheck
                Paul Murphy . unresolved

                I'm not sure these tests belong in a new file. They could be placed in `arithmetic.go` or `bits.go`.

                Open in Gerrit

                Related details

                Attention is currently required from:
                • Archana Ravindar
                • Jayanth Krishnamurthy
                Submit Requirements:
                  • requirement is not satisfiedCode-Review
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement is not satisfiedReview-Enforcement
                  • requirement satisfiedTryBots-Pass
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: go
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I9fcdf4498c4e984c7587814fb9019a75865c4a0d
                  Gerrit-Change-Number: 704015
                  Gerrit-PatchSet: 4
                  Gerrit-Owner: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
                  Gerrit-Reviewer: Archana Ravindar <arav...@redhat.com>
                  Gerrit-Reviewer: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
                  Gerrit-Reviewer: Paul Murphy <paum...@redhat.com>
                  Gerrit-CC: Gopher Robot <go...@golang.org>
                  Gerrit-Attention: Archana Ravindar <arav...@redhat.com>
                  Gerrit-Attention: Jayanth Krishnamurthy <jayanth.kr...@ibm.com>
                  Gerrit-Comment-Date: Tue, 11 Nov 2025 21:20:33 +0000
                  unsatisfied_requirement
                  satisfied_requirement
                  open
                  diffy
                  Reply all
                  Reply to author
                  Forward
                  0 new messages