Skip to content

Strange behaviour with loops [1.16 backport] #45192

@randall77

Description

@randall77

@randall77 requested issue #45175 to be considered for backport to the next 1.16 minor release.

Here's a simpler reproducer:

package main

//go:noinline
func f(c bool) int {
	b := true
	x := 0
	y := 1
	for b {
		b = false
		y = x
		x = 2
		if c {
			return 3
		}
	}
	return y
}

func main() {
	println(f(false))
}

This reproducer incorrectly prints 2.
It should print 0. And it does, with -gcflags=-d=ssa/short_circuit/off.
The problem is that during short circuit, we don't take into account that the arguments to a phi are from the previous iteration, not the current iteration. That confusion leads to assigning y the current iteration's value of x, not the previous iteration's value of x.

The bug looks like it started in 1.15.

In shortcircuit.go, we need to be a bit more choosy in replaceUses to not replace uses inside a phi, as we're replacing the current iteration's values, not those which are from the previous iteration. At least, something like that; it may not be quite so simple.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions