Repository: go
Issue: cmd/compile: should delete loops without side-effects
Labels: Performance,help wanted,NeedsInvestigation,compiler/runtime

As of `go1.24-cbdb3545ad`, none of the following loops get optimized away:

```
package main

func main() {
	for range 10 {
		// Just an empty loop
	}

	var x int
	for range 20 {
		// x never gets read after the loop
		x++
	}

	var y [30]int
	for i := range y {
		// The bounds check gets optimized out, turning this into an empty loop
		_ = y[i]
	}

	for range "13 characters" {
		// An empty loop that parses UTF-8
	}

	const debugFoo = false
	const debugBar = false
	for range 40 {
		// Loop body is dead and gets optimized out
		if debugFoo {
			println()
		}
		if debugBar {
			println()
		}
	}
}
```

```
main.main STEXT size=152 args=0x0 locals=0x20 funcid=0x0 align=0x0
	0x0000 00000 (...../foo.go:3)	TEXT	main.main(SB), ABIInternal, $32-0
	0x0000 00000 (...../foo.go:3)	CMPQ	SP, 16(R14)
	0x0004 00004 (...../foo.go:3)	PCDATA	$0, $-2
	0x0004 00004 (...../foo.go:3)	JLS	142
	0x000a 00010 (...../foo.go:3)	PCDATA	$0, $-1
	0x000a 00010 (...../foo.go:3)	PUSHQ	BP
	0x000b 00011 (...../foo.go:3)	MOVQ	SP, BP
	0x000e 00014 (...../foo.go:3)	SUBQ	$24, SP
	0x0012 00018 (...../foo.go:3)	FUNCDATA	$0, gclocals·M83szM6+gDKfH9vuf1h0yw==(SB)
	0x0012 00018 (...../foo.go:3)	FUNCDATA	$1, gclocals·M83szM6+gDKfH9vuf1h0yw==(SB)
	0x0012 00018 (...../foo.go:3)	XORL	AX, AX
	0x0014 00020 (...../foo.go:4)	JMP	25
	0x0016 00022 (...../foo.go:4)	INCQ	AX
	0x0019 00025 (...../foo.go:4)	CMPQ	AX, $10
	0x001d 00029 (...../foo.go:4)	JLT	22
	0x001f 00031 (...../foo.go:4)	XORL	AX, AX
	0x0021 00033 (...../foo.go:4)	JMP	38
	0x0023 00035 (...../foo.go:9)	INCQ	AX
	0x0026 00038 (...../foo.go:9)	CMPQ	AX, $20
	0x002a 00042 (...../foo.go:9)	JLT	35
	0x002c 00044 (...../foo.go:9)	XORL	AX, AX
	0x002e 00046 (...../foo.go:15)	JMP	51
	0x0030 00048 (...../foo.go:15)	INCQ	AX
	0x0033 00051 (...../foo.go:15)	CMPQ	AX, $30
	0x0037 00055 (...../foo.go:15)	JLT	48
	0x0039 00057 (...../foo.go:15)	XORL	AX, AX
	0x003b 00059 (...../foo.go:15)	JMP	64
	0x003d 00061 (...../foo.go:20)	MOVQ	SI, AX
	0x0040 00064 (...../foo.go:20)	CMPQ	AX, $13
	0x0044 00068 (...../foo.go:20)	JGE	123
	0x0046 00070 (...../foo.go:20)	LEAQ	go:string."13 characters"(SB), DX
	0x004d 00077 (...../foo.go:20)	MOVBLZX	(DX)(AX*1), SI
	0x0051 00081 (...../foo.go:20)	CMPL	SI, $128
	0x0057 00087 (...../foo.go:20)	JGE	95
	0x0059 00089 (...../foo.go:20)	LEAQ	1(AX), SI
	0x005d 00093 (...../foo.go:20)	JMP	61
	0x005f 00095 (...../foo.go:20)	MOVL	$13, BX
	0x0064 00100 (...../foo.go:20)	MOVQ	AX, CX
	0x0067 00103 (...../foo.go:20)	MOVQ	DX, AX
	0x006a 00106 (...../foo.go:20)	PCDATA	$1, $0
	0x006a 00106 (...../foo.go:20)	CALL	runtime.decoderune(SB)
	0x006f 00111 (...../foo.go:20)	LEAQ	go:string."13 characters"(SB), DX
	0x0076 00118 (...../foo.go:20)	MOVQ	BX, SI
	0x0079 00121 (...../foo.go:20)	JMP	61
	0x007b 00123 (...../foo.go:20)	XORL	AX, AX
	0x007d 00125 (...../foo.go:20)	JMP	130
	0x007f 00127 (...../foo.go:26)	INCQ	AX
	0x0082 00130 (...../foo.go:26)	CMPQ	AX, $40
	0x0086 00134 (...../foo.go:26)	JLT	127
	0x0088 00136 (...../foo.go:35)	ADDQ	$24, SP
	0x008c 00140 (...../foo.go:35)	POPQ	BP
	0x008d 00141 (...../foo.go:35)	RET
	0x008e 00142 (...../foo.go:35)	NOP
	0x008e 00142 (...../foo.go:3)	PCDATA	$1, $-1
	0x008e 00142 (...../foo.go:3)	PCDATA	$0, $-2
	0x008e 00142 (...../foo.go:3)	CALL	runtime.morestack_noctxt(SB)
	0x0093 00147 (...../foo.go:3)	PCDATA	$0, $-1
	0x0093 00147 (...../foo.go:3)	JMP	0
```