(GetCallerSP ...) => (LoweredGetCallerSP ...)
(GetCallerPC ...) => (LoweredGetCallerPC ...)
-(If cond yes no) => (NE (MOVBUreg <typ.UInt64> cond) yes no)
+(If cond yes no) => (NEZ (MOVBUreg <typ.UInt64> cond) yes no)
(MOVBUreg x:((SGT|SGTU) _ _)) => x
(MOVBUreg x:(XOR (MOVVconst [1]) ((SGT|SGTU) _ _))) => x
// Optimizations
// Absorb boolean tests into block
-(NE (FPFlagTrue cmp) yes no) => (FPT cmp yes no)
-(NE (FPFlagFalse cmp) yes no) => (FPF cmp yes no)
-(EQ (FPFlagTrue cmp) yes no) => (FPF cmp yes no)
-(EQ (FPFlagFalse cmp) yes no) => (FPT cmp yes no)
-(NE (XORconst [1] cmp:(SGT _ _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTU _ _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTconst _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTUconst _)) yes no) => (EQ cmp yes no)
-(EQ (XORconst [1] cmp:(SGT _ _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTU _ _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTconst _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTUconst _)) yes no) => (NE cmp yes no)
-(NE (SGTUconst [1] x) yes no) => (EQ x yes no)
-(EQ (SGTUconst [1] x) yes no) => (NE x yes no)
-(NE (SGTU x (MOVVconst [0])) yes no) => (NE x yes no)
-(EQ (SGTU x (MOVVconst [0])) yes no) => (EQ x yes no)
-(NE (SGTconst [0] x) yes no) => (LTZ x yes no)
-(EQ (SGTconst [0] x) yes no) => (GEZ x yes no)
-(NE (SGT x (MOVVconst [0])) yes no) => (GTZ x yes no)
-(EQ (SGT x (MOVVconst [0])) yes no) => (LEZ x yes no)
-
-(EQ (SGTU (MOVVconst [c]) y) yes no) && c >= -2048 && c <= 2047 => (EQ (SGTUconst [c] y) yes no)
-(NE (SGTU (MOVVconst [c]) y) yes no) && c >= -2048 && c <= 2047 => (NE (SGTUconst [c] y) yes no)
-(EQ (SUBV x y) yes no) => (BEQ x y yes no)
-(NE (SUBV x y) yes no) => (BNE x y yes no)
-(EQ (SGT x y) yes no) => (BGE y x yes no)
-(NE (SGT x y) yes no) => (BLT y x yes no)
-(EQ (SGTU x y) yes no) => (BGEU y x yes no)
-(NE (SGTU x y) yes no) => (BLTU y x yes no)
+(NEZ (FPFlagTrue cmp) yes no) => (FPT cmp yes no)
+(NEZ (FPFlagFalse cmp) yes no) => (FPF cmp yes no)
+(EQZ (FPFlagTrue cmp) yes no) => (FPF cmp yes no)
+(EQZ (FPFlagFalse cmp) yes no) => (FPT cmp yes no)
+(NEZ (XORconst [1] cmp:(SGT _ _)) yes no) => (EQZ cmp yes no)
+(NEZ (XORconst [1] cmp:(SGTU _ _)) yes no) => (EQZ cmp yes no)
+(NEZ (XORconst [1] cmp:(SGTconst _)) yes no) => (EQZ cmp yes no)
+(NEZ (XORconst [1] cmp:(SGTUconst _)) yes no) => (EQZ cmp yes no)
+(EQZ (XORconst [1] cmp:(SGT _ _)) yes no) => (NEZ cmp yes no)
+(EQZ (XORconst [1] cmp:(SGTU _ _)) yes no) => (NEZ cmp yes no)
+(EQZ (XORconst [1] cmp:(SGTconst _)) yes no) => (NEZ cmp yes no)
+(EQZ (XORconst [1] cmp:(SGTUconst _)) yes no) => (NEZ cmp yes no)
+(NEZ (SGTUconst [1] x) yes no) => (EQZ x yes no)
+(EQZ (SGTUconst [1] x) yes no) => (NEZ x yes no)
+(NEZ (SGTU x (MOVVconst [0])) yes no) => (NEZ x yes no)
+(EQZ (SGTU x (MOVVconst [0])) yes no) => (EQZ x yes no)
+(NEZ (SGTconst [0] x) yes no) => (LTZ x yes no)
+(EQZ (SGTconst [0] x) yes no) => (GEZ x yes no)
+(NEZ (SGT x (MOVVconst [0])) yes no) => (GTZ x yes no)
+(EQZ (SGT x (MOVVconst [0])) yes no) => (LEZ x yes no)
+
+// Convert EQZ/NEZ into more optimal branch conditions.
+(EQZ (SGTU (MOVVconst [c]) y) yes no) && c >= -2048 && c <= 2047 => (EQZ (SGTUconst [c] y) yes no)
+(NEZ (SGTU (MOVVconst [c]) y) yes no) && c >= -2048 && c <= 2047 => (NEZ (SGTUconst [c] y) yes no)
+(EQZ (SUBV x y) yes no) => (BEQ x y yes no)
+(NEZ (SUBV x y) yes no) => (BNE x y yes no)
+(EQZ (SGT x y) yes no) => (BGE y x yes no)
+(NEZ (SGT x y) yes no) => (BLT y x yes no)
+(EQZ (SGTU x y) yes no) => (BGEU y x yes no)
+(NEZ (SGTU x y) yes no) => (BLTU y x yes no)
+(EQZ (SGTconst [c] y) yes no) => (BGE y (MOVVconst [c]) yes no)
+(NEZ (SGTconst [c] y) yes no) => (BLT y (MOVVconst [c]) yes no)
+(EQZ (SGTUconst [c] y) yes no) => (BGEU y (MOVVconst [c]) yes no)
+(NEZ (SGTUconst [c] y) yes no) => (BLTU y (MOVVconst [c]) yes no)
// absorb constants into branches
-(EQ (MOVVconst [0]) yes no) => (First yes no)
-(EQ (MOVVconst [c]) yes no) && c != 0 => (First no yes)
-(NE (MOVVconst [0]) yes no) => (First no yes)
-(NE (MOVVconst [c]) yes no) && c != 0 => (First yes no)
+(EQZ (MOVVconst [0]) yes no) => (First yes no)
+(EQZ (MOVVconst [c]) yes no) && c != 0 => (First no yes)
+(NEZ (MOVVconst [0]) yes no) => (First no yes)
+(NEZ (MOVVconst [c]) yes no) && c != 0 => (First yes no)
(LTZ (MOVVconst [c]) yes no) && c < 0 => (First yes no)
(LTZ (MOVVconst [c]) yes no) && c >= 0 => (First no yes)
(LEZ (MOVVconst [c]) yes no) && c <= 0 => (First yes no)
func rewriteBlockLOONG64(b *Block) bool {
typ := &b.Func.Config.Types
switch b.Kind {
- case BlockLOONG64EQ:
- // match: (EQ (FPFlagTrue cmp) yes no)
+ case BlockLOONG64EQZ:
+ // match: (EQZ (FPFlagTrue cmp) yes no)
// result: (FPF cmp yes no)
for b.Controls[0].Op == OpLOONG64FPFlagTrue {
v_0 := b.Controls[0]
b.resetWithControl(BlockLOONG64FPF, cmp)
return true
}
- // match: (EQ (FPFlagFalse cmp) yes no)
+ // match: (EQZ (FPFlagFalse cmp) yes no)
// result: (FPT cmp yes no)
for b.Controls[0].Op == OpLOONG64FPFlagFalse {
v_0 := b.Controls[0]
b.resetWithControl(BlockLOONG64FPT, cmp)
return true
}
- // match: (EQ (XORconst [1] cmp:(SGT _ _)) yes no)
- // result: (NE cmp yes no)
+ // match: (EQZ (XORconst [1] cmp:(SGT _ _)) yes no)
+ // result: (NEZ cmp yes no)
for b.Controls[0].Op == OpLOONG64XORconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
if cmp.Op != OpLOONG64SGT {
break
}
- b.resetWithControl(BlockLOONG64NE, cmp)
+ b.resetWithControl(BlockLOONG64NEZ, cmp)
return true
}
- // match: (EQ (XORconst [1] cmp:(SGTU _ _)) yes no)
- // result: (NE cmp yes no)
+ // match: (EQZ (XORconst [1] cmp:(SGTU _ _)) yes no)
+ // result: (NEZ cmp yes no)
for b.Controls[0].Op == OpLOONG64XORconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
if cmp.Op != OpLOONG64SGTU {
break
}
- b.resetWithControl(BlockLOONG64NE, cmp)
+ b.resetWithControl(BlockLOONG64NEZ, cmp)
return true
}
- // match: (EQ (XORconst [1] cmp:(SGTconst _)) yes no)
- // result: (NE cmp yes no)
+ // match: (EQZ (XORconst [1] cmp:(SGTconst _)) yes no)
+ // result: (NEZ cmp yes no)
for b.Controls[0].Op == OpLOONG64XORconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
if cmp.Op != OpLOONG64SGTconst {
break
}
- b.resetWithControl(BlockLOONG64NE, cmp)
+ b.resetWithControl(BlockLOONG64NEZ, cmp)
return true
}
- // match: (EQ (XORconst [1] cmp:(SGTUconst _)) yes no)
- // result: (NE cmp yes no)
+ // match: (EQZ (XORconst [1] cmp:(SGTUconst _)) yes no)
+ // result: (NEZ cmp yes no)
for b.Controls[0].Op == OpLOONG64XORconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
if cmp.Op != OpLOONG64SGTUconst {
break
}
- b.resetWithControl(BlockLOONG64NE, cmp)
+ b.resetWithControl(BlockLOONG64NEZ, cmp)
return true
}
- // match: (EQ (SGTUconst [1] x) yes no)
- // result: (NE x yes no)
+ // match: (EQZ (SGTUconst [1] x) yes no)
+ // result: (NEZ x yes no)
for b.Controls[0].Op == OpLOONG64SGTUconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
- b.resetWithControl(BlockLOONG64NE, x)
+ b.resetWithControl(BlockLOONG64NEZ, x)
return true
}
- // match: (EQ (SGTU x (MOVVconst [0])) yes no)
- // result: (EQ x yes no)
+ // match: (EQZ (SGTU x (MOVVconst [0])) yes no)
+ // result: (EQZ x yes no)
for b.Controls[0].Op == OpLOONG64SGTU {
v_0 := b.Controls[0]
_ = v_0.Args[1]
if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 {
break
}
- b.resetWithControl(BlockLOONG64EQ, x)
+ b.resetWithControl(BlockLOONG64EQZ, x)
return true
}
- // match: (EQ (SGTconst [0] x) yes no)
+ // match: (EQZ (SGTconst [0] x) yes no)
// result: (GEZ x yes no)
for b.Controls[0].Op == OpLOONG64SGTconst {
v_0 := b.Controls[0]
b.resetWithControl(BlockLOONG64GEZ, x)
return true
}
- // match: (EQ (SGT x (MOVVconst [0])) yes no)
+ // match: (EQZ (SGT x (MOVVconst [0])) yes no)
// result: (LEZ x yes no)
for b.Controls[0].Op == OpLOONG64SGT {
v_0 := b.Controls[0]
b.resetWithControl(BlockLOONG64LEZ, x)
return true
}
- // match: (EQ (SGTU (MOVVconst [c]) y) yes no)
+ // match: (EQZ (SGTU (MOVVconst [c]) y) yes no)
// cond: c >= -2048 && c <= 2047
- // result: (EQ (SGTUconst [c] y) yes no)
+ // result: (EQZ (SGTUconst [c] y) yes no)
for b.Controls[0].Op == OpLOONG64SGTU {
v_0 := b.Controls[0]
y := v_0.Args[1]
v0 := b.NewValue0(v_0.Pos, OpLOONG64SGTUconst, typ.Bool)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
- b.resetWithControl(BlockLOONG64EQ, v0)
+ b.resetWithControl(BlockLOONG64EQZ, v0)
return true
}
- // match: (EQ (SUBV x y) yes no)
+ // match: (EQZ (SUBV x y) yes no)
// result: (BEQ x y yes no)
for b.Controls[0].Op == OpLOONG64SUBV {
v_0 := b.Controls[0]
b.resetWithControl2(BlockLOONG64BEQ, x, y)
return true
}
- // match: (EQ (SGT x y) yes no)
+ // match: (EQZ (SGT x y) yes no)
// result: (BGE y x yes no)
for b.Controls[0].Op == OpLOONG64SGT {
v_0 := b.Controls[0]
b.resetWithControl2(BlockLOONG64BGE, y, x)
return true
}
- // match: (EQ (SGTU x y) yes no)
+ // match: (EQZ (SGTU x y) yes no)
// result: (BGEU y x yes no)
for b.Controls[0].Op == OpLOONG64SGTU {
v_0 := b.Controls[0]
b.resetWithControl2(BlockLOONG64BGEU, y, x)
return true
}
- // match: (EQ (MOVVconst [0]) yes no)
+ // match: (EQZ (SGTconst [c] y) yes no)
+ // result: (BGE y (MOVVconst [c]) yes no)
+ for b.Controls[0].Op == OpLOONG64SGTconst {
+ v_0 := b.Controls[0]
+ c := auxIntToInt64(v_0.AuxInt)
+ y := v_0.Args[0]
+ v0 := b.NewValue0(b.Pos, OpLOONG64MOVVconst, typ.UInt64)
+ v0.AuxInt = int64ToAuxInt(c)
+ b.resetWithControl2(BlockLOONG64BGE, y, v0)
+ return true
+ }
+ // match: (EQZ (SGTUconst [c] y) yes no)
+ // result: (BGEU y (MOVVconst [c]) yes no)
+ for b.Controls[0].Op == OpLOONG64SGTUconst {
+ v_0 := b.Controls[0]
+ c := auxIntToInt64(v_0.AuxInt)
+ y := v_0.Args[0]
+ v0 := b.NewValue0(b.Pos, OpLOONG64MOVVconst, typ.UInt64)
+ v0.AuxInt = int64ToAuxInt(c)
+ b.resetWithControl2(BlockLOONG64BGEU, y, v0)
+ return true
+ }
+ // match: (EQZ (MOVVconst [0]) yes no)
// result: (First yes no)
for b.Controls[0].Op == OpLOONG64MOVVconst {
v_0 := b.Controls[0]
b.Reset(BlockFirst)
return true
}
- // match: (EQ (MOVVconst [c]) yes no)
+ // match: (EQZ (MOVVconst [c]) yes no)
// cond: c != 0
// result: (First no yes)
for b.Controls[0].Op == OpLOONG64MOVVconst {
}
case BlockIf:
// match: (If cond yes no)
- // result: (NE (MOVBUreg <typ.UInt64> cond) yes no)
+ // result: (NEZ (MOVBUreg <typ.UInt64> cond) yes no)
for {
cond := b.Controls[0]
v0 := b.NewValue0(cond.Pos, OpLOONG64MOVBUreg, typ.UInt64)
v0.AddArg(cond)
- b.resetWithControl(BlockLOONG64NE, v0)
+ b.resetWithControl(BlockLOONG64NEZ, v0)
return true
}
case BlockLOONG64LEZ:
b.swapSuccessors()
return true
}
- case BlockLOONG64NE:
- // match: (NE (FPFlagTrue cmp) yes no)
+ case BlockLOONG64NEZ:
+ // match: (NEZ (FPFlagTrue cmp) yes no)
// result: (FPT cmp yes no)
for b.Controls[0].Op == OpLOONG64FPFlagTrue {
v_0 := b.Controls[0]
b.resetWithControl(BlockLOONG64FPT, cmp)
return true
}
- // match: (NE (FPFlagFalse cmp) yes no)
+ // match: (NEZ (FPFlagFalse cmp) yes no)
// result: (FPF cmp yes no)
for b.Controls[0].Op == OpLOONG64FPFlagFalse {
v_0 := b.Controls[0]
b.resetWithControl(BlockLOONG64FPF, cmp)
return true
}
- // match: (NE (XORconst [1] cmp:(SGT _ _)) yes no)
- // result: (EQ cmp yes no)
+ // match: (NEZ (XORconst [1] cmp:(SGT _ _)) yes no)
+ // result: (EQZ cmp yes no)
for b.Controls[0].Op == OpLOONG64XORconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
if cmp.Op != OpLOONG64SGT {
break
}
- b.resetWithControl(BlockLOONG64EQ, cmp)
+ b.resetWithControl(BlockLOONG64EQZ, cmp)
return true
}
- // match: (NE (XORconst [1] cmp:(SGTU _ _)) yes no)
- // result: (EQ cmp yes no)
+ // match: (NEZ (XORconst [1] cmp:(SGTU _ _)) yes no)
+ // result: (EQZ cmp yes no)
for b.Controls[0].Op == OpLOONG64XORconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
if cmp.Op != OpLOONG64SGTU {
break
}
- b.resetWithControl(BlockLOONG64EQ, cmp)
+ b.resetWithControl(BlockLOONG64EQZ, cmp)
return true
}
- // match: (NE (XORconst [1] cmp:(SGTconst _)) yes no)
- // result: (EQ cmp yes no)
+ // match: (NEZ (XORconst [1] cmp:(SGTconst _)) yes no)
+ // result: (EQZ cmp yes no)
for b.Controls[0].Op == OpLOONG64XORconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
if cmp.Op != OpLOONG64SGTconst {
break
}
- b.resetWithControl(BlockLOONG64EQ, cmp)
+ b.resetWithControl(BlockLOONG64EQZ, cmp)
return true
}
- // match: (NE (XORconst [1] cmp:(SGTUconst _)) yes no)
- // result: (EQ cmp yes no)
+ // match: (NEZ (XORconst [1] cmp:(SGTUconst _)) yes no)
+ // result: (EQZ cmp yes no)
for b.Controls[0].Op == OpLOONG64XORconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
if cmp.Op != OpLOONG64SGTUconst {
break
}
- b.resetWithControl(BlockLOONG64EQ, cmp)
+ b.resetWithControl(BlockLOONG64EQZ, cmp)
return true
}
- // match: (NE (SGTUconst [1] x) yes no)
- // result: (EQ x yes no)
+ // match: (NEZ (SGTUconst [1] x) yes no)
+ // result: (EQZ x yes no)
for b.Controls[0].Op == OpLOONG64SGTUconst {
v_0 := b.Controls[0]
if auxIntToInt64(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
- b.resetWithControl(BlockLOONG64EQ, x)
+ b.resetWithControl(BlockLOONG64EQZ, x)
return true
}
- // match: (NE (SGTU x (MOVVconst [0])) yes no)
- // result: (NE x yes no)
+ // match: (NEZ (SGTU x (MOVVconst [0])) yes no)
+ // result: (NEZ x yes no)
for b.Controls[0].Op == OpLOONG64SGTU {
v_0 := b.Controls[0]
_ = v_0.Args[1]
if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 {
break
}
- b.resetWithControl(BlockLOONG64NE, x)
+ b.resetWithControl(BlockLOONG64NEZ, x)
return true
}
- // match: (NE (SGTconst [0] x) yes no)
+ // match: (NEZ (SGTconst [0] x) yes no)
// result: (LTZ x yes no)
for b.Controls[0].Op == OpLOONG64SGTconst {
v_0 := b.Controls[0]
b.resetWithControl(BlockLOONG64LTZ, x)
return true
}
- // match: (NE (SGT x (MOVVconst [0])) yes no)
+ // match: (NEZ (SGT x (MOVVconst [0])) yes no)
// result: (GTZ x yes no)
for b.Controls[0].Op == OpLOONG64SGT {
v_0 := b.Controls[0]
b.resetWithControl(BlockLOONG64GTZ, x)
return true
}
- // match: (NE (SGTU (MOVVconst [c]) y) yes no)
+ // match: (NEZ (SGTU (MOVVconst [c]) y) yes no)
// cond: c >= -2048 && c <= 2047
- // result: (NE (SGTUconst [c] y) yes no)
+ // result: (NEZ (SGTUconst [c] y) yes no)
for b.Controls[0].Op == OpLOONG64SGTU {
v_0 := b.Controls[0]
y := v_0.Args[1]
v0 := b.NewValue0(v_0.Pos, OpLOONG64SGTUconst, typ.Bool)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
- b.resetWithControl(BlockLOONG64NE, v0)
+ b.resetWithControl(BlockLOONG64NEZ, v0)
return true
}
- // match: (NE (SUBV x y) yes no)
+ // match: (NEZ (SUBV x y) yes no)
// result: (BNE x y yes no)
for b.Controls[0].Op == OpLOONG64SUBV {
v_0 := b.Controls[0]
b.resetWithControl2(BlockLOONG64BNE, x, y)
return true
}
- // match: (NE (SGT x y) yes no)
+ // match: (NEZ (SGT x y) yes no)
// result: (BLT y x yes no)
for b.Controls[0].Op == OpLOONG64SGT {
v_0 := b.Controls[0]
b.resetWithControl2(BlockLOONG64BLT, y, x)
return true
}
- // match: (NE (SGTU x y) yes no)
+ // match: (NEZ (SGTU x y) yes no)
// result: (BLTU y x yes no)
for b.Controls[0].Op == OpLOONG64SGTU {
v_0 := b.Controls[0]
b.resetWithControl2(BlockLOONG64BLTU, y, x)
return true
}
- // match: (NE (MOVVconst [0]) yes no)
+ // match: (NEZ (SGTconst [c] y) yes no)
+ // result: (BLT y (MOVVconst [c]) yes no)
+ for b.Controls[0].Op == OpLOONG64SGTconst {
+ v_0 := b.Controls[0]
+ c := auxIntToInt64(v_0.AuxInt)
+ y := v_0.Args[0]
+ v0 := b.NewValue0(b.Pos, OpLOONG64MOVVconst, typ.UInt64)
+ v0.AuxInt = int64ToAuxInt(c)
+ b.resetWithControl2(BlockLOONG64BLT, y, v0)
+ return true
+ }
+ // match: (NEZ (SGTUconst [c] y) yes no)
+ // result: (BLTU y (MOVVconst [c]) yes no)
+ for b.Controls[0].Op == OpLOONG64SGTUconst {
+ v_0 := b.Controls[0]
+ c := auxIntToInt64(v_0.AuxInt)
+ y := v_0.Args[0]
+ v0 := b.NewValue0(b.Pos, OpLOONG64MOVVconst, typ.UInt64)
+ v0.AuxInt = int64ToAuxInt(c)
+ b.resetWithControl2(BlockLOONG64BLTU, y, v0)
+ return true
+ }
+ // match: (NEZ (MOVVconst [0]) yes no)
// result: (First no yes)
for b.Controls[0].Op == OpLOONG64MOVVconst {
v_0 := b.Controls[0]
b.swapSuccessors()
return true
}
- // match: (NE (MOVVconst [c]) yes no)
+ // match: (NEZ (MOVVconst [c]) yes no)
// cond: c != 0
// result: (First yes no)
for b.Controls[0].Op == OpLOONG64MOVVconst {