This is an archive of the discontinued LLVM Phabricator instance.

Propagate branchweight through phi values when ExpectedValue is unlikely in LowerExpectIntrinsic
ClosedPublic

Authored by LukeZhuang on Dec 19 2022, 12:04 PM.

Details

Reviewers
davidxl
Summary

Currently handlePhiDef does not take the probability operand of expect_with_probability into consideration.
When the probability is low, meaning the "expected value" is unlikely, we need to mark the branches from which the phi value is the same as "expected value" as unlikely.

The existing code treats __builtin_expect((a0==1)||(a1==1)||(a2==1), 1) and __builtin_expect_with_probability((a0==1)||(a1==1)||(a2==1), 1, 0) the same, when in fact they are very different: They both "expect" value 1, but the first says it is very likely and the second says it has probability 0, i.e. very unlikely.

An example of IR code we need to handle is:

b0:
  %c0 = icmp eq i8 %a0, 1
  br i1 %c0, label %b3, label %b1
  
b1:
  %c1 = icmp eq i8 %a1, 1
  br i1 %c1, label %b3, label %b2
  
b2:
  %c2 = icmp eq i8 %a2, 1
  br label %b3

b3:
  %cond0 = phi i1 [ true, %b0 ], [ true, %b1 ], [ %c2, %b2 ]
  %cond1 = extend %cond0 to i64
  %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond1, i64 1, double 0.0)

We should also annotate the BranchInst of b0 and b1 because we know that "true" is unlikely. The only path that does not result in an unlikely outcome is through b2.

This helps __builtin_expect(x, 0) and __builtin_expect_with_probability(x, 1, 0) have the same behavior. For reference, GCC does already behave consistently like this.

In addition, we also added an ImmArg attribute to the expect.with.probability intrinsic to disallow non-constant probability arguments.

This issue was introduced by https://reviews.llvm.org/D79830, which did not update handlePhiDef correctly for the expect.with.probability case.

Diff Detail

Event Timeline

LukeZhuang created this revision.Dec 19 2022, 12:04 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 19 2022, 12:04 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
LukeZhuang requested review of this revision.Dec 19 2022, 12:04 PM
davidxl added inline comments.Dec 20 2022, 11:14 PM
llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
137

This should probably be made more biased.

LukeZhuang added inline comments.Dec 21 2022, 9:00 AM
llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
137

Hi David, thanks for the comment! May I ask is "more biased" meant by a higher threshold of considering a branch likely/unlikely? Or could you give an example of which it ought to behave differently than this code(and why)? Thanks!

never mind. I misunderstood the usage of this variable. There is no need to adjust.

This revision is now accepted and ready to land.Dec 21 2022, 11:48 AM
LukeZhuang added a comment.EditedDec 21 2022, 1:06 PM

Hi David, thank you very much! Seems I do not have access to push to the repo, may I ask could you please help me do it? Here is the commit info:

Commit message title:
[LowerExpectIntrinsic] Propagate branch weights through phi values when ExpectedValue is unlikely in LowerExpectIntrinsic

Detailed info:
Update handlePhiDef to consider the probability argument in an expect.with.probability intrinsic when annotating BranchInsts.
In addition, we also disallow non-constant probability arguments in this intrinsic.

Differential Revsion: https://reviews.llvm.org/D140337

It might be better to ask for commit access. It is needed for potential follow-ups.

LukeZhuang marked an inline comment as done.Dec 22 2022, 10:51 AM

It might be better to ask for commit access. It is needed for potential follow-ups.

Got it, I have just asked for commit access. Thanks!

LukeZhuang closed this revision.Dec 22 2022, 2:46 PM