ldc icon indicating copy to clipboard operation
ldc copied to clipboard

'Instruction does not dominate all uses' wrt. ternary expressions using array literals

Open kinke opened this issue 1 year ago • 1 comments

struct S {
    ~this() {}
}

int foo(S[] ss...) { return 0; }

void bar(bool a) {
    const r = a ? foo(S()) : foo(S());
}

The frontend lowers the ternary to (a) ? foo([(S())][]) : foo([(S())][]).

kinke avatar Jan 29 '24 18:01 kinke

This is probably going to be tricky to solve. The problem is that we have two S[1] static array allocas for the implicit array literals, one for each branch, but the compiler generates temporaries for the S elements, and those have a custom dtor expression, so that they are only destructed if that branch was taken (i.e., the first S temporary gets a a && tmp1.~this() edtor, the 2nd one a a || tmp2.~this()).

What we do is emplace the element temporaries into the static array directly. The lvalues of the temporaries are thus GEPs into the static array allocas, not allocas directly (which would definitely dominate all uses). And those GEPs are created in the respective branches only, so don't dominate all uses in the cleanups (even though the dtor call would be disabled anyway if that branch wasn't taken).

kinke avatar Jan 30 '24 11:01 kinke