This is an archive of the discontinued LLVM Phabricator instance.

[ConstraintElim] Track and simplify conditions at use.
ClosedPublic

Authored by fhahn on Jun 23 2023, 1:02 PM.

Details

Summary

This patch updates ConstraintElimination to track uses of conditions in
the worklist. This allows simplifying conditions using the context that
holds directly at the condition, instead of where the condition is
defined.

This allows us to catch more cases in practice: there are multiple
code-size changes for CTMark while compile-time remains unchanged:
https://llvm-compile-time-tracker.com/compare.php?from=55d04119687ac4a9509717a4c310332921047375&to=6c8e15609386078cb34df7c3891fdb1c47c8f830&stat=size-total

This should help to simplify D151799.

Diff Detail

Event Timeline

fhahn created this revision.Jun 23 2023, 1:02 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 23 2023, 1:02 PM
fhahn requested review of this revision.Jun 23 2023, 1:02 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 23 2023, 1:02 PM
nikic added inline comments.Jun 23 2023, 1:45 PM
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
1064

Aren't we always working on a single Use now and could replace just that use?

fhahn marked an inline comment as done.Jun 23 2023, 2:18 PM
fhahn added inline comments.
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
1064

We could still replace multiple uses if there are other uses dominated by the current one. This way, we don't need to query the constraint system repeatedly if we already were able to prove it at a dominating use.

nikic added a comment.Jun 24 2023, 3:11 AM

Can you please add some tests with uses in phi nodes? I don't think the handling for those is correct. (Though more in the direction of missing some replacements that were previously done rather than doing invalid replacements.)

fhahn marked an inline comment as done.Jun 25 2023, 9:10 AM

Can you please add some tests with uses in phi nodes? I don't think the handling for those is correct. (Though more in the direction of missing some replacements that were previously done rather than doing invalid replacements.)

I added some tests in 0ddfb802e4ca. Is that what you had in mind? I think we shouldn't miss any of those, because the code should ensure that the uses in the context instruction (the user of the use we queued) is always replaced.

fhahn updated this revision to Diff 534353.Jun 25 2023, 9:11 AM

Rebase on top of current main.

nikic added a comment.Jun 25 2023, 9:32 AM

The case I had in mind is something like this:

define i1 @test(i32 %x) {
entry:
  %cmp1 = icmp sgt i32 %x, 1
  br i1 %cmp1, label %if, label %join

if:
  %cmp2 = icmp sgt i32 %x, 0
  br label %join

join:
  %phi = phi i1 [ %cmp2, %if ], [ false, %entry ]
  ret i1 %phi
}

Where the %cmp1 fact dominates the %cmp2 use, but not if we consider the %cmp2 use to be in %join.

bcl5980 added inline comments.
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
1306

Typo?

fhahn updated this revision to Diff 534484.Jun 26 2023, 3:21 AM
fhahn marked an inline comment as done.

The case I had in mind is something like this:

define i1 @test(i32 %x) {
entry:
  %cmp1 = icmp sgt i32 %x, 1
  br i1 %cmp1, label %if, label %join

if:
  %cmp2 = icmp sgt i32 %x, 0
  br label %join

join:
  %phi = phi i1 [ %cmp2, %if ], [ false, %entry ]
  ret i1 %phi
}

Where the %cmp1 fact dominates the %cmp2 use, but not if we consider the %cmp2 use to be in %join.

Ah yes, not an issue during the replacement but where we queue. Added tests in 81e3779a131f and updated the code to use the branch instruction of the incoming block as context.

fhahn added inline comments.Jun 26 2023, 3:23 AM
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
1306

Thanks, removed!

nikic added a comment.Jun 27 2023, 6:15 AM

Can you please also add a test along these lines?

define i1 @test(i1 %c, i32 %x) {
entry:
  br i1 %c, label %if, label %join

if: 
  %cmp1 = icmp sgt i32 %x, 1
  %cmp2 = icmp sgt i32 %x, 0
  br i1 %cmp1, label %join, label %exit

join:
  %phi = phi i1 [ %cmp2, %if ], [ false, %entry ]
  ret i1 %phi

exit:
  ret i1 false
}

Here the fact is known only along the edge, but in neither of the blocks. I don't expect this to actually get folded...

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
666

No need for getOperandNo, there's an overload for Uses.

721

The dyn_cast is needed because it may have been replaced by a constant already?

1286

Stray semicolon

fhahn updated this revision to Diff 534967.Jun 27 2023, 7:00 AM

Address latest comments, thanks!

Can you please also add a test along these lines?

define i1 @test(i1 %c, i32 %x) {
entry:
  br i1 %c, label %if, label %join

if: 
  %cmp1 = icmp sgt i32 %x, 1
  %cmp2 = icmp sgt i32 %x, 0
  br i1 %cmp1, label %join, label %exit

join:
  %phi = phi i1 [ %cmp2, %if ], [ false, %entry ]
  ret i1 %phi

exit:
  ret i1 false
}

Here the fact is known only along the edge, but in neither of the blocks. I don't expect this to actually get folded...

Yep, if the fact is only known on the edge then we don't simplify it at the moment. This could probably be handled by making the fact handling more fine-grained.

I *think* this should already be covered by the following test. It's a 3 entry phi, not sure if it is worth adding a dedicated simpler case? https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/ConstraintElimination/cond-used-in-phi.ll#L221

fhahn marked 3 inline comments as done.Jun 27 2023, 7:01 AM
fhahn added inline comments.
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
666

Done, thanks!

721

Yes, I added a comment here.

1286

removed, thanks!

nikic accepted this revision.Jun 27 2023, 8:25 AM

Yep, if the fact is only known on the edge then we don't simplify it at the moment. This could probably be handled by making the fact handling more fine-grained.

I *think* this should already be covered by the following test. It's a 3 entry phi, not sure if it is worth adding a dedicated simpler case? https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/ConstraintElimination/cond-used-in-phi.ll#L221

Ah yes, that does cover the case. Nevermind then.

LGTM with the nits addressed.

This revision is now accepted and ready to land.Jun 27 2023, 8:25 AM
fhahn marked 3 inline comments as done.Jun 27 2023, 8:27 AM

Yep, if the fact is only known on the edge then we don't simplify it at the moment. This could probably be handled by making the fact handling more fine-grained.

I *think* this should already be covered by the following test. It's a 3 entry phi, not sure if it is worth adding a dedicated simpler case? https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/ConstraintElimination/cond-used-in-phi.ll#L221

Ah yes, that does cover the case. Nevermind then.

LGTM with the nits addressed.

Thanks! Just to double check, the previous nits should already be addressed, where there any additional nits that may not got submitted?

nikic added a comment.Jun 27 2023, 8:29 AM

Thanks! Just to double check, the previous nits should already be addressed, where there any additional nits that may not got submitted?

Nope, just a case of too many tabs...

This revision was automatically updated to reflect the committed changes.