]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: repair bisection behavior for float-to-unsigned conversion
authorDavid Chase <drchase@google.com>
Fri, 10 Oct 2025 21:08:20 +0000 (17:08 -0400)
committerDavid Chase <drchase@google.com>
Fri, 10 Oct 2025 23:21:25 +0000 (16:21 -0700)
My stab at a bisect-reproducer failed, but I verified that
it fixed the problem described in the issue.

Updates #75834

Change-Id: I9e0dfacd2bbd22cbc557e144920ee3417a48088c
Reviewed-on: https://go-review.googlesource.com/c/go/+/710997
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/compile/internal/ssagen/ssa.go

index 57cd9084821237a0bb25e04ff54bcbe6b84f1451..e2ef33274577cce8b489886e43ac0ee73a0ae718 100644 (file)
@@ -2865,7 +2865,19 @@ func (s *state) conv(n ir.Node, v *ssa.Value, ft, tt *types.Type) *ssa.Value {
        }
 
        if ft.IsFloat() || tt.IsFloat() {
-               conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
+               cft, ctt := s.concreteEtype(ft), s.concreteEtype(tt)
+               conv, ok := fpConvOpToSSA[twoTypes{cft, ctt}]
+               // there's a change to a conversion-op table, this restores the old behavior if ConvertHash is false.
+               // use salted hash to distinguish unsigned convert at a Pos from signed convert at a Pos
+               if ctt == types.TUINT32 && ft.IsFloat() && !base.ConvertHash.MatchPosWithInfo(n.Pos(), "U", nil) {
+                       // revert to old behavior
+                       conv.op1 = ssa.OpCvt64Fto64
+                       if cft == types.TFLOAT32 {
+                               conv.op1 = ssa.OpCvt32Fto64
+                       }
+                       conv.op2 = ssa.OpTrunc64to32
+
+               }
                if s.config.RegSize == 4 && Arch.LinkArch.Family != sys.MIPS && !s.softFloat {
                        if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
                                conv = conv1
@@ -5862,6 +5874,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n ir.Node, x *ssa.Value, ft, tt *
        // cutoff:=1<<(intY_Size-1)
        // if x < floatX(cutoff) {
        //      result = uintY(x) // bThen
+       //  // gated by ConvertHash, clamp negative inputs to zero
        //      if x < 0 { // unlikely
        //              result = 0 // bZero
        //      }
@@ -5879,7 +5892,8 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n ir.Node, x *ssa.Value, ft, tt *
        b.Likely = ssa.BranchLikely
 
        var bThen, bZero *ssa.Block
-       newConversion := base.ConvertHash.MatchPos(n.Pos(), nil)
+       // use salted hash to distinguish unsigned convert at a Pos from signed convert at a Pos
+       newConversion := base.ConvertHash.MatchPosWithInfo(n.Pos(), "U", nil)
        if newConversion {
                bZero = s.f.NewBlock(ssa.BlockPlain)
                bThen = s.f.NewBlock(ssa.BlockIf)