Commit 98938189 authored by Keith Randall's avatar Keith Randall

cmd/compile: remove duplicate nilchecks

Mark nil check operations as faulting if their arg is zero.
This lets the late nilcheck pass remove duplicates.

Fixes #17242.

Change-Id: I4c9938d8a5a1e43edd85b4a66f0b34004860bcd9
Reviewed-on: https://go-review.googlesource.com/29952
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent ba94dd34
...@@ -439,7 +439,7 @@ func init() { ...@@ -439,7 +439,7 @@ func init() {
// use of DX (the closure pointer) // use of DX (the closure pointer)
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}},
//arg0=ptr,arg1=mem, returns void. Faults if ptr is nil. //arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true}, {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
// MOVLconvert converts between pointers and integers. // MOVLconvert converts between pointers and integers.
// We have a special op for this so as to not confuse GC // We have a special op for this so as to not confuse GC
......
...@@ -486,7 +486,7 @@ func init() { ...@@ -486,7 +486,7 @@ func init() {
// use of DX (the closure pointer) // use of DX (the closure pointer)
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}},
//arg0=ptr,arg1=mem, returns void. Faults if ptr is nil. //arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true}, {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
// MOVQconvert converts between pointers and integers. // MOVQconvert converts between pointers and integers.
// We have a special op for this so as to not confuse GC // We have a special op for this so as to not confuse GC
......
...@@ -325,7 +325,7 @@ func init() { ...@@ -325,7 +325,7 @@ func init() {
{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
// pseudo-ops // pseudo-ops
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true}, // panic if arg0 is nil. arg1=mem. {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem.
{name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise. {name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise.
{name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise. {name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise.
......
...@@ -381,7 +381,7 @@ func init() { ...@@ -381,7 +381,7 @@ func init() {
{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
// pseudo-ops // pseudo-ops
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true}, // panic if arg0 is nil. arg1=mem. {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem.
{name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise. {name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise.
{name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise. {name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise.
......
...@@ -336,7 +336,7 @@ func init() { ...@@ -336,7 +336,7 @@ func init() {
}, },
// pseudo-ops // pseudo-ops
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true}, // panic if arg0 is nil. arg1=mem. {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem.
{name: "FPFlagTrue", argLength: 1, reg: readflags}, // bool, true if FP flag is true {name: "FPFlagTrue", argLength: 1, reg: readflags}, // bool, true if FP flag is true
{name: "FPFlagFalse", argLength: 1, reg: readflags}, // bool, true if FP flag is false {name: "FPFlagFalse", argLength: 1, reg: readflags}, // bool, true if FP flag is false
......
...@@ -288,7 +288,7 @@ func init() { ...@@ -288,7 +288,7 @@ func init() {
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}},
//arg0=ptr,arg1=mem, returns void. Faults if ptr is nil. //arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true}, {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
// Convert pointer to integer, takes a memory operand for ordering. // Convert pointer to integer, takes a memory operand for ordering.
{name: "MOVDconvert", argLength: 2, reg: gp11, asm: "MOVD"}, {name: "MOVDconvert", argLength: 2, reg: gp11, asm: "MOVD"},
......
...@@ -370,7 +370,7 @@ func init() { ...@@ -370,7 +370,7 @@ func init() {
// use of R12 (the closure pointer) // use of R12 (the closure pointer)
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}},
// arg0=ptr,arg1=mem, returns void. Faults if ptr is nil. // arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true}, {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
// MOVDconvert converts between pointers and integers. // MOVDconvert converts between pointers and integers.
// We have a special op for this so as to not confuse GC // We have a special op for this so as to not confuse GC
......
...@@ -4023,10 +4023,11 @@ var opcodeTable = [...]opInfo{ ...@@ -4023,10 +4023,11 @@ var opcodeTable = [...]opInfo{
}, },
}, },
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
clobberFlags: true, clobberFlags: true,
nilCheck: true, nilCheck: true,
faultOnNilArg0: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 255}, // AX CX DX BX SP BP SI DI {0, 255}, // AX CX DX BX SP BP SI DI
...@@ -6992,10 +6993,11 @@ var opcodeTable = [...]opInfo{ ...@@ -6992,10 +6993,11 @@ var opcodeTable = [...]opInfo{
}, },
}, },
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
clobberFlags: true, clobberFlags: true,
nilCheck: true, nilCheck: true,
faultOnNilArg0: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 {0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
...@@ -10081,9 +10083,10 @@ var opcodeTable = [...]opInfo{ ...@@ -10081,9 +10083,10 @@ var opcodeTable = [...]opInfo{
}, },
}, },
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
nilCheck: true, nilCheck: true,
faultOnNilArg0: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12
...@@ -12200,9 +12203,10 @@ var opcodeTable = [...]opInfo{ ...@@ -12200,9 +12203,10 @@ var opcodeTable = [...]opInfo{
}, },
}, },
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
nilCheck: true, nilCheck: true,
faultOnNilArg0: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 268173311}, // 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 {0, 268173311}, // 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
...@@ -13817,9 +13821,10 @@ var opcodeTable = [...]opInfo{ ...@@ -13817,9 +13821,10 @@ var opcodeTable = [...]opInfo{
}, },
}, },
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
nilCheck: true, nilCheck: true,
faultOnNilArg0: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 100663294}, // 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 {0, 100663294}, // 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
...@@ -15195,10 +15200,11 @@ var opcodeTable = [...]opInfo{ ...@@ -15195,10 +15200,11 @@ var opcodeTable = [...]opInfo{
}, },
}, },
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
clobberFlags: true, clobberFlags: true,
nilCheck: true, nilCheck: true,
faultOnNilArg0: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ 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 {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
...@@ -17511,10 +17517,11 @@ var opcodeTable = [...]opInfo{ ...@@ -17511,10 +17517,11 @@ var opcodeTable = [...]opInfo{
}, },
}, },
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
clobberFlags: true, clobberFlags: true,
nilCheck: true, nilCheck: true,
faultOnNilArg0: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 37886}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP {0, 37886}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP
......
...@@ -233,3 +233,17 @@ func c1() { ...@@ -233,3 +233,17 @@ func c1() {
var x Struct var x Struct
func() { x.m() }() // ERROR "removed nil check" func() { x.m() }() // ERROR "removed nil check"
} }
type SS struct {
x byte
}
type TT struct {
SS
}
func f(t *TT) *byte {
// See issue 17242.
s := &t.SS // ERROR "removed nil check"
return &s.x // ERROR "generated nil check"
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment