Skip to content

Conversation

@Camsyn
Copy link
Contributor

@Camsyn Camsyn commented Oct 27, 2025

Key change: model constraints of predicate infos as ConstangtRange, supporting multi-case destinations and default destination of switch.


Previously, PredicateInfo and SCCP handled a very simple situation of switch branch, i.e., single-case dest.

There were still TWO situations pending to handle, i.e., 1) default dest, and 2) multi-cases dest, as follows:

  switch i32 %x, label %default [
    i32 0, label %multicases
    i32 2, label %multicases
    i32 3, label %singlecase
    i32 4, label %default
  ]

Previously, predicate infos of a renamed operand were only modeled as a and-chain of PredicateConstraint { Pred, OtherOp }, which cannot handle complex situations.

  • For multi-cases dest, its predicate infos should have been or-chained, e.g., x == 0 || x == 2 here, which has not been supported.
  • For default dest, its predicate infos can be modeled as and chain of ne, e.g., x!=0 && x!=2 && x!=3 here. However, such handling would generate lots of intermediate no-op bitcast, especially for those big switchs.

Although PredicateConstrant is challenging to model multi-cases/default dest of a switch, ConstantRange is fortunately able to do so; Thus, this PR introduces a new way (i.e., ConstantRange) to model constraints for PredicateInfo.

E.g.,

  • For multi-cases branch switch -> %multcases (x == 0 || x == 2 ), we can conservatively derive a constant range [0, 3) via union of emptyset ∪ {0} ∪ {2} .
  • For defualt branch switch -> %default (x!=0 && x!=2 && x!=3), we can conservatively derive a constant range [1, MAX] via intersection of fullset ∩ ~{0} ∩ ~{2} ∩ ~{3}

Currently, we only use new constraints of ConstantRange in SCCP and keep the semantics of PredicateConstraint unchanged.

For each successor of a switch, we collect all its related case values, and construct

  1. PredicateConstraint only if NumCases == 1, to keep consistent with previous semantic;
  2. ConstantRange for all situations related to switch, for SCCP's better optimization.

For assume/branch, we give a ConstrantRange only if isa<ConstantInt>(OtherOp) in PredicateConstraint { Pred, OtherOp }.

Negligible CompTime Impact: dtcxzyw/llvm-opt-benchmark#2990
Promising Optimization Impact:

@Camsyn Camsyn force-pushed the predicate-info-switch-augment branch 2 times, most recently from 1310036 to 2f10deb Compare October 27, 2025 15:44
Now we can handle default-dst and multi-cases dest of switch for
PredicateInfo, via using a constant range to model such scenario.
@Camsyn
Copy link
Contributor Author

Camsyn commented Oct 31, 2025

Question for another potential new feature: should we model the OR-chain of PredicateInfo, which brings extra complexity to PredicateInfo?

E.g.,

int a = ...;
if ( a < 0 || a >= 10) {
  // If we support OR-chained Predicate Info, we can derive that a ∈ [10, 0) in this branch.
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant