cmd/compile: don't lift divide instructions out of loops

We can't lift things that might panic out of loops.
(In particular, for divides, out from underneath their divisor==0 check.)

Technically, it's not "things that might panic", but "instructions
that might fault". We have to ensure that we issue those instructions
only after we've checked their preconditions. It would be great if
there was an integer divide instruction that didn't fault on
divisor==0. Then it would be ok to lift it, as we already guarantee
we don't use the result. (I'm presuming here all the archs we support
only have faulting integer divides. If we have nonfaulting divides,
we could use them and revert this CL for that arch.)

Fixes #78892

Change-Id: Ie09d1f3d28ae320f6835730c2debcf0dd3df6a04
Reviewed-on: https://go-review.googlesource.com/c/go/+/769700
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
khr@golang.org 2026-04-21 16:21:54 -04:00 committed by Gopher Robot
parent 81973b4038
commit 9c688e3f4d
14 changed files with 396 additions and 304 deletions

View file

@ -209,15 +209,15 @@ func init() {
{name: "AVGLU", argLength: 2, reg: gp21, commutative: true, resultInArg0: true, clobberFlags: true}, // (arg0 + arg1) / 2 as unsigned, all 32 result bits
// For DIVL, DIVW, MODL and MODW, AuxInt non-zero means that the divisor has been proved to be not -1.
{name: "DIVL", argLength: 2, reg: gp11div, asm: "IDIVL", aux: "Bool", clobberFlags: true}, // arg0 / arg1
{name: "DIVW", argLength: 2, reg: gp11div, asm: "IDIVW", aux: "Bool", clobberFlags: true}, // arg0 / arg1
{name: "DIVLU", argLength: 2, reg: gp11div, asm: "DIVL", clobberFlags: true}, // arg0 / arg1
{name: "DIVWU", argLength: 2, reg: gp11div, asm: "DIVW", clobberFlags: true}, // arg0 / arg1
{name: "DIVL", argLength: 2, reg: gp11div, asm: "IDIVL", aux: "Bool", clobberFlags: true, hasSideEffects: true}, // arg0 / arg1
{name: "DIVW", argLength: 2, reg: gp11div, asm: "IDIVW", aux: "Bool", clobberFlags: true, hasSideEffects: true}, // arg0 / arg1
{name: "DIVLU", argLength: 2, reg: gp11div, asm: "DIVL", clobberFlags: true, hasSideEffects: true}, // arg0 / arg1
{name: "DIVWU", argLength: 2, reg: gp11div, asm: "DIVW", clobberFlags: true, hasSideEffects: true}, // arg0 / arg1
{name: "MODL", argLength: 2, reg: gp11mod, asm: "IDIVL", aux: "Bool", clobberFlags: true}, // arg0 % arg1
{name: "MODW", argLength: 2, reg: gp11mod, asm: "IDIVW", aux: "Bool", clobberFlags: true}, // arg0 % arg1
{name: "MODLU", argLength: 2, reg: gp11mod, asm: "DIVL", clobberFlags: true}, // arg0 % arg1
{name: "MODWU", argLength: 2, reg: gp11mod, asm: "DIVW", clobberFlags: true}, // arg0 % arg1
{name: "MODL", argLength: 2, reg: gp11mod, asm: "IDIVL", aux: "Bool", clobberFlags: true, hasSideEffects: true}, // arg0 % arg1
{name: "MODW", argLength: 2, reg: gp11mod, asm: "IDIVW", aux: "Bool", clobberFlags: true, hasSideEffects: true}, // arg0 % arg1
{name: "MODLU", argLength: 2, reg: gp11mod, asm: "DIVL", clobberFlags: true, hasSideEffects: true}, // arg0 % arg1
{name: "MODWU", argLength: 2, reg: gp11mod, asm: "DIVW", clobberFlags: true, hasSideEffects: true}, // arg0 % arg1
{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 & arg1
{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint

View file

@ -395,12 +395,12 @@ func init() {
// DIVx[U] computes [arg0 / arg1, arg0 % arg1]
// For signed versions, AuxInt non-zero means that the divisor has been proved to be not -1.
{name: "DIVQ", argLength: 2, reg: gp11div, typ: "(Int64,Int64)", asm: "IDIVQ", aux: "Bool", clobberFlags: true},
{name: "DIVL", argLength: 2, reg: gp11div, typ: "(Int32,Int32)", asm: "IDIVL", aux: "Bool", clobberFlags: true},
{name: "DIVW", argLength: 2, reg: gp11div, typ: "(Int16,Int16)", asm: "IDIVW", aux: "Bool", clobberFlags: true},
{name: "DIVQU", argLength: 2, reg: gp11div, typ: "(UInt64,UInt64)", asm: "DIVQ", clobberFlags: true},
{name: "DIVLU", argLength: 2, reg: gp11div, typ: "(UInt32,UInt32)", asm: "DIVL", clobberFlags: true},
{name: "DIVWU", argLength: 2, reg: gp11div, typ: "(UInt16,UInt16)", asm: "DIVW", clobberFlags: true},
{name: "DIVQ", argLength: 2, reg: gp11div, typ: "(Int64,Int64)", asm: "IDIVQ", aux: "Bool", clobberFlags: true, hasSideEffects: true},
{name: "DIVL", argLength: 2, reg: gp11div, typ: "(Int32,Int32)", asm: "IDIVL", aux: "Bool", clobberFlags: true, hasSideEffects: true},
{name: "DIVW", argLength: 2, reg: gp11div, typ: "(Int16,Int16)", asm: "IDIVW", aux: "Bool", clobberFlags: true, hasSideEffects: true},
{name: "DIVQU", argLength: 2, reg: gp11div, typ: "(UInt64,UInt64)", asm: "DIVQ", clobberFlags: true, hasSideEffects: true},
{name: "DIVLU", argLength: 2, reg: gp11div, typ: "(UInt32,UInt32)", asm: "DIVL", clobberFlags: true, hasSideEffects: true},
{name: "DIVWU", argLength: 2, reg: gp11div, typ: "(UInt16,UInt16)", asm: "DIVW", clobberFlags: true, hasSideEffects: true},
// computes -arg0, flags set for 0-arg0.
{name: "NEGLflags", argLength: 1, reg: gp11flags, typ: "(UInt32,Flags)", asm: "NEGL", resultInArg0: true},
@ -424,8 +424,8 @@ func init() {
{name: "SUBQconstborrow", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "SUBQ", aux: "Int32", resultInArg0: true}, // r = arg0-auxint
{name: "SBBQconst", argLength: 2, reg: gp1flags1flags, typ: "(UInt64,Flags)", asm: "SBBQ", aux: "Int32", resultInArg0: true}, // r = arg0-(auxint+carry(arg1))
{name: "MULQU2", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx, ax}}, commutative: true, asm: "MULQ", clobberFlags: true}, // arg0 * arg1, returns (hi, lo)
{name: "DIVQU2", argLength: 3, reg: regInfo{inputs: []regMask{dx, ax, gpsp}, outputs: []regMask{ax, dx}}, asm: "DIVQ", clobberFlags: true}, // arg0:arg1 / arg2 (128-bit divided by 64-bit), returns (q, r)
{name: "MULQU2", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx, ax}}, commutative: true, asm: "MULQ", clobberFlags: true}, // arg0 * arg1, returns (hi, lo)
{name: "DIVQU2", argLength: 3, reg: regInfo{inputs: []regMask{dx, ax, gpsp}, outputs: []regMask{ax, dx}}, asm: "DIVQ", clobberFlags: true, hasSideEffects: true}, // arg0:arg1 / arg2 (128-bit divided by 64-bit), returns (q, r)
{name: "ANDQ", argLength: 2, reg: gp21, asm: "ANDQ", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 & arg1
{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 & arg1

View file

@ -212,14 +212,14 @@ func init() {
{name: "UMULH", argLength: 2, reg: gp21, asm: "UMULH", commutative: true}, // (arg0 * arg1) >> 64, unsigned
{name: "MULL", argLength: 2, reg: gp21, asm: "SMULL", commutative: true}, // arg0 * arg1, signed, 32-bit mult results in 64-bit
{name: "UMULL", argLength: 2, reg: gp21, asm: "UMULL", commutative: true}, // arg0 * arg1, unsigned, 32-bit mult results in 64-bit
{name: "DIV", argLength: 2, reg: gp21, asm: "SDIV"}, // arg0 / arg1, signed
{name: "UDIV", argLength: 2, reg: gp21, asm: "UDIV"}, // arg0 / arg1, unsigned
{name: "DIVW", argLength: 2, reg: gp21, asm: "SDIVW"}, // arg0 / arg1, signed, 32 bit
{name: "UDIVW", argLength: 2, reg: gp21, asm: "UDIVW"}, // arg0 / arg1, unsigned, 32 bit
{name: "MOD", argLength: 2, reg: gp21, asm: "REM"}, // arg0 % arg1, signed
{name: "UMOD", argLength: 2, reg: gp21, asm: "UREM"}, // arg0 % arg1, unsigned
{name: "MODW", argLength: 2, reg: gp21, asm: "REMW"}, // arg0 % arg1, signed, 32 bit
{name: "UMODW", argLength: 2, reg: gp21, asm: "UREMW"}, // arg0 % arg1, unsigned, 32 bit
{name: "DIV", argLength: 2, reg: gp21, asm: "SDIV", hasSideEffects: true}, // arg0 / arg1, signed
{name: "UDIV", argLength: 2, reg: gp21, asm: "UDIV", hasSideEffects: true}, // arg0 / arg1, unsigned
{name: "DIVW", argLength: 2, reg: gp21, asm: "SDIVW", hasSideEffects: true}, // arg0 / arg1, signed, 32 bit
{name: "UDIVW", argLength: 2, reg: gp21, asm: "UDIVW", hasSideEffects: true}, // arg0 / arg1, unsigned, 32 bit
{name: "MOD", argLength: 2, reg: gp21, asm: "REM", hasSideEffects: true}, // arg0 % arg1, signed
{name: "UMOD", argLength: 2, reg: gp21, asm: "UREM", hasSideEffects: true}, // arg0 % arg1, unsigned
{name: "MODW", argLength: 2, reg: gp21, asm: "REMW", hasSideEffects: true}, // arg0 % arg1, signed, 32 bit
{name: "UMODW", argLength: 2, reg: gp21, asm: "UREMW", hasSideEffects: true}, // arg0 % arg1, unsigned, 32 bit
{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true}, // arg0 + arg1
{name: "FADDD", argLength: 2, reg: fp21, asm: "FADDD", commutative: true}, // arg0 + arg1

View file

@ -157,9 +157,10 @@ func init() {
outputs: []regMask{buildReg("R0"), buildReg("R1")},
clobbers: buildReg("R2 R3 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
},
clobberFlags: true,
typ: "(UInt32,UInt32)",
call: false, // TODO(mdempsky): Should this be true?
clobberFlags: true,
typ: "(UInt32,UInt32)",
call: false, // TODO(mdempsky): Should this be true?
hasSideEffects: true,
},
{name: "ADDS", argLength: 2, reg: gp21carry, asm: "ADD", commutative: true}, // arg0 + arg1, set carry flag

View file

@ -197,17 +197,17 @@ func init() {
{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"}, // arg0 - arg1
{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"}, // arg0 - auxInt
{name: "MULV", argLength: 2, reg: gp21, asm: "MULV", commutative: true, typ: "Int64"}, // arg0 * arg1
{name: "MULHV", argLength: 2, reg: gp21, asm: "MULHV", commutative: true, typ: "Int64"}, // (arg0 * arg1) >> 64, signed
{name: "MULHVU", argLength: 2, reg: gp21, asm: "MULHVU", commutative: true, typ: "UInt64"}, // (arg0 * arg1) >> 64, unsigned
{name: "MULH", argLength: 2, reg: gp21, asm: "MULH", commutative: true, typ: "Int32"}, // (arg0 * arg1) >> 32, signed
{name: "MULHU", argLength: 2, reg: gp21, asm: "MULHU", commutative: true, typ: "UInt32"}, // (arg0 * arg1) >> 32, unsigned
{name: "DIVV", argLength: 2, reg: gp21, asm: "DIVV", typ: "Int64"}, // arg0 / arg1, signed
{name: "DIVVU", argLength: 2, reg: gp21, asm: "DIVVU", typ: "UInt64"}, // arg0 / arg1, unsigned
{name: "REMV", argLength: 2, reg: gp21, asm: "REMV", typ: "Int64"}, // arg0 / arg1, signed
{name: "REMVU", argLength: 2, reg: gp21, asm: "REMVU", typ: "UInt64"}, // arg0 / arg1, unsigned
{name: "MULWVW", argLength: 2, reg: gp21, asm: "MULWVW", commutative: true}, // arg0 * arg1, signed, 32-bit mult results in 64-bit
{name: "MULWVWU", argLength: 2, reg: gp21, asm: "MULWVWU", commutative: true}, // arg0 * arg1, unsigned, 32-bit mult results in 64-bit
{name: "MULV", argLength: 2, reg: gp21, asm: "MULV", commutative: true, typ: "Int64"}, // arg0 * arg1
{name: "MULHV", argLength: 2, reg: gp21, asm: "MULHV", commutative: true, typ: "Int64"}, // (arg0 * arg1) >> 64, signed
{name: "MULHVU", argLength: 2, reg: gp21, asm: "MULHVU", commutative: true, typ: "UInt64"}, // (arg0 * arg1) >> 64, unsigned
{name: "MULH", argLength: 2, reg: gp21, asm: "MULH", commutative: true, typ: "Int32"}, // (arg0 * arg1) >> 32, signed
{name: "MULHU", argLength: 2, reg: gp21, asm: "MULHU", commutative: true, typ: "UInt32"}, // (arg0 * arg1) >> 32, unsigned
{name: "DIVV", argLength: 2, reg: gp21, asm: "DIVV", typ: "Int64", hasSideEffects: true}, // arg0 / arg1, signed
{name: "DIVVU", argLength: 2, reg: gp21, asm: "DIVVU", typ: "UInt64", hasSideEffects: true}, // arg0 / arg1, unsigned
{name: "REMV", argLength: 2, reg: gp21, asm: "REMV", typ: "Int64", hasSideEffects: true}, // arg0 / arg1, signed
{name: "REMVU", argLength: 2, reg: gp21, asm: "REMVU", typ: "UInt64", hasSideEffects: true}, // arg0 / arg1, unsigned
{name: "MULWVW", argLength: 2, reg: gp21, asm: "MULWVW", commutative: true}, // arg0 * arg1, signed, 32-bit mult results in 64-bit
{name: "MULWVWU", argLength: 2, reg: gp21, asm: "MULWVWU", commutative: true}, // arg0 * arg1, unsigned, 32-bit mult results in 64-bit
{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1

View file

@ -164,14 +164,14 @@ func init() {
)
ops := []opData{
// binary ops
{name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true}, // arg0 + arg1
{name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"}, // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"}, // arg0 - arg1
{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"}, // arg0 - auxInt
{name: "MULV", argLength: 2, reg: gp2hilo, asm: "MULV", commutative: true, typ: "(Int64,Int64)"}, // arg0 * arg1, signed, results hi,lo
{name: "MULVU", argLength: 2, reg: gp2hilo, asm: "MULVU", commutative: true, typ: "(UInt64,UInt64)"}, // arg0 * arg1, unsigned, results hi,lo
{name: "DIVV", argLength: 2, reg: gp2hilo, asm: "DIVV", typ: "(Int64,Int64)"}, // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
{name: "DIVVU", argLength: 2, reg: gp2hilo, asm: "DIVVU", typ: "(UInt64,UInt64)"}, // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
{name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true}, // arg0 + arg1
{name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"}, // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"}, // arg0 - arg1
{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"}, // arg0 - auxInt
{name: "MULV", argLength: 2, reg: gp2hilo, asm: "MULV", commutative: true, typ: "(Int64,Int64)"}, // arg0 * arg1, signed, results hi,lo
{name: "MULVU", argLength: 2, reg: gp2hilo, asm: "MULVU", commutative: true, typ: "(UInt64,UInt64)"}, // arg0 * arg1, unsigned, results hi,lo
{name: "DIVV", argLength: 2, reg: gp2hilo, asm: "DIVV", typ: "(Int64,Int64)", hasSideEffects: true}, // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
{name: "DIVVU", argLength: 2, reg: gp2hilo, asm: "DIVVU", typ: "(UInt64,UInt64)", hasSideEffects: true}, // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1

View file

@ -154,8 +154,8 @@ func init() {
{name: "MUL", argLength: 2, reg: regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}, clobbers: hi | lo}, asm: "MUL", commutative: true}, // arg0 * arg1
{name: "MULT", argLength: 2, reg: gp2hilo, asm: "MUL", commutative: true, typ: "(Int32,Int32)"}, // arg0 * arg1, signed, results hi,lo
{name: "MULTU", argLength: 2, reg: gp2hilo, asm: "MULU", commutative: true, typ: "(UInt32,UInt32)"}, // arg0 * arg1, unsigned, results hi,lo
{name: "DIV", argLength: 2, reg: gp2hilo, asm: "DIV", typ: "(Int32,Int32)"}, // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
{name: "DIVU", argLength: 2, reg: gp2hilo, asm: "DIVU", typ: "(UInt32,UInt32)"}, // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
{name: "DIV", argLength: 2, reg: gp2hilo, asm: "DIV", typ: "(Int32,Int32)", hasSideEffects: true}, // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
{name: "DIVU", argLength: 2, reg: gp2hilo, asm: "DIVU", typ: "(UInt32,UInt32)", hasSideEffects: true}, // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1

View file

@ -267,15 +267,15 @@ func init() {
{name: "FDIV", argLength: 2, reg: fp21, asm: "FDIV"}, // arg0/arg1
{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS"}, // arg0/arg1
{name: "DIVD", argLength: 2, reg: gp21, asm: "DIVD", typ: "Int64"}, // arg0/arg1 (signed 64-bit)
{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32"}, // arg0/arg1 (signed 32-bit)
{name: "DIVDU", argLength: 2, reg: gp21, asm: "DIVDU", typ: "Int64"}, // arg0/arg1 (unsigned 64-bit)
{name: "DIVWU", argLength: 2, reg: gp21, asm: "DIVWU", typ: "Int32"}, // arg0/arg1 (unsigned 32-bit)
{name: "DIVD", argLength: 2, reg: gp21, asm: "DIVD", typ: "Int64", hasSideEffects: true}, // arg0/arg1 (signed 64-bit)
{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32", hasSideEffects: true}, // arg0/arg1 (signed 32-bit)
{name: "DIVDU", argLength: 2, reg: gp21, asm: "DIVDU", typ: "Int64", hasSideEffects: true}, // arg0/arg1 (unsigned 64-bit)
{name: "DIVWU", argLength: 2, reg: gp21, asm: "DIVWU", typ: "Int32", hasSideEffects: true}, // arg0/arg1 (unsigned 32-bit)
{name: "MODUD", argLength: 2, reg: gp21, asm: "MODUD", typ: "UInt64"}, // arg0 % arg1 (unsigned 64-bit)
{name: "MODSD", argLength: 2, reg: gp21, asm: "MODSD", typ: "Int64"}, // arg0 % arg1 (signed 64-bit)
{name: "MODUW", argLength: 2, reg: gp21, asm: "MODUW", typ: "UInt32"}, // arg0 % arg1 (unsigned 32-bit)
{name: "MODSW", argLength: 2, reg: gp21, asm: "MODSW", typ: "Int32"}, // arg0 % arg1 (signed 32-bit)
{name: "MODUD", argLength: 2, reg: gp21, asm: "MODUD", typ: "UInt64", hasSideEffects: true}, // arg0 % arg1 (unsigned 64-bit)
{name: "MODSD", argLength: 2, reg: gp21, asm: "MODSD", typ: "Int64", hasSideEffects: true}, // arg0 % arg1 (signed 64-bit)
{name: "MODUW", argLength: 2, reg: gp21, asm: "MODUW", typ: "UInt32", hasSideEffects: true}, // arg0 % arg1 (unsigned 32-bit)
{name: "MODSW", argLength: 2, reg: gp21, asm: "MODSW", typ: "Int32", hasSideEffects: true}, // arg0 % arg1 (signed 32-bit)
// MOD is implemented as rem := arg0 - (arg0/arg1) * arg1
// Conversions are all float-to-float register operations. "Integer" refers to encoding in the FP register.

View file

@ -170,14 +170,14 @@ func init() {
{name: "LoweredMuluhilo", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, return (hi, lo)
{name: "LoweredMuluover", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, return (64 bits of arg0*arg1, overflow)
{name: "DIV", argLength: 2, reg: gp21, asm: "DIV", typ: "Int64"}, // arg0 / arg1
{name: "DIVU", argLength: 2, reg: gp21, asm: "DIVU", typ: "UInt64"},
{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32"},
{name: "DIVUW", argLength: 2, reg: gp21, asm: "DIVUW", typ: "UInt32"},
{name: "REM", argLength: 2, reg: gp21, asm: "REM", typ: "Int64"}, // arg0 % arg1
{name: "REMU", argLength: 2, reg: gp21, asm: "REMU", typ: "UInt64"},
{name: "REMW", argLength: 2, reg: gp21, asm: "REMW", typ: "Int32"},
{name: "REMUW", argLength: 2, reg: gp21, asm: "REMUW", typ: "UInt32"},
{name: "DIV", argLength: 2, reg: gp21, asm: "DIV", typ: "Int64", hasSideEffects: true}, // arg0 / arg1
{name: "DIVU", argLength: 2, reg: gp21, asm: "DIVU", typ: "UInt64", hasSideEffects: true},
{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32", hasSideEffects: true},
{name: "DIVUW", argLength: 2, reg: gp21, asm: "DIVUW", typ: "UInt32", hasSideEffects: true},
{name: "REM", argLength: 2, reg: gp21, asm: "REM", typ: "Int64", hasSideEffects: true}, // arg0 % arg1
{name: "REMU", argLength: 2, reg: gp21, asm: "REMU", typ: "UInt64", hasSideEffects: true},
{name: "REMW", argLength: 2, reg: gp21, asm: "REMW", typ: "Int32", hasSideEffects: true},
{name: "REMUW", argLength: 2, reg: gp21, asm: "REMUW", typ: "UInt32", hasSideEffects: true},
{name: "MOVaddr", argLength: 1, reg: gp11sb, asm: "MOV", aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxint + offset encoded in aux
// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address

View file

@ -277,16 +277,16 @@ func init() {
{name: "MULHD", argLength: 2, reg: gp21tmp, asm: "MULHD", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true}, // (arg0 * arg1) >> width
{name: "MULHDU", argLength: 2, reg: gp21tmp, asm: "MULHDU", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true}, // (arg0 * arg1) >> width
{name: "DIVD", argLength: 2, reg: gp21tmp, asm: "DIVD", resultInArg0: true, clobberFlags: true}, // arg0 / arg1
{name: "DIVW", argLength: 2, reg: gp21tmp, asm: "DIVW", resultInArg0: true, clobberFlags: true}, // arg0 / arg1
{name: "DIVDU", argLength: 2, reg: gp21tmp, asm: "DIVDU", resultInArg0: true, clobberFlags: true}, // arg0 / arg1
{name: "DIVWU", argLength: 2, reg: gp21tmp, asm: "DIVWU", resultInArg0: true, clobberFlags: true}, // arg0 / arg1
{name: "DIVD", argLength: 2, reg: gp21tmp, asm: "DIVD", resultInArg0: true, clobberFlags: true, hasSideEffects: true}, // arg0 / arg1
{name: "DIVW", argLength: 2, reg: gp21tmp, asm: "DIVW", resultInArg0: true, clobberFlags: true, hasSideEffects: true}, // arg0 / arg1
{name: "DIVDU", argLength: 2, reg: gp21tmp, asm: "DIVDU", resultInArg0: true, clobberFlags: true, hasSideEffects: true}, // arg0 / arg1
{name: "DIVWU", argLength: 2, reg: gp21tmp, asm: "DIVWU", resultInArg0: true, clobberFlags: true, hasSideEffects: true}, // arg0 / arg1
{name: "MODD", argLength: 2, reg: gp21tmp, asm: "MODD", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
{name: "MODW", argLength: 2, reg: gp21tmp, asm: "MODW", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
{name: "MODD", argLength: 2, reg: gp21tmp, asm: "MODD", resultInArg0: true, clobberFlags: true, hasSideEffects: true}, // arg0 % arg1
{name: "MODW", argLength: 2, reg: gp21tmp, asm: "MODW", resultInArg0: true, clobberFlags: true, hasSideEffects: true}, // arg0 % arg1
{name: "MODDU", argLength: 2, reg: gp21tmp, asm: "MODDU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
{name: "MODWU", argLength: 2, reg: gp21tmp, asm: "MODWU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
{name: "MODDU", argLength: 2, reg: gp21tmp, asm: "MODDU", resultInArg0: true, clobberFlags: true, hasSideEffects: true}, // arg0 % arg1
{name: "MODWU", argLength: 2, reg: gp21tmp, asm: "MODWU", resultInArg0: true, clobberFlags: true, hasSideEffects: true}, // arg0 % arg1
{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true}, // arg0 & arg1
{name: "ANDW", argLength: 2, reg: gp21, asm: "ANDW", commutative: true, clobberFlags: true}, // arg0 & arg1

View file

@ -196,20 +196,20 @@ func init() {
{name: "F64Le", asm: "F64Le", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 <= arg1
{name: "F64Ge", asm: "F64Ge", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 >= arg1
{name: "I64Add", asm: "I64Add", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 + arg1
{name: "I64AddConst", asm: "I64Add", argLength: 1, reg: gp11, aux: "Int64", typ: "Int64"}, // arg0 + aux
{name: "I64Sub", asm: "I64Sub", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 - arg1
{name: "I64Mul", asm: "I64Mul", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 * arg1
{name: "I64DivS", asm: "I64DivS", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 / arg1 (signed)
{name: "I64DivU", asm: "I64DivU", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 / arg1 (unsigned)
{name: "I64RemS", asm: "I64RemS", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 % arg1 (signed)
{name: "I64RemU", asm: "I64RemU", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 % arg1 (unsigned)
{name: "I64And", asm: "I64And", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 & arg1
{name: "I64Or", asm: "I64Or", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 | arg1
{name: "I64Xor", asm: "I64Xor", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 ^ arg1
{name: "I64Shl", asm: "I64Shl", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 << (arg1 % 64)
{name: "I64ShrS", asm: "I64ShrS", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 >> (arg1 % 64) (signed)
{name: "I64ShrU", asm: "I64ShrU", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 >> (arg1 % 64) (unsigned)
{name: "I64Add", asm: "I64Add", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 + arg1
{name: "I64AddConst", asm: "I64Add", argLength: 1, reg: gp11, aux: "Int64", typ: "Int64"}, // arg0 + aux
{name: "I64Sub", asm: "I64Sub", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 - arg1
{name: "I64Mul", asm: "I64Mul", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 * arg1
{name: "I64DivS", asm: "I64DivS", argLength: 2, reg: gp21, typ: "Int64", hasSideEffects: true}, // arg0 / arg1 (signed)
{name: "I64DivU", asm: "I64DivU", argLength: 2, reg: gp21, typ: "Int64", hasSideEffects: true}, // arg0 / arg1 (unsigned)
{name: "I64RemS", asm: "I64RemS", argLength: 2, reg: gp21, typ: "Int64", hasSideEffects: true}, // arg0 % arg1 (signed)
{name: "I64RemU", asm: "I64RemU", argLength: 2, reg: gp21, typ: "Int64", hasSideEffects: true}, // arg0 % arg1 (unsigned)
{name: "I64And", asm: "I64And", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 & arg1
{name: "I64Or", asm: "I64Or", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 | arg1
{name: "I64Xor", asm: "I64Xor", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 ^ arg1
{name: "I64Shl", asm: "I64Shl", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 << (arg1 % 64)
{name: "I64ShrS", asm: "I64ShrS", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 >> (arg1 % 64) (signed)
{name: "I64ShrU", asm: "I64ShrU", argLength: 2, reg: gp21, typ: "Int64"}, // arg0 >> (arg1 % 64) (unsigned)
{name: "F32Neg", asm: "F32Neg", argLength: 1, reg: fp32_11, typ: "Float32"}, // -arg0
{name: "F32Add", asm: "F32Add", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 + arg1

View file

@ -71,6 +71,10 @@ func licm(f *Func) {
} else if opcodeTable[v.Op].nilCheck {
// NilCheck in case loop executes 0 times. (It has a memory arg anyway?)
loopDep = true
} else if opcodeTable[v.Op].hasSideEffects {
// Operations with side effects cannot be moved.
// (This includes divides that might fault, see issue 78892.)
loopDep = true
} else if v.MemoryArg() != nil {
// Because the state of memory might be different at the loop start. (Also handled by Phi?)
loopDep = true

View file

@ -8327,11 +8327,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVL",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
asm: x86.AIDIVL,
name: "DIVL",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.AIDIVL,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -8344,11 +8345,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVW",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
asm: x86.AIDIVW,
name: "DIVW",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.AIDIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -8361,10 +8363,11 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVLU",
argLen: 2,
clobberFlags: true,
asm: x86.ADIVL,
name: "DIVLU",
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.ADIVL,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -8377,10 +8380,11 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVWU",
argLen: 2,
clobberFlags: true,
asm: x86.ADIVW,
name: "DIVWU",
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.ADIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -8393,11 +8397,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODL",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
asm: x86.AIDIVL,
name: "MODL",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.AIDIVL,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -8410,11 +8415,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODW",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
asm: x86.AIDIVW,
name: "MODW",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.AIDIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -8427,10 +8433,11 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODLU",
argLen: 2,
clobberFlags: true,
asm: x86.ADIVL,
name: "MODLU",
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.ADIVL,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -8443,10 +8450,11 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODWU",
argLen: 2,
clobberFlags: true,
asm: x86.ADIVW,
name: "MODWU",
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.ADIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -12000,11 +12008,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVQ",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
asm: x86.AIDIVQ,
name: "DIVQ",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.AIDIVQ,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -12017,11 +12026,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVL",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
asm: x86.AIDIVL,
name: "DIVL",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.AIDIVL,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -12034,11 +12044,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVW",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
asm: x86.AIDIVW,
name: "DIVW",
auxType: auxBool,
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.AIDIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -12051,10 +12062,11 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVQU",
argLen: 2,
clobberFlags: true,
asm: x86.ADIVQ,
name: "DIVQU",
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.ADIVQ,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -12067,10 +12079,11 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVLU",
argLen: 2,
clobberFlags: true,
asm: x86.ADIVL,
name: "DIVLU",
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.ADIVL,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -12083,10 +12096,11 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVWU",
argLen: 2,
clobberFlags: true,
asm: x86.ADIVW,
name: "DIVWU",
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
asm: x86.ADIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
@ -12293,10 +12307,11 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVQU2",
argLen: 3,
clobberFlags: true,
asm: x86.ADIVQ,
name: "DIVQU2",
argLen: 3,
clobberFlags: true,
hasSideEffects: true,
asm: x86.ADIVQ,
reg: regInfo{
inputs: []inputInfo{
{0, 4}, // DX
@ -61478,9 +61493,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "CALLudiv",
argLen: 2,
clobberFlags: true,
name: "CALLudiv",
argLen: 2,
clobberFlags: true,
hasSideEffects: true,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // R1
@ -65309,9 +65325,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIV",
argLen: 2,
asm: arm64.ASDIV,
name: "DIV",
argLen: 2,
hasSideEffects: true,
asm: arm64.ASDIV,
reg: regInfo{
inputs: []inputInfo{
{0, 402653183}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
@ -65323,9 +65340,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "UDIV",
argLen: 2,
asm: arm64.AUDIV,
name: "UDIV",
argLen: 2,
hasSideEffects: true,
asm: arm64.AUDIV,
reg: regInfo{
inputs: []inputInfo{
{0, 402653183}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
@ -65337,9 +65355,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVW",
argLen: 2,
asm: arm64.ASDIVW,
name: "DIVW",
argLen: 2,
hasSideEffects: true,
asm: arm64.ASDIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 402653183}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
@ -65351,9 +65370,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "UDIVW",
argLen: 2,
asm: arm64.AUDIVW,
name: "UDIVW",
argLen: 2,
hasSideEffects: true,
asm: arm64.AUDIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 402653183}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
@ -65365,9 +65385,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MOD",
argLen: 2,
asm: arm64.AREM,
name: "MOD",
argLen: 2,
hasSideEffects: true,
asm: arm64.AREM,
reg: regInfo{
inputs: []inputInfo{
{0, 402653183}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
@ -65379,9 +65400,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "UMOD",
argLen: 2,
asm: arm64.AUREM,
name: "UMOD",
argLen: 2,
hasSideEffects: true,
asm: arm64.AUREM,
reg: regInfo{
inputs: []inputInfo{
{0, 402653183}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
@ -65393,9 +65415,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODW",
argLen: 2,
asm: arm64.AREMW,
name: "MODW",
argLen: 2,
hasSideEffects: true,
asm: arm64.AREMW,
reg: regInfo{
inputs: []inputInfo{
{0, 402653183}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
@ -65407,9 +65430,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "UMODW",
argLen: 2,
asm: arm64.AUREMW,
name: "UMODW",
argLen: 2,
hasSideEffects: true,
asm: arm64.AUREMW,
reg: regInfo{
inputs: []inputInfo{
{0, 402653183}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
@ -70264,9 +70288,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVV",
argLen: 2,
asm: loong64.ADIVV,
name: "DIVV",
argLen: 2,
hasSideEffects: true,
asm: loong64.ADIVV,
reg: regInfo{
inputs: []inputInfo{
{0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31
@ -70278,9 +70303,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVVU",
argLen: 2,
asm: loong64.ADIVVU,
name: "DIVVU",
argLen: 2,
hasSideEffects: true,
asm: loong64.ADIVVU,
reg: regInfo{
inputs: []inputInfo{
{0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31
@ -70292,9 +70318,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "REMV",
argLen: 2,
asm: loong64.AREMV,
name: "REMV",
argLen: 2,
hasSideEffects: true,
asm: loong64.AREMV,
reg: regInfo{
inputs: []inputInfo{
{0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31
@ -70306,9 +70333,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "REMVU",
argLen: 2,
asm: loong64.AREMVU,
name: "REMVU",
argLen: 2,
hasSideEffects: true,
asm: loong64.AREMVU,
reg: regInfo{
inputs: []inputInfo{
{0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31
@ -72755,9 +72783,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIV",
argLen: 2,
asm: mips.ADIV,
name: "DIV",
argLen: 2,
hasSideEffects: true,
asm: mips.ADIV,
reg: regInfo{
inputs: []inputInfo{
{0, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
@ -72770,9 +72799,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVU",
argLen: 2,
asm: mips.ADIVU,
name: "DIVU",
argLen: 2,
hasSideEffects: true,
asm: mips.ADIVU,
reg: regInfo{
inputs: []inputInfo{
{0, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
@ -74293,9 +74323,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVV",
argLen: 2,
asm: mips.ADIVV,
name: "DIVV",
argLen: 2,
hasSideEffects: true,
asm: mips.ADIVV,
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
@ -74308,9 +74339,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVVU",
argLen: 2,
asm: mips.ADIVVU,
name: "DIVVU",
argLen: 2,
hasSideEffects: true,
asm: mips.ADIVVU,
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
@ -76968,9 +77000,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVD",
argLen: 2,
asm: ppc64.ADIVD,
name: "DIVD",
argLen: 2,
hasSideEffects: true,
asm: ppc64.ADIVD,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@ -76982,9 +77015,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVW",
argLen: 2,
asm: ppc64.ADIVW,
name: "DIVW",
argLen: 2,
hasSideEffects: true,
asm: ppc64.ADIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@ -76996,9 +77030,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVDU",
argLen: 2,
asm: ppc64.ADIVDU,
name: "DIVDU",
argLen: 2,
hasSideEffects: true,
asm: ppc64.ADIVDU,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@ -77010,9 +77045,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVWU",
argLen: 2,
asm: ppc64.ADIVWU,
name: "DIVWU",
argLen: 2,
hasSideEffects: true,
asm: ppc64.ADIVWU,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@ -77024,9 +77060,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODUD",
argLen: 2,
asm: ppc64.AMODUD,
name: "MODUD",
argLen: 2,
hasSideEffects: true,
asm: ppc64.AMODUD,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@ -77038,9 +77075,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODSD",
argLen: 2,
asm: ppc64.AMODSD,
name: "MODSD",
argLen: 2,
hasSideEffects: true,
asm: ppc64.AMODSD,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@ -77052,9 +77090,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODUW",
argLen: 2,
asm: ppc64.AMODUW,
name: "MODUW",
argLen: 2,
hasSideEffects: true,
asm: ppc64.AMODUW,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@ -77066,9 +77105,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODSW",
argLen: 2,
asm: ppc64.AMODSW,
name: "MODSW",
argLen: 2,
hasSideEffects: true,
asm: ppc64.AMODSW,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@ -79374,9 +79414,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIV",
argLen: 2,
asm: riscv.ADIV,
name: "DIV",
argLen: 2,
hasSideEffects: true,
asm: riscv.ADIV,
reg: regInfo{
inputs: []inputInfo{
{0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
@ -79388,9 +79429,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVU",
argLen: 2,
asm: riscv.ADIVU,
name: "DIVU",
argLen: 2,
hasSideEffects: true,
asm: riscv.ADIVU,
reg: regInfo{
inputs: []inputInfo{
{0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
@ -79402,9 +79444,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVW",
argLen: 2,
asm: riscv.ADIVW,
name: "DIVW",
argLen: 2,
hasSideEffects: true,
asm: riscv.ADIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
@ -79416,9 +79459,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVUW",
argLen: 2,
asm: riscv.ADIVUW,
name: "DIVUW",
argLen: 2,
hasSideEffects: true,
asm: riscv.ADIVUW,
reg: regInfo{
inputs: []inputInfo{
{0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
@ -79430,9 +79474,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "REM",
argLen: 2,
asm: riscv.AREM,
name: "REM",
argLen: 2,
hasSideEffects: true,
asm: riscv.AREM,
reg: regInfo{
inputs: []inputInfo{
{0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
@ -79444,9 +79489,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "REMU",
argLen: 2,
asm: riscv.AREMU,
name: "REMU",
argLen: 2,
hasSideEffects: true,
asm: riscv.AREMU,
reg: regInfo{
inputs: []inputInfo{
{0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
@ -79458,9 +79504,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "REMW",
argLen: 2,
asm: riscv.AREMW,
name: "REMW",
argLen: 2,
hasSideEffects: true,
asm: riscv.AREMW,
reg: regInfo{
inputs: []inputInfo{
{0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
@ -79472,9 +79519,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "REMUW",
argLen: 2,
asm: riscv.AREMUW,
name: "REMUW",
argLen: 2,
hasSideEffects: true,
asm: riscv.AREMUW,
reg: regInfo{
inputs: []inputInfo{
{0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
@ -82599,11 +82647,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVD",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
asm: s390x.ADIVD,
name: "DIVD",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
hasSideEffects: true,
asm: s390x.ADIVD,
reg: regInfo{
inputs: []inputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
@ -82616,11 +82665,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVW",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
asm: s390x.ADIVW,
name: "DIVW",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
hasSideEffects: true,
asm: s390x.ADIVW,
reg: regInfo{
inputs: []inputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
@ -82633,11 +82683,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVDU",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
asm: s390x.ADIVDU,
name: "DIVDU",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
hasSideEffects: true,
asm: s390x.ADIVDU,
reg: regInfo{
inputs: []inputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
@ -82650,11 +82701,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "DIVWU",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
asm: s390x.ADIVWU,
name: "DIVWU",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
hasSideEffects: true,
asm: s390x.ADIVWU,
reg: regInfo{
inputs: []inputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
@ -82667,11 +82719,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODD",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
asm: s390x.AMODD,
name: "MODD",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
hasSideEffects: true,
asm: s390x.AMODD,
reg: regInfo{
inputs: []inputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
@ -82684,11 +82737,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODW",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
asm: s390x.AMODW,
name: "MODW",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
hasSideEffects: true,
asm: s390x.AMODW,
reg: regInfo{
inputs: []inputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
@ -82701,11 +82755,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODDU",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
asm: s390x.AMODDU,
name: "MODDU",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
hasSideEffects: true,
asm: s390x.AMODDU,
reg: regInfo{
inputs: []inputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
@ -82718,11 +82773,12 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "MODWU",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
asm: s390x.AMODWU,
name: "MODWU",
argLen: 2,
resultInArg0: true,
clobberFlags: true,
hasSideEffects: true,
asm: s390x.AMODWU,
reg: regInfo{
inputs: []inputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
@ -86104,9 +86160,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "I64DivS",
argLen: 2,
asm: wasm.AI64DivS,
name: "I64DivS",
argLen: 2,
hasSideEffects: true,
asm: wasm.AI64DivS,
reg: regInfo{
inputs: []inputInfo{
{0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP
@ -86118,9 +86175,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "I64DivU",
argLen: 2,
asm: wasm.AI64DivU,
name: "I64DivU",
argLen: 2,
hasSideEffects: true,
asm: wasm.AI64DivU,
reg: regInfo{
inputs: []inputInfo{
{0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP
@ -86132,9 +86190,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "I64RemS",
argLen: 2,
asm: wasm.AI64RemS,
name: "I64RemS",
argLen: 2,
hasSideEffects: true,
asm: wasm.AI64RemS,
reg: regInfo{
inputs: []inputInfo{
{0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP
@ -86146,9 +86205,10 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "I64RemU",
argLen: 2,
asm: wasm.AI64RemU,
name: "I64RemU",
argLen: 2,
hasSideEffects: true,
asm: wasm.AI64RemU,
reg: regInfo{
inputs: []inputInfo{
{0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP

View file

@ -0,0 +1,27 @@
// run
// Copyright 2026 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.
package main
func f(x int) int {
if x == 1 {
return 7
}
return 7 / (x - 1)
}
//go:noinline
func g(x int) int {
r := 0
for range 5 {
r += f(x)
}
return r
}
func main() {
g(1)
}