Source file test/known_bits.go

     1  // errorcheck -0 -d=ssa/known_bits/debug=1
     2  
     3  //go:build amd64 || arm64 || s390x || ppc64le || riscv64
     4  
     5  // Copyright 2026 The Go Authors. All rights reserved.
     6  // Use of this source code is governed by a BSD-style
     7  // license that can be found in the LICENSE file.
     8  
     9  package a
    10  
    11  func knownBitsPhiAnd(cond bool) int {
    12  	x := 1
    13  	if cond {
    14  		x = 3
    15  	}
    16  	return x & 1 // ERROR "known value of v[0-9]+ \(And64\): 1$"
    17  }
    18  
    19  func knownBitsPhiAndGarbage(cond bool, x int) int {
    20  	x &^= 1
    21  	if cond {
    22  		x = 2
    23  	}
    24  	return x & 1 // ERROR "known value of v[0-9]+ \(And64\): 0$"
    25  }
    26  
    27  func unknownBitsPhiAnd(cond bool) int {
    28  	x := 1
    29  	if cond {
    30  		x = 2
    31  	}
    32  	return x & 1
    33  }
    34  
    35  func knownBitsOrGarbage(x, unknown int) int {
    36  	x |= 7
    37  	x |= unknown &^ 3
    38  	return x & 3 // ERROR "known value of v[0-9]+ \(And64\): 3$"
    39  }
    40  
    41  func unknownBitsOrGarbage(x, unknown int) int {
    42  	x |= 1
    43  	x |= unknown
    44  	return x & 3
    45  }
    46  
    47  func knownBitsDeferPattern(a, b bool) int {
    48  	bits := 0
    49  	bits |= 1 << 0
    50  	if a {
    51  		bits |= 1 << 1
    52  	}
    53  	bits |= 1 << 2
    54  	if b {
    55  		bits |= 1 << 3
    56  	}
    57  	return bits & (1<<2 | 1<<0) // ERROR "known value of v[0-9]+ \(And64\): 5$"
    58  }
    59  
    60  func knownBitsDeferPatternGarbage(a, b bool, garbage int) int {
    61  	bits := 0
    62  	bits |= 1 << 0
    63  	if a {
    64  		bits |= 1 << 1
    65  	}
    66  	bits |= 1 << 2
    67  	if b {
    68  		bits |= 1 << 3
    69  	}
    70  	bits ^= garbage &^ (1<<2 | 1<<0)
    71  	return bits & (1<<2 | 1<<0) // ERROR "known value of v[0-9]+ \(And64\): 5$"
    72  }
    73  
    74  func knownBitsXorToggle(a, b, c bool) int {
    75  	bits := 0
    76  	bits ^= 1 << 0
    77  	if a {
    78  		bits ^= 1 << 1
    79  	}
    80  	bits ^= 1 << 2
    81  	if b {
    82  		bits ^= 1 << 3
    83  	}
    84  	bits ^= 1 << 2
    85  	if c {
    86  		bits ^= 1 << 4
    87  	}
    88  	return bits & (1<<2 | 1<<0) // ERROR "known value of v[0-9]+ \(And64\): 1$"
    89  }
    90  
    91  func knownBitsXorToggleGarbage(a, b, c bool, garbage int) int {
    92  	bits := 0
    93  	bits ^= 1 << 0
    94  	if a {
    95  		bits ^= 1 << 1
    96  	}
    97  	bits ^= 1 << 2
    98  	if b {
    99  		bits ^= 1 << 3
   100  	}
   101  	bits ^= 1 << 2
   102  	if c {
   103  		bits ^= 1 << 4
   104  	}
   105  	bits ^= garbage &^ (1<<2 | 1<<0)
   106  	return bits & (1<<2 | 1<<0) // ERROR "known value of v[0-9]+ \(And64\): 1$"
   107  }
   108  
   109  func unknownBitsXorToggle(a, b, c bool) int {
   110  	bits := 0
   111  	bits ^= 1 << 0
   112  	if a {
   113  		bits ^= 1 << 1
   114  	}
   115  	bits ^= 1 << 2
   116  	if b {
   117  		bits ^= 1 << 2
   118  	}
   119  	bits ^= 1 << 2
   120  	if c {
   121  		bits ^= 1 << 4
   122  	}
   123  	return bits & (1<<2 | 1<<0)
   124  }
   125  
   126  func knownBitsPhiComAnd(cond bool) int {
   127  	x := 1
   128  	if cond {
   129  		x = 3
   130  	}
   131  	return ^x & 1 // ERROR "known value of v[0-9]+ \(And64\): 0$"
   132  }
   133  
   134  func knownBitsPhiComAndGarbage(cond bool, garbage int) int {
   135  	x := 1
   136  	if cond {
   137  		x = 3
   138  	}
   139  	x ^= garbage &^ 1
   140  	return ^x & 1 // ERROR "known value of v[0-9]+ \(And64\): 0$"
   141  }
   142  
   143  func unknownBitsPhiComAnd(cond bool) int {
   144  	x := 1
   145  	if cond {
   146  		x = 2
   147  	}
   148  	return ^x & 1
   149  }
   150  
   151  func knownBitsEqFalse(x, y uint64) bool {
   152  	x |= 1
   153  	y &^= 1
   154  	return x == y // ERROR "known value of v[0-9]+ \(Eq64\): false$"
   155  }
   156  
   157  func knownBitsEqTrue(x uint64, cond bool) bool {
   158  	x |= (1<<32 - 1) << 32
   159  	if cond {
   160  		x |= 42
   161  	}
   162  	x |= 1<<32 - 1      // ERROR "known value of v[0-9]+ \(Or64\): -1$"
   163  	return x == 1<<64-1 // ERROR "known value of v[0-9]+ \(Eq64\): true$"
   164  }
   165  
   166  func unknownBitsEq(x, y uint64) bool {
   167  	x |= 1
   168  	return x == y
   169  }
   170  
   171  func knownBitsNeqTrue(x, y uint64) bool {
   172  	x |= 1
   173  	y &^= 1
   174  	return x != y // ERROR "known value of v[0-9]+ \(Neq64\): true$"
   175  }
   176  
   177  func knownBitsNeqFalse(x uint64, cond bool) bool {
   178  	x |= (1<<32 - 1) << 32
   179  	if cond {
   180  		x |= 42
   181  	}
   182  	x |= 1<<32 - 1
   183  	return x != 1<<64-1 // ERROR "known value of v[0-9]+ \(Neq64\): false$"
   184  }
   185  
   186  func unknownBitsNeq(x, y uint64) bool {
   187  	x |= 1
   188  	return x != y
   189  }
   190  
   191  func knownBitsZeroExtPassThrough(x uint8) uint64 {
   192  	x |= 6
   193  	return uint64(x) & 6 // ERROR "known value of v[0-9]+ \(And64\): 6$"
   194  }
   195  
   196  func knownBitsZeroExtUpperHalf(x uint16) uint32 {
   197  	return uint32(x) & 0xFFFF0000 // ERROR "known value of v[0-9]+ \(And32\): 0$"
   198  }
   199  
   200  func unknownBitsZeroExt(x uint16) uint32 {
   201  	x |= 0xAAAA
   202  	return uint32(x) & 0xFFFFF000
   203  }
   204  
   205  func cvtBoolToUint8(cond bool) (r uint8) {
   206  	if cond {
   207  		r = 1
   208  	}
   209  	return r
   210  }
   211  
   212  func knownBitsCvtBoolToUint8False(x, y uint64) uint8 {
   213  	x |= 1
   214  	y &^= 1
   215  	bool := x == y                  // ERROR "known value of v[0-9]+ \(Eq64\): false$"
   216  	return cvtBoolToUint8(bool) & 1 // ERROR "known value of v[0-9]+ \(CvtBoolToUint8\): 0$"
   217  }
   218  
   219  func knownBitsCvtBoolToUint8True(x int64, cond bool) uint8 {
   220  	x |= 6
   221  	if cond {
   222  		x |= 1
   223  		x |= 4
   224  	}
   225  	// I would expect "known value of v[0-9]+ \(And64\): 6$" to be required, but somehow it's not there even tho the AND is being folded.
   226  	// I think it's an issue with the And's LOC meaning known bits prints it without a LOC and errorcheck skips it.
   227  	r := cvtBoolToUint8(x&6 == 6) // ERROR "known value of v[0-9]+ \(Eq64\): true$" "known value of v[0-9]+ \(CvtBoolToUint8\): 1$"
   228  	if cond {
   229  		r |= 4 // ERROR "known value of v[0-9]+ \(Or8\): 5$"
   230  	}
   231  	return r & 3 // ERROR "known value of v[0-9]+ \(And8\): 1$"
   232  }
   233  
   234  func unknownBitsCvtBoolToUint8(cond bool) uint8 {
   235  	return cvtBoolToUint8(cond) & 1
   236  }
   237  
   238  func knownBitsSignExtPassThrough(x int8) int64 {
   239  	x |= 6
   240  	return int64(x) & 6 // ERROR "known value of v[0-9]+ \(And64\): 6$"
   241  }
   242  
   243  func knownBitsSignExtUpperHalf(x int16) int32 {
   244  	x |= -1 << 15
   245  	return int32(x) & (-1 << 16) // ERROR "known value of v[0-9]+ \(And32\): -65536$"
   246  }
   247  
   248  func unknownBitsSignExt(x int16) int32 {
   249  	x |= -0b010101010101010
   250  	return int32(x) & -1 << 12
   251  }
   252  
   253  func knownBitsLsh(x, y uint32) uint32 {
   254  	x |= 0b11110
   255  	x &^= 0b100000
   256  	y &= 2
   257  
   258  	// ???01111?
   259  	// ?01111???
   260  	// ---------
   261  	// ????11???
   262  
   263  	return (x << y) & 0b11000 // ERROR "known value of v[0-9]+ \(And32\): 24$"
   264  }
   265  
   266  func knownBitsLshZero(x, y uint64) uint64 {
   267  	x &^= 2
   268  	y &^= 2
   269  	y |= 128
   270  
   271  	return (x << y) & 8 // ERROR "known value of v[0-9]+ \(And64\): 0$" "known value of v[0-9]+ \(Lsh64x[0-9]+\): 0$"
   272  }
   273  
   274  func unknownBitsLshLeftSideMsb(x uint32, y uint32) uint32 {
   275  	x |= 0b11110
   276  	x &^= 0b100000
   277  	y &= 2
   278  
   279  	return (x << y) & 0b111000
   280  }
   281  
   282  func unknownBitsLshLeftSideLsb(x uint32, y uint32) uint32 {
   283  	x |= 0b11110
   284  	x &^= 0b100000
   285  	y &= 2
   286  
   287  	return (x << y) & 0b011100
   288  }
   289  
   290  func unknownBitsLshRightSide(x uint32, y uint32) uint32 {
   291  	x |= 0b11110
   292  	x &^= 0b100000
   293  	y &= 6
   294  
   295  	return (x << y) & 0b11000
   296  }
   297  
   298  func knownBitsRshU(x, y uint32) uint32 {
   299  	x |= 0b11110
   300  	x &^= 0b100000
   301  	y &= 2
   302  
   303  	// ?01111?
   304  	// ???0111
   305  	// -------
   306  	// ????11?
   307  
   308  	return (x >> y) & 0b110 // ERROR "known value of v[0-9]+ \(And32\): 6$"
   309  }
   310  
   311  func knownBitsRshUZero(x, y uint64) uint64 {
   312  	x &^= 4
   313  	y &^= 2
   314  	y |= 128
   315  
   316  	return (x >> y) & 1 // ERROR "known value of v[0-9]+ \(And64\): 0$" "known value of v[0-9]+ \(Rsh64Ux[0-9]+\): 0$"
   317  }
   318  
   319  func unknownBitsRshULeftSideMsb(x uint32, y uint32) uint32 {
   320  	x |= 0b11110
   321  	x &^= 0b100000
   322  	y &= 2
   323  
   324  	return (x >> y) & 0b1110
   325  }
   326  
   327  func unknownBitsRshULeftSideLsb(x uint32, y uint32) uint32 {
   328  	x |= 0b11110
   329  	x &^= 0b100000
   330  	y &= 2
   331  
   332  	return (x >> y) & 0b111
   333  }
   334  
   335  func unknownBitsRshURightSide(x uint32, y uint32) uint32 {
   336  	x |= 0b11110
   337  	x &^= 0b100000
   338  	y &= 6
   339  
   340  	return (x >> y) & 0b110
   341  }
   342  
   343  func knownBitsRsh(x, y int32) int32 {
   344  	x |= 0b11110
   345  	x &^= 0b100000
   346  	y &= 2
   347  
   348  	// ?01111?
   349  	// ???0111
   350  	// -------
   351  	// ????11?
   352  
   353  	return (x >> y) & 0b110 // ERROR "known value of v[0-9]+ \(And32\): 6$"
   354  }
   355  
   356  func knownBitsRshSignCopy(x, y int64) int64 {
   357  	x |= -1 << 63
   358  	y |= 128
   359  
   360  	return (x >> y) & 1 // ERROR "known value of v[0-9]+ \(And64\): 1$"
   361  }
   362  
   363  func unknownBitsRshLeftSideMsb(x int32, y int32) int32 {
   364  	x |= 0b11110
   365  	x &^= 0b100000
   366  	y &= 2
   367  
   368  	return (x >> y) & 0b1110
   369  }
   370  
   371  func unknownBitsRshLeftSideLsb(x int32, y int32) int32 {
   372  	x |= 0b11110
   373  	x &^= 0b100000
   374  	y &= 2
   375  
   376  	return (x >> y) & 0b111
   377  }
   378  
   379  func unknownBitsRshRightSide(x int32, y int32) int32 {
   380  	x |= 0b11110
   381  	x &^= 0b100000
   382  	y &= 6
   383  
   384  	return (x >> y) & 0b110
   385  }
   386  
   387  func knownBitsTrunc(x int64, cond bool) int32 {
   388  	x |= 2
   389  	if cond {
   390  		x = 3
   391  	}
   392  
   393  	return int32(x) & 2 // ERROR "known value of v[0-9]+ \(And32\): 2$"
   394  }
   395  
   396  func unknownBitsTrunc(x int64, cond bool) int32 {
   397  	x |= 2
   398  	if cond {
   399  		x = 3
   400  	}
   401  
   402  	return int32(x) & 1
   403  }
   404  
   405  func knownBitsSextAfterTrunc(x int64, cond1, cond2 bool) int64 {
   406  	x |= -1 << 31
   407  	if cond1 {
   408  		x = -3
   409  	}
   410  
   411  	truncated := int32(x)
   412  
   413  	if cond2 {
   414  		truncated |= 4
   415  	}
   416  
   417  	return int64(truncated) & (-1 << 63) // ERROR "known value of v[0-9]+ \(And64\): -9223372036854775808$"
   418  }
   419  
   420  func unknownBitsSextAfterTrunc(x int64, cond1, cond2 bool) int64 {
   421  	x |= 2
   422  	if cond1 {
   423  		x = 3
   424  	}
   425  
   426  	truncated := int32(x)
   427  
   428  	if cond2 {
   429  		truncated |= 4
   430  	}
   431  
   432  	return int64(truncated) & (-1 << 63)
   433  }
   434  

View as plain text