We noticed a regression in
llvm-test-suite/MicroBenchmarks/ImageProcessing/Interpolation that,
through bisection, appeared to be caused by D124252. Upon investigation,
the root cause appears to be the way D105392 propagates upwards freezes.
D124252 would freeze the cmp result, and loop unswitching would
otherwise happen identically. We'd then do instcombine. At this point,
we'd be presented with a few redundant definitions - see the %idx1 and
%idx2 in the added test. They'd have uses in the then and else
sides of the unswitched loop that, before D124252, would be recognized
as equivalent and optimized out (the test glosses over that and just
uses the mock_use function to make sure the values have a use).
D124252's introduction of the freeze kicked in the behavior introduced
by D105392. The problem is that the freeze would be always propagated up
right before the current freeze - which in our case would leave one of
the equivalent idx before the freeze and one after. The two would be
now different, and we lose the optimization opportunity. Here's what the
IR looked like post-instcombine, for the newly added test:
define i1 @func(i32 %0, i32 noundef %1) { %dr = lshr i32 %0, 2 %idx1 = zext i32 %dr to i64 %dr.fr = freeze i32 %dr %add = add i32 %dr.fr, 1 %cmp = icmp slt i32 %add, %1 %idx2 = zext i32 %dr.fr to i64 %v = call i1 @use(i64 %idx1, i64 %idx2) %ret = and i1 %v, %cmp ret i1 %ret }
Note how %idx1 and %idx2 are using, one the pre-freeze def of %dr
and one the post-freeze (i.e. %dr.fr).
This patch moves the freeze right after definition.
I *think* this is just the case when MaybePoisonOperand is a function parameter, so we should insert in the entry block - but want to first make sure the idea of the patch isn't missing something.