github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/compile/internal/ssa/prove.go (about)

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ssa
     6  
     7  import (
     8  	"fmt"
     9  	"math"
    10  )
    11  
    12  type branch int
    13  
    14  const (
    15  	unknown branch = iota
    16  	positive
    17  	negative
    18  )
    19  
    20  // relation represents the set of possible relations between
    21  // pairs of variables (v, w). Without a priori knowledge the
    22  // mask is lt | eq | gt meaning v can be less than, equal to or
    23  // greater than w. When the execution path branches on the condition
    24  // `v op w` the set of relations is updated to exclude any
    25  // relation not possible due to `v op w` being true (or false).
    26  //
    27  // E.g.
    28  //
    29  // r := relation(...)
    30  //
    31  // if v < w {
    32  //   newR := r & lt
    33  // }
    34  // if v >= w {
    35  //   newR := r & (eq|gt)
    36  // }
    37  // if v != w {
    38  //   newR := r & (lt|gt)
    39  // }
    40  type relation uint
    41  
    42  const (
    43  	lt relation = 1 << iota
    44  	eq
    45  	gt
    46  )
    47  
    48  var relationStrings = [...]string{
    49  	0: "none", lt: "<", eq: "==", lt | eq: "<=",
    50  	gt: ">", gt | lt: "!=", gt | eq: ">=", gt | eq | lt: "any",
    51  }
    52  
    53  func (r relation) String() string {
    54  	if r < relation(len(relationStrings)) {
    55  		return relationStrings[r]
    56  	}
    57  	return fmt.Sprintf("relation(%d)", uint(r))
    58  }
    59  
    60  // domain represents the domain of a variable pair in which a set
    61  // of relations is known. For example, relations learned for unsigned
    62  // pairs cannot be transferred to signed pairs because the same bit
    63  // representation can mean something else.
    64  type domain uint
    65  
    66  const (
    67  	signed domain = 1 << iota
    68  	unsigned
    69  	pointer
    70  	boolean
    71  )
    72  
    73  var domainStrings = [...]string{
    74  	"signed", "unsigned", "pointer", "boolean",
    75  }
    76  
    77  func (d domain) String() string {
    78  	s := ""
    79  	for i, ds := range domainStrings {
    80  		if d&(1<<uint(i)) != 0 {
    81  			if len(s) != 0 {
    82  				s += "|"
    83  			}
    84  			s += ds
    85  			d &^= 1 << uint(i)
    86  		}
    87  	}
    88  	if d != 0 {
    89  		if len(s) != 0 {
    90  			s += "|"
    91  		}
    92  		s += fmt.Sprintf("0x%x", uint(d))
    93  	}
    94  	return s
    95  }
    96  
    97  type pair struct {
    98  	v, w *Value // a pair of values, ordered by ID.
    99  	// v can be nil, to mean the zero value.
   100  	// for booleans the zero value (v == nil) is false.
   101  	d domain
   102  }
   103  
   104  // fact is a pair plus a relation for that pair.
   105  type fact struct {
   106  	p pair
   107  	r relation
   108  }
   109  
   110  // a limit records known upper and lower bounds for a value.
   111  type limit struct {
   112  	min, max   int64  // min <= value <= max, signed
   113  	umin, umax uint64 // umin <= value <= umax, unsigned
   114  }
   115  
   116  func (l limit) String() string {
   117  	return fmt.Sprintf("sm,SM,um,UM=%d,%d,%d,%d", l.min, l.max, l.umin, l.umax)
   118  }
   119  
   120  func (l limit) intersect(l2 limit) limit {
   121  	if l.min < l2.min {
   122  		l.min = l2.min
   123  	}
   124  	if l.umin < l2.umin {
   125  		l.umin = l2.umin
   126  	}
   127  	if l.max > l2.max {
   128  		l.max = l2.max
   129  	}
   130  	if l.umax > l2.umax {
   131  		l.umax = l2.umax
   132  	}
   133  	return l
   134  }
   135  
   136  var noLimit = limit{math.MinInt64, math.MaxInt64, 0, math.MaxUint64}
   137  
   138  // a limitFact is a limit known for a particular value.
   139  type limitFact struct {
   140  	vid   ID
   141  	limit limit
   142  }
   143  
   144  // factsTable keeps track of relations between pairs of values.
   145  //
   146  // The fact table logic is sound, but incomplete. Outside of a few
   147  // special cases, it performs no deduction or arithmetic. While there
   148  // are known decision procedures for this, the ad hoc approach taken
   149  // by the facts table is effective for real code while remaining very
   150  // efficient.
   151  type factsTable struct {
   152  	// unsat is true if facts contains a contradiction.
   153  	//
   154  	// Note that the factsTable logic is incomplete, so if unsat
   155  	// is false, the assertions in factsTable could be satisfiable
   156  	// *or* unsatisfiable.
   157  	unsat      bool // true if facts contains a contradiction
   158  	unsatDepth int  // number of unsat checkpoints
   159  
   160  	facts map[pair]relation // current known set of relation
   161  	stack []fact            // previous sets of relations
   162  
   163  	// order is a couple of partial order sets that record information
   164  	// about relations between SSA values in the signed and unsigned
   165  	// domain.
   166  	order [2]*poset
   167  
   168  	// known lower and upper bounds on individual values.
   169  	limits     map[ID]limit
   170  	limitStack []limitFact // previous entries
   171  
   172  	// For each slice s, a map from s to a len(s)/cap(s) value (if any)
   173  	// TODO: check if there are cases that matter where we have
   174  	// more than one len(s) for a slice. We could keep a list if necessary.
   175  	lens map[ID]*Value
   176  	caps map[ID]*Value
   177  }
   178  
   179  // checkpointFact is an invalid value used for checkpointing
   180  // and restoring factsTable.
   181  var checkpointFact = fact{}
   182  var checkpointBound = limitFact{}
   183  
   184  func newFactsTable(f *Func) *factsTable {
   185  	ft := &factsTable{}
   186  	ft.order[0] = f.newPoset() // signed
   187  	ft.order[1] = f.newPoset() // unsigned
   188  	ft.order[0].SetUnsigned(false)
   189  	ft.order[1].SetUnsigned(true)
   190  	ft.facts = make(map[pair]relation)
   191  	ft.stack = make([]fact, 4)
   192  	ft.limits = make(map[ID]limit)
   193  	ft.limitStack = make([]limitFact, 4)
   194  	return ft
   195  }
   196  
   197  // update updates the set of relations between v and w in domain d
   198  // restricting it to r.
   199  func (ft *factsTable) update(parent *Block, v, w *Value, d domain, r relation) {
   200  	if parent.Func.pass.debug > 2 {
   201  		parent.Func.Warnl(parent.Pos, "parent=%s, update %s %s %s", parent, v, w, r)
   202  	}
   203  	// No need to do anything else if we already found unsat.
   204  	if ft.unsat {
   205  		return
   206  	}
   207  
   208  	// Self-fact. It's wasteful to register it into the facts
   209  	// table, so just note whether it's satisfiable
   210  	if v == w {
   211  		if r&eq == 0 {
   212  			ft.unsat = true
   213  		}
   214  		return
   215  	}
   216  
   217  	if d == signed || d == unsigned {
   218  		var ok bool
   219  		idx := 0
   220  		if d == unsigned {
   221  			idx = 1
   222  		}
   223  		switch r {
   224  		case lt:
   225  			ok = ft.order[idx].SetOrder(v, w)
   226  		case gt:
   227  			ok = ft.order[idx].SetOrder(w, v)
   228  		case lt | eq:
   229  			ok = ft.order[idx].SetOrderOrEqual(v, w)
   230  		case gt | eq:
   231  			ok = ft.order[idx].SetOrderOrEqual(w, v)
   232  		case eq:
   233  			ok = ft.order[idx].SetEqual(v, w)
   234  		case lt | gt:
   235  			ok = ft.order[idx].SetNonEqual(v, w)
   236  		default:
   237  			panic("unknown relation")
   238  		}
   239  		if !ok {
   240  			if parent.Func.pass.debug > 2 {
   241  				parent.Func.Warnl(parent.Pos, "unsat %s %s %s", v, w, r)
   242  			}
   243  			ft.unsat = true
   244  			return
   245  		}
   246  	} else {
   247  		if lessByID(w, v) {
   248  			v, w = w, v
   249  			r = reverseBits[r]
   250  		}
   251  
   252  		p := pair{v, w, d}
   253  		oldR, ok := ft.facts[p]
   254  		if !ok {
   255  			if v == w {
   256  				oldR = eq
   257  			} else {
   258  				oldR = lt | eq | gt
   259  			}
   260  		}
   261  		// No changes compared to information already in facts table.
   262  		if oldR == r {
   263  			return
   264  		}
   265  		ft.stack = append(ft.stack, fact{p, oldR})
   266  		ft.facts[p] = oldR & r
   267  		// If this relation is not satisfiable, mark it and exit right away
   268  		if oldR&r == 0 {
   269  			if parent.Func.pass.debug > 2 {
   270  				parent.Func.Warnl(parent.Pos, "unsat %s %s %s", v, w, r)
   271  			}
   272  			ft.unsat = true
   273  			return
   274  		}
   275  	}
   276  
   277  	// Extract bounds when comparing against constants
   278  	if v.isGenericIntConst() {
   279  		v, w = w, v
   280  		r = reverseBits[r]
   281  	}
   282  	if v != nil && w.isGenericIntConst() {
   283  		// Note: all the +1/-1 below could overflow/underflow. Either will
   284  		// still generate correct results, it will just lead to imprecision.
   285  		// In fact if there is overflow/underflow, the corresponding
   286  		// code is unreachable because the known range is outside the range
   287  		// of the value's type.
   288  		old, ok := ft.limits[v.ID]
   289  		if !ok {
   290  			old = noLimit
   291  			if v.isGenericIntConst() {
   292  				switch d {
   293  				case signed:
   294  					old.min, old.max = v.AuxInt, v.AuxInt
   295  					if v.AuxInt >= 0 {
   296  						old.umin, old.umax = uint64(v.AuxInt), uint64(v.AuxInt)
   297  					}
   298  				case unsigned:
   299  					old.umin = v.AuxUnsigned()
   300  					old.umax = old.umin
   301  					if int64(old.umin) >= 0 {
   302  						old.min, old.max = int64(old.umin), int64(old.umin)
   303  					}
   304  				}
   305  			}
   306  		}
   307  		lim := noLimit
   308  		switch d {
   309  		case signed:
   310  			c := w.AuxInt
   311  			switch r {
   312  			case lt:
   313  				lim.max = c - 1
   314  			case lt | eq:
   315  				lim.max = c
   316  			case gt | eq:
   317  				lim.min = c
   318  			case gt:
   319  				lim.min = c + 1
   320  			case lt | gt:
   321  				lim = old
   322  				if c == lim.min {
   323  					lim.min++
   324  				}
   325  				if c == lim.max {
   326  					lim.max--
   327  				}
   328  			case eq:
   329  				lim.min = c
   330  				lim.max = c
   331  			}
   332  			if lim.min >= 0 {
   333  				// int(x) >= 0 && int(x) >= N  ⇒  uint(x) >= N
   334  				lim.umin = uint64(lim.min)
   335  			}
   336  			if lim.max != noLimit.max && old.min >= 0 && lim.max >= 0 {
   337  				// 0 <= int(x) <= N  ⇒  0 <= uint(x) <= N
   338  				// This is for a max update, so the lower bound
   339  				// comes from what we already know (old).
   340  				lim.umax = uint64(lim.max)
   341  			}
   342  		case unsigned:
   343  			uc := w.AuxUnsigned()
   344  			switch r {
   345  			case lt:
   346  				lim.umax = uc - 1
   347  			case lt | eq:
   348  				lim.umax = uc
   349  			case gt | eq:
   350  				lim.umin = uc
   351  			case gt:
   352  				lim.umin = uc + 1
   353  			case lt | gt:
   354  				lim = old
   355  				if uc == lim.umin {
   356  					lim.umin++
   357  				}
   358  				if uc == lim.umax {
   359  					lim.umax--
   360  				}
   361  			case eq:
   362  				lim.umin = uc
   363  				lim.umax = uc
   364  			}
   365  			// We could use the contrapositives of the
   366  			// signed implications to derive signed facts,
   367  			// but it turns out not to matter.
   368  		}
   369  		ft.limitStack = append(ft.limitStack, limitFact{v.ID, old})
   370  		lim = old.intersect(lim)
   371  		ft.limits[v.ID] = lim
   372  		if v.Block.Func.pass.debug > 2 {
   373  			v.Block.Func.Warnl(parent.Pos, "parent=%s, new limits %s %s %s %s", parent, v, w, r, lim.String())
   374  		}
   375  		if lim.min > lim.max || lim.umin > lim.umax {
   376  			ft.unsat = true
   377  			return
   378  		}
   379  	}
   380  
   381  	// Derived facts below here are only about numbers.
   382  	if d != signed && d != unsigned {
   383  		return
   384  	}
   385  
   386  	// Additional facts we know given the relationship between len and cap.
   387  	//
   388  	// TODO: Since prove now derives transitive relations, it
   389  	// should be sufficient to learn that len(w) <= cap(w) at the
   390  	// beginning of prove where we look for all len/cap ops.
   391  	if v.Op == OpSliceLen && r&lt == 0 && ft.caps[v.Args[0].ID] != nil {
   392  		// len(s) > w implies cap(s) > w
   393  		// len(s) >= w implies cap(s) >= w
   394  		// len(s) == w implies cap(s) >= w
   395  		ft.update(parent, ft.caps[v.Args[0].ID], w, d, r|gt)
   396  	}
   397  	if w.Op == OpSliceLen && r&gt == 0 && ft.caps[w.Args[0].ID] != nil {
   398  		// same, length on the RHS.
   399  		ft.update(parent, v, ft.caps[w.Args[0].ID], d, r|lt)
   400  	}
   401  	if v.Op == OpSliceCap && r&gt == 0 && ft.lens[v.Args[0].ID] != nil {
   402  		// cap(s) < w implies len(s) < w
   403  		// cap(s) <= w implies len(s) <= w
   404  		// cap(s) == w implies len(s) <= w
   405  		ft.update(parent, ft.lens[v.Args[0].ID], w, d, r|lt)
   406  	}
   407  	if w.Op == OpSliceCap && r&lt == 0 && ft.lens[w.Args[0].ID] != nil {
   408  		// same, capacity on the RHS.
   409  		ft.update(parent, v, ft.lens[w.Args[0].ID], d, r|gt)
   410  	}
   411  
   412  	// Process fence-post implications.
   413  	//
   414  	// First, make the condition > or >=.
   415  	if r == lt || r == lt|eq {
   416  		v, w = w, v
   417  		r = reverseBits[r]
   418  	}
   419  	switch r {
   420  	case gt:
   421  		if x, delta := isConstDelta(v); x != nil && delta == 1 {
   422  			// x+1 > w  ⇒  x >= w
   423  			//
   424  			// This is useful for eliminating the
   425  			// growslice branch of append.
   426  			ft.update(parent, x, w, d, gt|eq)
   427  		} else if x, delta := isConstDelta(w); x != nil && delta == -1 {
   428  			// v > x-1  ⇒  v >= x
   429  			ft.update(parent, v, x, d, gt|eq)
   430  		}
   431  	case gt | eq:
   432  		if x, delta := isConstDelta(v); x != nil && delta == -1 {
   433  			// x-1 >= w && x > min  ⇒  x > w
   434  			//
   435  			// Useful for i > 0; s[i-1].
   436  			lim, ok := ft.limits[x.ID]
   437  			if ok && ((d == signed && lim.min > opMin[v.Op]) || (d == unsigned && lim.umin > 0)) {
   438  				ft.update(parent, x, w, d, gt)
   439  			}
   440  		} else if x, delta := isConstDelta(w); x != nil && delta == 1 {
   441  			// v >= x+1 && x < max  ⇒  v > x
   442  			lim, ok := ft.limits[x.ID]
   443  			if ok && ((d == signed && lim.max < opMax[w.Op]) || (d == unsigned && lim.umax < opUMax[w.Op])) {
   444  				ft.update(parent, v, x, d, gt)
   445  			}
   446  		}
   447  	}
   448  
   449  	// Process: x+delta > w (with delta constant)
   450  	// Only signed domain for now (useful for accesses to slices in loops).
   451  	if r == gt || r == gt|eq {
   452  		if x, delta := isConstDelta(v); x != nil && d == signed {
   453  			if parent.Func.pass.debug > 1 {
   454  				parent.Func.Warnl(parent.Pos, "x+d %s w; x:%v %v delta:%v w:%v d:%v", r, x, parent.String(), delta, w.AuxInt, d)
   455  			}
   456  			if !w.isGenericIntConst() {
   457  				// If we know that x+delta > w but w is not constant, we can derive:
   458  				//    if delta < 0 and x > MinInt - delta, then x > w (because x+delta cannot underflow)
   459  				// This is useful for loops with bounds "len(slice)-K" (delta = -K)
   460  				if l, has := ft.limits[x.ID]; has && delta < 0 {
   461  					if (x.Type.Size() == 8 && l.min >= math.MinInt64-delta) ||
   462  						(x.Type.Size() == 4 && l.min >= math.MinInt32-delta) {
   463  						ft.update(parent, x, w, signed, r)
   464  					}
   465  				}
   466  			} else {
   467  				// With w,delta constants, we want to derive: x+delta > w  ⇒  x > w-delta
   468  				//
   469  				// We compute (using integers of the correct size):
   470  				//    min = w - delta
   471  				//    max = MaxInt - delta
   472  				//
   473  				// And we prove that:
   474  				//    if min<max: min < x AND x <= max
   475  				//    if min>max: min < x OR  x <= max
   476  				//
   477  				// This is always correct, even in case of overflow.
   478  				//
   479  				// If the initial fact is x+delta >= w instead, the derived conditions are:
   480  				//    if min<max: min <= x AND x <= max
   481  				//    if min>max: min <= x OR  x <= max
   482  				//
   483  				// Notice the conditions for max are still <=, as they handle overflows.
   484  				var min, max int64
   485  				var vmin, vmax *Value
   486  				switch x.Type.Size() {
   487  				case 8:
   488  					min = w.AuxInt - delta
   489  					max = int64(^uint64(0)>>1) - delta
   490  
   491  					vmin = parent.NewValue0I(parent.Pos, OpConst64, parent.Func.Config.Types.Int64, min)
   492  					vmax = parent.NewValue0I(parent.Pos, OpConst64, parent.Func.Config.Types.Int64, max)
   493  
   494  				case 4:
   495  					min = int64(int32(w.AuxInt) - int32(delta))
   496  					max = int64(int32(^uint32(0)>>1) - int32(delta))
   497  
   498  					vmin = parent.NewValue0I(parent.Pos, OpConst32, parent.Func.Config.Types.Int32, min)
   499  					vmax = parent.NewValue0I(parent.Pos, OpConst32, parent.Func.Config.Types.Int32, max)
   500  
   501  				default:
   502  					panic("unimplemented")
   503  				}
   504  
   505  				if min < max {
   506  					// Record that x > min and max >= x
   507  					ft.update(parent, x, vmin, d, r)
   508  					ft.update(parent, vmax, x, d, r|eq)
   509  				} else {
   510  					// We know that either x>min OR x<=max. factsTable cannot record OR conditions,
   511  					// so let's see if we can already prove that one of them is false, in which case
   512  					// the other must be true
   513  					if l, has := ft.limits[x.ID]; has {
   514  						if l.max <= min {
   515  							if r&eq == 0 || l.max < min {
   516  								// x>min (x>=min) is impossible, so it must be x<=max
   517  								ft.update(parent, vmax, x, d, r|eq)
   518  							}
   519  						} else if l.min > max {
   520  							// x<=max is impossible, so it must be x>min
   521  							ft.update(parent, x, vmin, d, r)
   522  						}
   523  					}
   524  				}
   525  			}
   526  		}
   527  	}
   528  
   529  }
   530  
   531  var opMin = map[Op]int64{
   532  	OpAdd64: math.MinInt64, OpSub64: math.MinInt64,
   533  	OpAdd32: math.MinInt32, OpSub32: math.MinInt32,
   534  }
   535  
   536  var opMax = map[Op]int64{
   537  	OpAdd64: math.MaxInt64, OpSub64: math.MaxInt64,
   538  	OpAdd32: math.MaxInt32, OpSub32: math.MaxInt32,
   539  }
   540  
   541  var opUMax = map[Op]uint64{
   542  	OpAdd64: math.MaxUint64, OpSub64: math.MaxUint64,
   543  	OpAdd32: math.MaxUint32, OpSub32: math.MaxUint32,
   544  }
   545  
   546  // isNonNegative reports whether v is known to be non-negative.
   547  func (ft *factsTable) isNonNegative(v *Value) bool {
   548  	if isNonNegative(v) {
   549  		return true
   550  	}
   551  
   552  	var max int64
   553  	switch v.Type.Size() {
   554  	case 1:
   555  		max = math.MaxInt8
   556  	case 2:
   557  		max = math.MaxInt16
   558  	case 4:
   559  		max = math.MaxInt32
   560  	case 8:
   561  		max = math.MaxInt64
   562  	default:
   563  		panic("unexpected integer size")
   564  	}
   565  
   566  	// Check if the recorded limits can prove that the value is positive
   567  	if l, has := ft.limits[v.ID]; has && (l.min >= 0 || l.umax <= uint64(max)) {
   568  		return true
   569  	}
   570  
   571  	// Check if v = x+delta, and we can use x's limits to prove that it's positive
   572  	if x, delta := isConstDelta(v); x != nil {
   573  		if l, has := ft.limits[x.ID]; has {
   574  			if delta > 0 && l.min >= -delta && l.max <= max-delta {
   575  				return true
   576  			}
   577  			if delta < 0 && l.min >= -delta {
   578  				return true
   579  			}
   580  		}
   581  	}
   582  
   583  	return false
   584  }
   585  
   586  // checkpoint saves the current state of known relations.
   587  // Called when descending on a branch.
   588  func (ft *factsTable) checkpoint() {
   589  	if ft.unsat {
   590  		ft.unsatDepth++
   591  	}
   592  	ft.stack = append(ft.stack, checkpointFact)
   593  	ft.limitStack = append(ft.limitStack, checkpointBound)
   594  	ft.order[0].Checkpoint()
   595  	ft.order[1].Checkpoint()
   596  }
   597  
   598  // restore restores known relation to the state just
   599  // before the previous checkpoint.
   600  // Called when backing up on a branch.
   601  func (ft *factsTable) restore() {
   602  	if ft.unsatDepth > 0 {
   603  		ft.unsatDepth--
   604  	} else {
   605  		ft.unsat = false
   606  	}
   607  	for {
   608  		old := ft.stack[len(ft.stack)-1]
   609  		ft.stack = ft.stack[:len(ft.stack)-1]
   610  		if old == checkpointFact {
   611  			break
   612  		}
   613  		if old.r == lt|eq|gt {
   614  			delete(ft.facts, old.p)
   615  		} else {
   616  			ft.facts[old.p] = old.r
   617  		}
   618  	}
   619  	for {
   620  		old := ft.limitStack[len(ft.limitStack)-1]
   621  		ft.limitStack = ft.limitStack[:len(ft.limitStack)-1]
   622  		if old.vid == 0 { // checkpointBound
   623  			break
   624  		}
   625  		if old.limit == noLimit {
   626  			delete(ft.limits, old.vid)
   627  		} else {
   628  			ft.limits[old.vid] = old.limit
   629  		}
   630  	}
   631  	ft.order[0].Undo()
   632  	ft.order[1].Undo()
   633  }
   634  
   635  func lessByID(v, w *Value) bool {
   636  	if v == nil && w == nil {
   637  		// Should not happen, but just in case.
   638  		return false
   639  	}
   640  	if v == nil {
   641  		return true
   642  	}
   643  	return w != nil && v.ID < w.ID
   644  }
   645  
   646  var (
   647  	reverseBits = [...]relation{0, 4, 2, 6, 1, 5, 3, 7}
   648  
   649  	// maps what we learn when the positive branch is taken.
   650  	// For example:
   651  	//      OpLess8:   {signed, lt},
   652  	//	v1 = (OpLess8 v2 v3).
   653  	// If v1 branch is taken then we learn that the rangeMask
   654  	// can be at most lt.
   655  	domainRelationTable = map[Op]struct {
   656  		d domain
   657  		r relation
   658  	}{
   659  		OpEq8:   {signed | unsigned, eq},
   660  		OpEq16:  {signed | unsigned, eq},
   661  		OpEq32:  {signed | unsigned, eq},
   662  		OpEq64:  {signed | unsigned, eq},
   663  		OpEqPtr: {pointer, eq},
   664  
   665  		OpNeq8:   {signed | unsigned, lt | gt},
   666  		OpNeq16:  {signed | unsigned, lt | gt},
   667  		OpNeq32:  {signed | unsigned, lt | gt},
   668  		OpNeq64:  {signed | unsigned, lt | gt},
   669  		OpNeqPtr: {pointer, lt | gt},
   670  
   671  		OpLess8:   {signed, lt},
   672  		OpLess8U:  {unsigned, lt},
   673  		OpLess16:  {signed, lt},
   674  		OpLess16U: {unsigned, lt},
   675  		OpLess32:  {signed, lt},
   676  		OpLess32U: {unsigned, lt},
   677  		OpLess64:  {signed, lt},
   678  		OpLess64U: {unsigned, lt},
   679  
   680  		OpLeq8:   {signed, lt | eq},
   681  		OpLeq8U:  {unsigned, lt | eq},
   682  		OpLeq16:  {signed, lt | eq},
   683  		OpLeq16U: {unsigned, lt | eq},
   684  		OpLeq32:  {signed, lt | eq},
   685  		OpLeq32U: {unsigned, lt | eq},
   686  		OpLeq64:  {signed, lt | eq},
   687  		OpLeq64U: {unsigned, lt | eq},
   688  
   689  		OpGeq8:   {signed, eq | gt},
   690  		OpGeq8U:  {unsigned, eq | gt},
   691  		OpGeq16:  {signed, eq | gt},
   692  		OpGeq16U: {unsigned, eq | gt},
   693  		OpGeq32:  {signed, eq | gt},
   694  		OpGeq32U: {unsigned, eq | gt},
   695  		OpGeq64:  {signed, eq | gt},
   696  		OpGeq64U: {unsigned, eq | gt},
   697  
   698  		OpGreater8:   {signed, gt},
   699  		OpGreater8U:  {unsigned, gt},
   700  		OpGreater16:  {signed, gt},
   701  		OpGreater16U: {unsigned, gt},
   702  		OpGreater32:  {signed, gt},
   703  		OpGreater32U: {unsigned, gt},
   704  		OpGreater64:  {signed, gt},
   705  		OpGreater64U: {unsigned, gt},
   706  
   707  		// For these ops, the negative branch is different: we can only
   708  		// prove signed/GE (signed/GT) if we can prove that arg0 is non-negative.
   709  		// See the special case in addBranchRestrictions.
   710  		OpIsInBounds:      {signed | unsigned, lt},      // 0 <= arg0 < arg1
   711  		OpIsSliceInBounds: {signed | unsigned, lt | eq}, // 0 <= arg0 <= arg1
   712  	}
   713  )
   714  
   715  // prove removes redundant BlockIf branches that can be inferred
   716  // from previous dominating comparisons.
   717  //
   718  // By far, the most common redundant pair are generated by bounds checking.
   719  // For example for the code:
   720  //
   721  //    a[i] = 4
   722  //    foo(a[i])
   723  //
   724  // The compiler will generate the following code:
   725  //
   726  //    if i >= len(a) {
   727  //        panic("not in bounds")
   728  //    }
   729  //    a[i] = 4
   730  //    if i >= len(a) {
   731  //        panic("not in bounds")
   732  //    }
   733  //    foo(a[i])
   734  //
   735  // The second comparison i >= len(a) is clearly redundant because if the
   736  // else branch of the first comparison is executed, we already know that i < len(a).
   737  // The code for the second panic can be removed.
   738  //
   739  // prove works by finding contradictions and trimming branches whose
   740  // conditions are unsatisfiable given the branches leading up to them.
   741  // It tracks a "fact table" of branch conditions. For each branching
   742  // block, it asserts the branch conditions that uniquely dominate that
   743  // block, and then separately asserts the block's branch condition and
   744  // its negation. If either leads to a contradiction, it can trim that
   745  // successor.
   746  func prove(f *Func) {
   747  	ft := newFactsTable(f)
   748  	ft.checkpoint()
   749  
   750  	// Find length and capacity ops.
   751  	var zero *Value
   752  	for _, b := range f.Blocks {
   753  		for _, v := range b.Values {
   754  			// If we found a zero constant, save it (so we don't have
   755  			// to build one later).
   756  			if zero == nil && v.Op == OpConst64 && v.AuxInt == 0 {
   757  				zero = v
   758  			}
   759  			if v.Uses == 0 {
   760  				// We don't care about dead values.
   761  				// (There can be some that are CSEd but not removed yet.)
   762  				continue
   763  			}
   764  			switch v.Op {
   765  			case OpStringLen:
   766  				if zero == nil {
   767  					zero = b.NewValue0I(b.Pos, OpConst64, f.Config.Types.Int64, 0)
   768  				}
   769  				ft.update(b, v, zero, signed, gt|eq)
   770  			case OpSliceLen:
   771  				if ft.lens == nil {
   772  					ft.lens = map[ID]*Value{}
   773  				}
   774  				ft.lens[v.Args[0].ID] = v
   775  				if zero == nil {
   776  					zero = b.NewValue0I(b.Pos, OpConst64, f.Config.Types.Int64, 0)
   777  				}
   778  				ft.update(b, v, zero, signed, gt|eq)
   779  			case OpSliceCap:
   780  				if ft.caps == nil {
   781  					ft.caps = map[ID]*Value{}
   782  				}
   783  				ft.caps[v.Args[0].ID] = v
   784  				if zero == nil {
   785  					zero = b.NewValue0I(b.Pos, OpConst64, f.Config.Types.Int64, 0)
   786  				}
   787  				ft.update(b, v, zero, signed, gt|eq)
   788  			}
   789  		}
   790  	}
   791  
   792  	// Find induction variables. Currently, findIndVars
   793  	// is limited to one induction variable per block.
   794  	var indVars map[*Block]indVar
   795  	for _, v := range findIndVar(f) {
   796  		if indVars == nil {
   797  			indVars = make(map[*Block]indVar)
   798  		}
   799  		indVars[v.entry] = v
   800  	}
   801  
   802  	// current node state
   803  	type walkState int
   804  	const (
   805  		descend walkState = iota
   806  		simplify
   807  	)
   808  	// work maintains the DFS stack.
   809  	type bp struct {
   810  		block *Block    // current handled block
   811  		state walkState // what's to do
   812  	}
   813  	work := make([]bp, 0, 256)
   814  	work = append(work, bp{
   815  		block: f.Entry,
   816  		state: descend,
   817  	})
   818  
   819  	idom := f.Idom()
   820  	sdom := f.sdom()
   821  
   822  	// DFS on the dominator tree.
   823  	//
   824  	// For efficiency, we consider only the dominator tree rather
   825  	// than the entire flow graph. On the way down, we consider
   826  	// incoming branches and accumulate conditions that uniquely
   827  	// dominate the current block. If we discover a contradiction,
   828  	// we can eliminate the entire block and all of its children.
   829  	// On the way back up, we consider outgoing branches that
   830  	// haven't already been considered. This way we consider each
   831  	// branch condition only once.
   832  	for len(work) > 0 {
   833  		node := work[len(work)-1]
   834  		work = work[:len(work)-1]
   835  		parent := idom[node.block.ID]
   836  		branch := getBranch(sdom, parent, node.block)
   837  
   838  		switch node.state {
   839  		case descend:
   840  			ft.checkpoint()
   841  			if iv, ok := indVars[node.block]; ok {
   842  				addIndVarRestrictions(ft, parent, iv)
   843  			}
   844  
   845  			if branch != unknown {
   846  				addBranchRestrictions(ft, parent, branch)
   847  				if ft.unsat {
   848  					// node.block is unreachable.
   849  					// Remove it and don't visit
   850  					// its children.
   851  					removeBranch(parent, branch)
   852  					ft.restore()
   853  					break
   854  				}
   855  				// Otherwise, we can now commit to
   856  				// taking this branch. We'll restore
   857  				// ft when we unwind.
   858  			}
   859  
   860  			// Add inductive facts for phis in this block.
   861  			addLocalInductiveFacts(ft, node.block)
   862  
   863  			work = append(work, bp{
   864  				block: node.block,
   865  				state: simplify,
   866  			})
   867  			for s := sdom.Child(node.block); s != nil; s = sdom.Sibling(s) {
   868  				work = append(work, bp{
   869  					block: s,
   870  					state: descend,
   871  				})
   872  			}
   873  
   874  		case simplify:
   875  			simplifyBlock(sdom, ft, node.block)
   876  			ft.restore()
   877  		}
   878  	}
   879  
   880  	ft.restore()
   881  
   882  	// Return the posets to the free list
   883  	for _, po := range ft.order {
   884  		// Make sure it's empty as it should be. A non-empty poset
   885  		// might cause errors and miscompilations if reused.
   886  		if checkEnabled {
   887  			if err := po.CheckEmpty(); err != nil {
   888  				f.Fatalf("prove poset not empty after function %s: %v", f.Name, err)
   889  			}
   890  		}
   891  		f.retPoset(po)
   892  	}
   893  }
   894  
   895  // getBranch returns the range restrictions added by p
   896  // when reaching b. p is the immediate dominator of b.
   897  func getBranch(sdom SparseTree, p *Block, b *Block) branch {
   898  	if p == nil || p.Kind != BlockIf {
   899  		return unknown
   900  	}
   901  	// If p and p.Succs[0] are dominators it means that every path
   902  	// from entry to b passes through p and p.Succs[0]. We care that
   903  	// no path from entry to b passes through p.Succs[1]. If p.Succs[0]
   904  	// has one predecessor then (apart from the degenerate case),
   905  	// there is no path from entry that can reach b through p.Succs[1].
   906  	// TODO: how about p->yes->b->yes, i.e. a loop in yes.
   907  	if sdom.isAncestorEq(p.Succs[0].b, b) && len(p.Succs[0].b.Preds) == 1 {
   908  		return positive
   909  	}
   910  	if sdom.isAncestorEq(p.Succs[1].b, b) && len(p.Succs[1].b.Preds) == 1 {
   911  		return negative
   912  	}
   913  	return unknown
   914  }
   915  
   916  // addIndVarRestrictions updates the factsTables ft with the facts
   917  // learned from the induction variable indVar which drives the loop
   918  // starting in Block b.
   919  func addIndVarRestrictions(ft *factsTable, b *Block, iv indVar) {
   920  	d := signed
   921  	if isNonNegative(iv.min) && isNonNegative(iv.max) {
   922  		d |= unsigned
   923  	}
   924  
   925  	if iv.flags&indVarMinExc == 0 {
   926  		addRestrictions(b, ft, d, iv.min, iv.ind, lt|eq)
   927  	} else {
   928  		addRestrictions(b, ft, d, iv.min, iv.ind, lt)
   929  	}
   930  
   931  	if iv.flags&indVarMaxInc == 0 {
   932  		addRestrictions(b, ft, d, iv.ind, iv.max, lt)
   933  	} else {
   934  		addRestrictions(b, ft, d, iv.ind, iv.max, lt|eq)
   935  	}
   936  }
   937  
   938  // addBranchRestrictions updates the factsTables ft with the facts learned when
   939  // branching from Block b in direction br.
   940  func addBranchRestrictions(ft *factsTable, b *Block, br branch) {
   941  	c := b.Control
   942  	switch br {
   943  	case negative:
   944  		addRestrictions(b, ft, boolean, nil, c, eq)
   945  	case positive:
   946  		addRestrictions(b, ft, boolean, nil, c, lt|gt)
   947  	default:
   948  		panic("unknown branch")
   949  	}
   950  	if tr, has := domainRelationTable[b.Control.Op]; has {
   951  		// When we branched from parent we learned a new set of
   952  		// restrictions. Update the factsTable accordingly.
   953  		d := tr.d
   954  		if d == signed && ft.isNonNegative(c.Args[0]) && ft.isNonNegative(c.Args[1]) {
   955  			d |= unsigned
   956  		}
   957  		switch br {
   958  		case negative:
   959  			switch b.Control.Op { // Special cases
   960  			case OpIsInBounds, OpIsSliceInBounds:
   961  				// 0 <= a0 < a1 (or 0 <= a0 <= a1)
   962  				//
   963  				// On the positive branch, we learn a0 < a1,
   964  				// both signed and unsigned.
   965  				//
   966  				// On the negative branch, we learn (0 > a0 ||
   967  				// a0 >= a1). In the unsigned domain, this is
   968  				// simply a0 >= a1 (which is the reverse of the
   969  				// positive branch, so nothing surprising).
   970  				// But in the signed domain, we can't express the ||
   971  				// condition, so check if a0 is non-negative instead,
   972  				// to be able to learn something.
   973  				d = unsigned
   974  				if ft.isNonNegative(c.Args[0]) {
   975  					d |= signed
   976  				}
   977  			}
   978  			addRestrictions(b, ft, d, c.Args[0], c.Args[1], tr.r^(lt|gt|eq))
   979  		case positive:
   980  			addRestrictions(b, ft, d, c.Args[0], c.Args[1], tr.r)
   981  		}
   982  	}
   983  }
   984  
   985  // addRestrictions updates restrictions from the immediate
   986  // dominating block (p) using r.
   987  func addRestrictions(parent *Block, ft *factsTable, t domain, v, w *Value, r relation) {
   988  	if t == 0 {
   989  		// Trivial case: nothing to do.
   990  		// Shoult not happen, but just in case.
   991  		return
   992  	}
   993  	for i := domain(1); i <= t; i <<= 1 {
   994  		if t&i == 0 {
   995  			continue
   996  		}
   997  		ft.update(parent, v, w, i, r)
   998  	}
   999  }
  1000  
  1001  // addLocalInductiveFacts adds inductive facts when visiting b, where
  1002  // b is a join point in a loop. In contrast with findIndVar, this
  1003  // depends on facts established for b, which is why it happens when
  1004  // visiting b. addLocalInductiveFacts specifically targets the pattern
  1005  // created by OFORUNTIL, which isn't detected by findIndVar.
  1006  //
  1007  // TODO: It would be nice to combine this with findIndVar.
  1008  func addLocalInductiveFacts(ft *factsTable, b *Block) {
  1009  	// This looks for a specific pattern of induction:
  1010  	//
  1011  	// 1. i1 = OpPhi(min, i2) in b
  1012  	// 2. i2 = i1 + 1
  1013  	// 3. i2 < max at exit from b.Preds[1]
  1014  	// 4. min < max
  1015  	//
  1016  	// If all of these conditions are true, then i1 < max and i1 >= min.
  1017  
  1018  	for _, i1 := range b.Values {
  1019  		if i1.Op != OpPhi {
  1020  			continue
  1021  		}
  1022  
  1023  		// Check for conditions 1 and 2. This is easy to do
  1024  		// and will throw out most phis.
  1025  		min, i2 := i1.Args[0], i1.Args[1]
  1026  		if i1q, delta := isConstDelta(i2); i1q != i1 || delta != 1 {
  1027  			continue
  1028  		}
  1029  
  1030  		// Try to prove condition 3. We can't just query the
  1031  		// fact table for this because we don't know what the
  1032  		// facts of b.Preds[1] are (in general, b.Preds[1] is
  1033  		// a loop-back edge, so we haven't even been there
  1034  		// yet). As a conservative approximation, we look for
  1035  		// this condition in the predecessor chain until we
  1036  		// hit a join point.
  1037  		uniquePred := func(b *Block) *Block {
  1038  			if len(b.Preds) == 1 {
  1039  				return b.Preds[0].b
  1040  			}
  1041  			return nil
  1042  		}
  1043  		pred, child := b.Preds[1].b, b
  1044  		for ; pred != nil; pred = uniquePred(pred) {
  1045  			if pred.Kind != BlockIf {
  1046  				continue
  1047  			}
  1048  
  1049  			br := unknown
  1050  			if pred.Succs[0].b == child {
  1051  				br = positive
  1052  			}
  1053  			if pred.Succs[1].b == child {
  1054  				if br != unknown {
  1055  					continue
  1056  				}
  1057  				br = negative
  1058  			}
  1059  
  1060  			tr, has := domainRelationTable[pred.Control.Op]
  1061  			if !has {
  1062  				continue
  1063  			}
  1064  			r := tr.r
  1065  			if br == negative {
  1066  				// Negative branch taken to reach b.
  1067  				// Complement the relations.
  1068  				r = (lt | eq | gt) ^ r
  1069  			}
  1070  
  1071  			// Check for i2 < max or max > i2.
  1072  			var max *Value
  1073  			if r == lt && pred.Control.Args[0] == i2 {
  1074  				max = pred.Control.Args[1]
  1075  			} else if r == gt && pred.Control.Args[1] == i2 {
  1076  				max = pred.Control.Args[0]
  1077  			} else {
  1078  				continue
  1079  			}
  1080  
  1081  			// Check condition 4 now that we have a
  1082  			// candidate max. For this we can query the
  1083  			// fact table. We "prove" min < max by showing
  1084  			// that min >= max is unsat. (This may simply
  1085  			// compare two constants; that's fine.)
  1086  			ft.checkpoint()
  1087  			ft.update(b, min, max, tr.d, gt|eq)
  1088  			proved := ft.unsat
  1089  			ft.restore()
  1090  
  1091  			if proved {
  1092  				// We know that min <= i1 < max.
  1093  				if b.Func.pass.debug > 0 {
  1094  					printIndVar(b, i1, min, max, 1, 0)
  1095  				}
  1096  				ft.update(b, min, i1, tr.d, lt|eq)
  1097  				ft.update(b, i1, max, tr.d, lt)
  1098  			}
  1099  		}
  1100  	}
  1101  }
  1102  
  1103  var ctzNonZeroOp = map[Op]Op{OpCtz8: OpCtz8NonZero, OpCtz16: OpCtz16NonZero, OpCtz32: OpCtz32NonZero, OpCtz64: OpCtz64NonZero}
  1104  var mostNegativeDividend = map[Op]int64{
  1105  	OpDiv16: -1 << 15,
  1106  	OpMod16: -1 << 15,
  1107  	OpDiv32: -1 << 31,
  1108  	OpMod32: -1 << 31,
  1109  	OpDiv64: -1 << 63,
  1110  	OpMod64: -1 << 63}
  1111  
  1112  // simplifyBlock simplifies some constant values in b and evaluates
  1113  // branches to non-uniquely dominated successors of b.
  1114  func simplifyBlock(sdom SparseTree, ft *factsTable, b *Block) {
  1115  	for _, v := range b.Values {
  1116  		switch v.Op {
  1117  		case OpSlicemask:
  1118  			// Replace OpSlicemask operations in b with constants where possible.
  1119  			x, delta := isConstDelta(v.Args[0])
  1120  			if x == nil {
  1121  				continue
  1122  			}
  1123  			// slicemask(x + y)
  1124  			// if x is larger than -y (y is negative), then slicemask is -1.
  1125  			lim, ok := ft.limits[x.ID]
  1126  			if !ok {
  1127  				continue
  1128  			}
  1129  			if lim.umin > uint64(-delta) {
  1130  				if v.Args[0].Op == OpAdd64 {
  1131  					v.reset(OpConst64)
  1132  				} else {
  1133  					v.reset(OpConst32)
  1134  				}
  1135  				if b.Func.pass.debug > 0 {
  1136  					b.Func.Warnl(v.Pos, "Proved slicemask not needed")
  1137  				}
  1138  				v.AuxInt = -1
  1139  			}
  1140  		case OpCtz8, OpCtz16, OpCtz32, OpCtz64:
  1141  			// On some architectures, notably amd64, we can generate much better
  1142  			// code for CtzNN if we know that the argument is non-zero.
  1143  			// Capture that information here for use in arch-specific optimizations.
  1144  			x := v.Args[0]
  1145  			lim, ok := ft.limits[x.ID]
  1146  			if !ok {
  1147  				continue
  1148  			}
  1149  			if lim.umin > 0 || lim.min > 0 || lim.max < 0 {
  1150  				if b.Func.pass.debug > 0 {
  1151  					b.Func.Warnl(v.Pos, "Proved %v non-zero", v.Op)
  1152  				}
  1153  				v.Op = ctzNonZeroOp[v.Op]
  1154  			}
  1155  
  1156  		case OpLsh8x8, OpLsh8x16, OpLsh8x32, OpLsh8x64,
  1157  			OpLsh16x8, OpLsh16x16, OpLsh16x32, OpLsh16x64,
  1158  			OpLsh32x8, OpLsh32x16, OpLsh32x32, OpLsh32x64,
  1159  			OpLsh64x8, OpLsh64x16, OpLsh64x32, OpLsh64x64,
  1160  			OpRsh8x8, OpRsh8x16, OpRsh8x32, OpRsh8x64,
  1161  			OpRsh16x8, OpRsh16x16, OpRsh16x32, OpRsh16x64,
  1162  			OpRsh32x8, OpRsh32x16, OpRsh32x32, OpRsh32x64,
  1163  			OpRsh64x8, OpRsh64x16, OpRsh64x32, OpRsh64x64,
  1164  			OpRsh8Ux8, OpRsh8Ux16, OpRsh8Ux32, OpRsh8Ux64,
  1165  			OpRsh16Ux8, OpRsh16Ux16, OpRsh16Ux32, OpRsh16Ux64,
  1166  			OpRsh32Ux8, OpRsh32Ux16, OpRsh32Ux32, OpRsh32Ux64,
  1167  			OpRsh64Ux8, OpRsh64Ux16, OpRsh64Ux32, OpRsh64Ux64:
  1168  			// Check whether, for a << b, we know that b
  1169  			// is strictly less than the number of bits in a.
  1170  			by := v.Args[1]
  1171  			lim, ok := ft.limits[by.ID]
  1172  			if !ok {
  1173  				continue
  1174  			}
  1175  			bits := 8 * v.Args[0].Type.Size()
  1176  			if lim.umax < uint64(bits) || (lim.max < bits && ft.isNonNegative(by)) {
  1177  				v.AuxInt = 1 // see shiftIsBounded
  1178  				if b.Func.pass.debug > 0 {
  1179  					b.Func.Warnl(v.Pos, "Proved %v bounded", v.Op)
  1180  				}
  1181  			}
  1182  		case OpDiv16, OpDiv32, OpDiv64, OpMod16, OpMod32, OpMod64:
  1183  			// On amd64 and 386 fix-up code can be avoided if we know
  1184  			//  the divisor is not -1 or the dividend > MinIntNN.
  1185  			divr := v.Args[1]
  1186  			divrLim, divrLimok := ft.limits[divr.ID]
  1187  			divd := v.Args[0]
  1188  			divdLim, divdLimok := ft.limits[divd.ID]
  1189  			if (divrLimok && (divrLim.max < -1 || divrLim.min > -1)) ||
  1190  				(divdLimok && divdLim.min > mostNegativeDividend[v.Op]) {
  1191  				v.AuxInt = 1 // see NeedsFixUp in genericOps - v.AuxInt = 0 means we have not proved
  1192  				// that the divisor is not -1 and the dividend is not the most negative,
  1193  				// so we need to add fix-up code.
  1194  				if b.Func.pass.debug > 0 {
  1195  					b.Func.Warnl(v.Pos, "Proved %v does not need fix-up", v.Op)
  1196  				}
  1197  			}
  1198  		}
  1199  	}
  1200  
  1201  	if b.Kind != BlockIf {
  1202  		return
  1203  	}
  1204  
  1205  	// Consider outgoing edges from this block.
  1206  	parent := b
  1207  	for i, branch := range [...]branch{positive, negative} {
  1208  		child := parent.Succs[i].b
  1209  		if getBranch(sdom, parent, child) != unknown {
  1210  			// For edges to uniquely dominated blocks, we
  1211  			// already did this when we visited the child.
  1212  			continue
  1213  		}
  1214  		// For edges to other blocks, this can trim a branch
  1215  		// even if we couldn't get rid of the child itself.
  1216  		ft.checkpoint()
  1217  		addBranchRestrictions(ft, parent, branch)
  1218  		unsat := ft.unsat
  1219  		ft.restore()
  1220  		if unsat {
  1221  			// This branch is impossible, so remove it
  1222  			// from the block.
  1223  			removeBranch(parent, branch)
  1224  			// No point in considering the other branch.
  1225  			// (It *is* possible for both to be
  1226  			// unsatisfiable since the fact table is
  1227  			// incomplete. We could turn this into a
  1228  			// BlockExit, but it doesn't seem worth it.)
  1229  			break
  1230  		}
  1231  	}
  1232  }
  1233  
  1234  func removeBranch(b *Block, branch branch) {
  1235  	if b.Func.pass.debug > 0 {
  1236  		verb := "Proved"
  1237  		if branch == positive {
  1238  			verb = "Disproved"
  1239  		}
  1240  		c := b.Control
  1241  		if b.Func.pass.debug > 1 {
  1242  			b.Func.Warnl(b.Pos, "%s %s (%s)", verb, c.Op, c)
  1243  		} else {
  1244  			b.Func.Warnl(b.Pos, "%s %s", verb, c.Op)
  1245  		}
  1246  	}
  1247  	b.Kind = BlockFirst
  1248  	b.SetControl(nil)
  1249  	if branch == positive {
  1250  		b.swapSuccessors()
  1251  	}
  1252  }
  1253  
  1254  // isNonNegative reports whether v is known to be greater or equal to zero.
  1255  func isNonNegative(v *Value) bool {
  1256  	switch v.Op {
  1257  	case OpConst64:
  1258  		return v.AuxInt >= 0
  1259  
  1260  	case OpConst32:
  1261  		return int32(v.AuxInt) >= 0
  1262  
  1263  	case OpStringLen, OpSliceLen, OpSliceCap,
  1264  		OpZeroExt8to64, OpZeroExt16to64, OpZeroExt32to64:
  1265  		return true
  1266  
  1267  	case OpRsh64Ux64:
  1268  		by := v.Args[1]
  1269  		return by.Op == OpConst64 && by.AuxInt > 0
  1270  
  1271  	case OpRsh64x64:
  1272  		return isNonNegative(v.Args[0])
  1273  	}
  1274  	return false
  1275  }
  1276  
  1277  // isConstDelta returns non-nil if v is equivalent to w+delta (signed).
  1278  func isConstDelta(v *Value) (w *Value, delta int64) {
  1279  	cop := OpConst64
  1280  	switch v.Op {
  1281  	case OpAdd32, OpSub32:
  1282  		cop = OpConst32
  1283  	}
  1284  	switch v.Op {
  1285  	case OpAdd64, OpAdd32:
  1286  		if v.Args[0].Op == cop {
  1287  			return v.Args[1], v.Args[0].AuxInt
  1288  		}
  1289  		if v.Args[1].Op == cop {
  1290  			return v.Args[0], v.Args[1].AuxInt
  1291  		}
  1292  	case OpSub64, OpSub32:
  1293  		if v.Args[1].Op == cop {
  1294  			aux := v.Args[1].AuxInt
  1295  			if aux != -aux { // Overflow; too bad
  1296  				return v.Args[0], -aux
  1297  			}
  1298  		}
  1299  	}
  1300  	return nil, 0
  1301  }