Skip to content

[clang] [codegen] unexpected codegen when struct is returned from a function or when struct has specific field order #162031

@03F001

Description

@03F001

clang 21.1 x86-64 -O3
https://godbolt.org/z/3WY37brEY simplified case where f1 codegen is expected to match f2. Define FIX1 to make the codegen match, or define FIX2.

FIX1 changes the struct field order so that the bool does not occur as the last field.
FIX2 changes struct creation is returned from a function rather than constructed in the function f2.

Full code:

void act(unsigned);

// baseline
void f1(unsigned stop)
{
	auto i = 0;
	do {
		act(i);
		++i;
	} while ( i != stop );
}

struct Iter
{
#ifdef FIX1
	bool done = false;
	unsigned i = 0;
	unsigned stop;
#else
	unsigned i = 0;
	unsigned stop;
	bool done = false; // codegen can differ when last field
#endif

	explicit constexpr Iter(unsigned stop) noexcept
		: stop(stop) {}

	constexpr bool more() const noexcept { return !done; }

	constexpr unsigned front() const noexcept { return i; }

	constexpr void popFront() noexcept
	{
		++i;
		done = i == stop;
	}
};

// codegen can differ when Iter is returned from a function
constexpr Iter mkIter(unsigned stop) noexcept
{
	return Iter(stop);
}

// does not match f1
// define FIX1 to match f1
// define FIX2 to match f1
void f2(unsigned stop)
{
#ifdef FIX2
	auto r = Iter(stop);
#else
	auto r = mkIter(stop);
#endif
	for ( ; r.more(); r.popFront() ) {
		act(r.front());
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    clangClang issues not falling into any other category

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions