...
Run Format

Text file src/cmd/compile/internal/ssa/_gen/divisible.rules

Documentation: cmd/compile/internal/ssa/_gen

     1// Copyright 2025 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// Divisibility checks (x%c == 0 or x%c != 0) convert to multiply, rotate, compare.
     6// The opt pass rewrote x%c to x-(x/c)*c
     7// and then also rewrote x-(x/c)*c == 0 to x == (x/c)*c.
     8// If x/c is being used for a division already (div.Uses != 1)
     9// then we leave the expression alone.
    10//
    11// See ../magic.go for a detailed description of these algorithms.
    12// See test/codegen/divmod.go for tests.
    13// See divmod.rules for other division rules that run after these.
    14
    15// Divisiblity by unsigned or signed power of two.
    16(Eq(8|16|32|64)  x (Mul(8|16|32|64) <t> (Div(8|16|32|64)u x (Const(8|16|32|64) [c])) (Const(8|16|32|64) [c])))
    17  && x.Op != OpConst64 && isPowerOfTwo(c) =>
    18  (Eq(8|16|32|64)  (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [c-1])) (Const(8|16|32|64) <t> [0]))
    19(Eq(8|16|32|64)  x (Mul(8|16|32|64) <t> (Div(8|16|32|64)  x (Const(8|16|32|64) [c])) (Const(8|16|32|64) [c])))
    20  && x.Op != OpConst64 && isPowerOfTwo(c) =>
    21  (Eq(8|16|32|64)  (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [c-1])) (Const(8|16|32|64) <t> [0]))
    22(Neq(8|16|32|64) x (Mul(8|16|32|64) <t> (Div(8|16|32|64)u x (Const(8|16|32|64) [c])) (Const(8|16|32|64) [c])))
    23  && x.Op != OpConst64 && isPowerOfTwo(c) =>
    24  (Neq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [c-1])) (Const(8|16|32|64) <t> [0]))
    25(Neq(8|16|32|64) x (Mul(8|16|32|64) <t> (Div(8|16|32|64)  x (Const(8|16|32|64) [c])) (Const(8|16|32|64) [c])))
    26  && x.Op != OpConst64 && isPowerOfTwo(c) =>
    27  (Neq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [c-1])) (Const(8|16|32|64) <t> [0]))
    28
    29// Divisiblity by unsigned.
    30(Eq8 x (Mul8 <t> div:(Div8u x (Const8 [c])) (Const8 [c])))
    31  && div.Uses == 1
    32  && x.Op != OpConst8 && udivisibleOK8(c) =>
    33  (Leq8U
    34    (RotateLeft8 <t>
    35      (Mul8 <t> x (Const8 <t> [int8(udivisible8(c).m)]))
    36      (Const8 <t> [int8(8 - udivisible8(c).k)]))
    37    (Const8 <t> [int8(udivisible8(c).max)]))
    38(Neq8 x (Mul8 <t> div:(Div8u x (Const8 [c])) (Const8 [c])))
    39  && div.Uses == 1
    40  && x.Op != OpConst8 && udivisibleOK8(c) =>
    41  (Less8U
    42    (Const8 <t> [int8(udivisible8(c).max)])
    43    (RotateLeft8 <t>
    44      (Mul8 <t> x (Const8 <t> [int8(udivisible8(c).m)]))
    45      (Const8 <t> [int8(8 - udivisible8(c).k)])))
    46(Eq16 x (Mul16 <t> div:(Div16u x (Const16 [c])) (Const16 [c])))
    47  && div.Uses == 1
    48  && x.Op != OpConst16 && udivisibleOK16(c) =>
    49  (Leq16U
    50    (RotateLeft16 <t>
    51      (Mul16 <t> x (Const16 <t> [int16(udivisible16(c).m)]))
    52      (Const16 <t> [int16(16 - udivisible16(c).k)]))
    53    (Const16 <t> [int16(udivisible16(c).max)]))
    54(Neq16 x (Mul16 <t> div:(Div16u x (Const16 [c])) (Const16 [c])))
    55  && div.Uses == 1
    56  && x.Op != OpConst16 && udivisibleOK16(c) =>
    57  (Less16U
    58    (Const16 <t> [int16(udivisible16(c).max)])
    59    (RotateLeft16 <t>
    60      (Mul16 <t> x (Const16 <t> [int16(udivisible16(c).m)]))
    61      (Const16 <t> [int16(16 - udivisible16(c).k)])))
    62(Eq32 x (Mul32 <t> div:(Div32u x (Const32 [c])) (Const32 [c])))
    63  && div.Uses == 1
    64  && x.Op != OpConst32 && udivisibleOK32(c) =>
    65  (Leq32U
    66    (RotateLeft32 <t>
    67      (Mul32 <t> x (Const32 <t> [int32(udivisible32(c).m)]))
    68      (Const32 <t> [int32(32 - udivisible32(c).k)]))
    69    (Const32 <t> [int32(udivisible32(c).max)]))
    70(Neq32 x (Mul32 <t> div:(Div32u x (Const32 [c])) (Const32 [c])))
    71  && div.Uses == 1
    72  && x.Op != OpConst32 && udivisibleOK32(c) =>
    73  (Less32U
    74    (Const32 <t> [int32(udivisible32(c).max)])
    75    (RotateLeft32 <t>
    76      (Mul32 <t> x (Const32 <t> [int32(udivisible32(c).m)]))
    77      (Const32 <t> [int32(32 - udivisible32(c).k)])))
    78(Eq64 x (Mul64 <t> div:(Div64u x (Const64 [c])) (Const64 [c])))
    79  && div.Uses == 1
    80  && x.Op != OpConst64 && udivisibleOK64(c) =>
    81  (Leq64U
    82    (RotateLeft64 <t>
    83      (Mul64 <t> x (Const64 <t> [int64(udivisible64(c).m)]))
    84      (Const64 <t> [int64(64 - udivisible64(c).k)]))
    85    (Const64 <t> [int64(udivisible64(c).max)]))
    86(Neq64 x (Mul64 <t> div:(Div64u x (Const64 [c])) (Const64 [c])))
    87  && div.Uses == 1
    88  && x.Op != OpConst64 && udivisibleOK64(c) =>
    89  (Less64U
    90    (Const64 <t> [int64(udivisible64(c).max)])
    91    (RotateLeft64 <t>
    92      (Mul64 <t> x (Const64 <t> [int64(udivisible64(c).m)]))
    93      (Const64 <t> [int64(64 - udivisible64(c).k)])))
    94
    95// Divisiblity by signed.
    96(Eq8 x (Mul8 <t> div:(Div8  x (Const8 [c])) (Const8 [c])))
    97  && div.Uses == 1
    98  && x.Op != OpConst8 && sdivisibleOK8(c) =>
    99  (Leq8U
   100    (RotateLeft8 <t>
   101      (Add8 <t> (Mul8 <t> x (Const8 <t> [int8(sdivisible8(c).m)]))
   102        (Const8 <t> [int8(sdivisible8(c).a)]))
   103      (Const8 <t> [int8(8 - sdivisible8(c).k)]))
   104    (Const8 <t> [int8(sdivisible8(c).max)]))
   105(Neq8 x (Mul8 <t> div:(Div8  x (Const8 [c])) (Const8 [c])))
   106  && div.Uses == 1
   107  && x.Op != OpConst8 && sdivisibleOK8(c) =>
   108  (Less8U
   109    (Const8 <t> [int8(sdivisible8(c).max)])
   110    (RotateLeft8 <t>
   111      (Add8 <t> (Mul8 <t> x (Const8 <t> [int8(sdivisible8(c).m)]))
   112        (Const8 <t> [int8(sdivisible8(c).a)]))
   113      (Const8 <t> [int8(8 - sdivisible8(c).k)])))
   114(Eq16 x (Mul16 <t> div:(Div16 x (Const16 [c])) (Const16 [c])))
   115  && div.Uses == 1
   116  && x.Op != OpConst16 && sdivisibleOK16(c) =>
   117  (Leq16U
   118    (RotateLeft16 <t>
   119      (Add16 <t> (Mul16 <t> x (Const16 <t> [int16(sdivisible16(c).m)]))
   120        (Const16 <t> [int16(sdivisible16(c).a)]))
   121      (Const16 <t> [int16(16 - sdivisible16(c).k)]))
   122    (Const16 <t> [int16(sdivisible16(c).max)]))
   123(Neq16 x (Mul16 <t> div:(Div16 x (Const16 [c])) (Const16 [c])))
   124  && div.Uses == 1
   125  && x.Op != OpConst16 && sdivisibleOK16(c) =>
   126  (Less16U
   127    (Const16 <t> [int16(sdivisible16(c).max)])
   128    (RotateLeft16 <t>
   129      (Add16 <t> (Mul16 <t> x (Const16 <t> [int16(sdivisible16(c).m)]))
   130        (Const16 <t> [int16(sdivisible16(c).a)]))
   131      (Const16 <t> [int16(16 - sdivisible16(c).k)])))
   132(Eq32 x (Mul32 <t> div:(Div32 x (Const32 [c])) (Const32 [c])))
   133  && div.Uses == 1
   134  && x.Op != OpConst32 && sdivisibleOK32(c) =>
   135  (Leq32U
   136    (RotateLeft32 <t>
   137      (Add32 <t> (Mul32 <t> x (Const32 <t> [int32(sdivisible32(c).m)]))
   138        (Const32 <t> [int32(sdivisible32(c).a)]))
   139      (Const32 <t> [int32(32 - sdivisible32(c).k)]))
   140    (Const32 <t> [int32(sdivisible32(c).max)]))
   141(Neq32 x (Mul32 <t> div:(Div32 x (Const32 [c])) (Const32 [c])))
   142  && div.Uses == 1
   143  && x.Op != OpConst32 && sdivisibleOK32(c) =>
   144  (Less32U
   145    (Const32 <t> [int32(sdivisible32(c).max)])
   146    (RotateLeft32 <t>
   147      (Add32 <t> (Mul32 <t> x (Const32 <t> [int32(sdivisible32(c).m)]))
   148        (Const32 <t> [int32(sdivisible32(c).a)]))
   149      (Const32 <t> [int32(32 - sdivisible32(c).k)])))
   150(Eq64 x (Mul64 <t> div:(Div64 x (Const64 [c])) (Const64 [c])))
   151  && div.Uses == 1
   152  && x.Op != OpConst64 && sdivisibleOK64(c) =>
   153  (Leq64U
   154    (RotateLeft64 <t>
   155      (Add64 <t> (Mul64 <t> x (Const64 <t> [int64(sdivisible64(c).m)]))
   156        (Const64 <t> [int64(sdivisible64(c).a)]))
   157      (Const64 <t> [int64(64 - sdivisible64(c).k)]))
   158    (Const64 <t> [int64(sdivisible64(c).max)]))
   159(Neq64 x (Mul64 <t> div:(Div64 x (Const64 [c])) (Const64 [c])))
   160  && div.Uses == 1
   161  && x.Op != OpConst64 && sdivisibleOK64(c) =>
   162  (Less64U
   163    (Const64 <t> [int64(sdivisible64(c).max)])
   164    (RotateLeft64 <t>
   165      (Add64 <t> (Mul64 <t> x (Const64 <t> [int64(sdivisible64(c).m)]))
   166        (Const64 <t> [int64(sdivisible64(c).a)]))
   167      (Const64 <t> [int64(64 - sdivisible64(c).k)])))

View as plain text