This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Prevent unnecessary sinks caused by the Freeze
AbandonedPublic

Authored by hyeongyukim on Jul 30 2021, 10:00 AM.

Details

Summary

The Freeze is added to Cond in fixing the miscomputation of loop unswitch(D106041).
However, more sinks are generated in Instcombine by Freeze that added in D106041.

Below is a situation where D106041 is not applied(bug exists in LU).
If D106041 is not applied, load(ptr) will not sink after InstCombine is performed.

  v = load(ptr)
  cond = icmp eq(v, 0)
  br body

body:
  br(cond, ..., ...)
=>
  v = load(ptr)
  br body

body:
  cond = icmp eq(v, 0)
  br(cond, ..., ...)

But when we add the Freeze to Cond(to fix LU), load(ptr) is sink to body block.
And this is not the intended situation.

  v = load(ptr)
  cond = icmp eq(v, 0)
  cond.fr = freeze(cond)
  br body

body:
  br(cond.fr, ..., ...)
=>
  br body

body:
  v = load(ptr)
  v.fr = freeze(v)
  cond = icmp eq(v, 0)
  br(cond, ..., ...)

Once this patch is applied, the load will not sink, but only Freeze and icmp will sink as below.

  v = load(ptr)
  cond = icmp eq(v, 0)
  cond.fr = freeze(cond)
  br body

body:
  br(cond.fr, ..., ...)
=>
  v = load(ptr)
  br body

body:
  v.fr = freeze(v)
  cond = icmp eq(v, 0)
  br(cond, ..., ...)

Diff Detail

Event Timeline

hyeongyukim created this revision.Jul 30 2021, 10:00 AM
hyeongyukim requested review of this revision.Jul 30 2021, 10:00 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 30 2021, 10:00 AM

I'm sorry, but TLDR.
We already sink everything successfully: https://godbolt.org/z/df73PEPf4
Why do we not want to sink the load in @test4.freeze,
or more generally, why do we not sink it in the first case?

I don't understand why we want/need to prevent sinking.

In the original code(code without freeze), load is not sinking.
And I thought I have to sink as few instructions as possible because the body block could run more than once.

However, I noticed that instructions would not sink if the body block could run more than once.
So... I think this patch is meaningless. Can I abandon this revision?

Yeah, i think there's already a profitability check there, so i don't see why we'd want this.
It could be interesting to enhance the sinking to handle multiple uses (see findCommonDominator() in SimplifyIndVar.cpp),
not sure what compile-time implications that would have.

As suggested, finding a common dominator and sinking the instruction to the location seems reasonable and worth trying.
It will help reduce the diff at line 3866~, I hope.
If DT is null, fallback to the old one use check?

As suggested, finding a common dominator and sinking the instruction to the location seems reasonable and worth trying.
It will help reduce the diff at line 3866~, I hope.
If DT is null, fallback to the old one use check?

DT can not be null here

hyeongyukim abandoned this revision.Jul 31 2021, 10:01 AM

Yeah, i think there's already a profitability check there, so i don't see why we'd want this.
It could be interesting to enhance the sinking to handle multiple uses (see findCommonDominator() in SimplifyIndVar.cpp),
not sure what compile-time implications that would have.

I am writing a new patch(D107226) related to your comment.
I agree that this patch is not profitable, so I'll close it!