cmd/compile: optimize bool to int conversion
cmd/compile: optimize bool to int conversion

This CL teaches SSA to recognize code of the form

// b is a boolean value, i is an int of some flavor
if b {
	i = 1
} else {
	i = 0
}

and use b's underlying 0/1 representation for i
instead of generating jumps.

Unfortunately, it does not work on the obvious code:

func bool2int(b bool) int {
	if b {
		return 1
	}
	return 0
}

This is left for future work.
Note that the existing phiopt optimizations also don't work for:

func neg(b bool) bool {
	if b {
		return false
	}
	return true
}

In the meantime, runtime authors and the like can use:

func bool2int(b bool) int {
	var i int
	if b {
		i = 1
	} else {
		i = 0
	}
	return i
}

This compiles to:

"".bool2int t=1 size=16 args=0x10 locals=0x0
	0x0000 00000 (x.go:25)	TEXT	"".bool2int(SB), $0-16
	0x0000 00000 (x.go:25)	FUNCDATA	$0, gclocals·23e8278e2b69a3a75fa59b23c49ed6ad(SB)
	0x0000 00000 (x.go:25)	FUNCDATA	$1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
	0x0000 00000 (x.go:32)	MOVBLZX	"".b+8(FP), AX
	0x0005 00005 (x.go:32)	MOVBQZX	AL, AX
	0x0008 00008 (x.go:32)	MOVQ	AX, "".~r1+16(FP)
	0x000d 00013 (x.go:32)	RET

The extraneous MOVBQZX is #15300.

This optimization also helps range and slice.
The compiler must protect against pointers pointing
to the end of a slice/string. It does this by increasing
a pointer by either 0 or 1 * elemsize, based on a condition.
This CL optimizes away a jump in that code.

This CL triggers 382 times while compiling the standard library.

Updating code to utilize this optimization is left for future CLs.

Updates #6011

Change-Id: Ia7c1185f8aa223c543f91a3cd6d4a2a09c691c70
Reviewed-on: https://go-review.googlesource.com/22711
Run-TryBot: Josh Bleecher Snyder <cdc248cc4d32e4fbfe04e45228163bcecd48a0b9@gmail.com>
TryBot-Result: Gobot Gobot <66cb808b70d30c07676d5e946fee83fd561249e5@golang.org>
Reviewed-by: Keith Randall <8c99c3a9284e493be632950b84cd789d08ed3e9d@golang.org>

derekmarcotte/go,josharian/go,josharian/go,vsekhar/elastic-go,golang/go,derekmarcotte/go,josharian/go,vsekhar/elastic-go,vsekhar/elastic-go,codestation/go,suncycheng/go,vsekhar/elastic-go,Cofyc/go,momchil-velikov/go,vsekhar/elastic-go,linux-on-ibm-z/go,momchil-velikov/go,derekmarcotte/go,codestation/go,ImJasonH/go,linux-on-ibm-z/go,josharian/go,codestation/go,nawawi/go,josharian/go,golang/go,cloudflare/go,josharian/go,josharian/go,linux-on-ibm-z/go,codestation/go,momchil-velikov/go,codestation/go,momchil-velikov/go,derekmarcotte/go,cloudflare/go,ImJasonH/go,CAFxX/go,goodlang/good,akutz/go,akutz/go,goodlang/good,goodlang/good,polyverse-security/go,derekmarcotte/go,golang/go,Cofyc/go,nawawi/go,derekmarcotte/go,momchil-velikov/go,christopher-henderson/Go,polyverse-security/go,goodlang/good,cloudflare/go,linux-on-ibm-z/go,momchil-velikov/go,CAFxX/go,nawawi/go,polyverse-security/go,ImJasonH/go,vsekhar/elastic-go,CAFxX/go,akutz/go,CAFxX/go,vsekhar/elastic-go,cloudflare/go,suncycheng/go,linux-on-ibm-z/go,nawawi/go,nawawi/go,nawawi/go,vsekhar/elastic-go,suncycheng/go,momchil-velikov/go,golang/go,CAFxX/go,suncycheng/go,golang/go,suncycheng/go,ImJasonH/go,cloudflare/go,linux-on-ibm-z/go,linux-on-ibm-z/go,Cofyc/go,golang/go,akutz/go,polyverse-security/go,Cofyc/go,akutz/go,cloudflare/go,Cofyc/go,codestation/go,suncycheng/go,linux-on-ibm-z/go,Cofyc/go,suncycheng/go,cloudflare/go,codestation/go,CAFxX/go,ImJasonH/go,Cofyc/go,goodlang/good,akutz/go,ImJasonH/go,akutz/go,Cofyc/go,goodlang/good,goodlang/good,goodlang/good,momchil-velikov/go,ImJasonH/go,suncycheng/go,josharian/go,codestation/go,nawawi/go,polyverse-security/go,cloudflare/go,polyverse-security/go,golang/go,derekmarcotte/go,CAFxX/go,nawawi/go,polyverse-security/go,akutz/go,ImJasonH/go,CAFxX/go,polyverse-security/go,derekmarcotte/go,golang/go