If we assign the same rank to select of constants as to constants, we enable InstCombine to absorb constant into the select.
Diff Detail
Event Timeline
Posting this as a draft to get some feedback / advice. I am not sure about the following points:
(1) If only one of the arguments of select is constant, putting select next to a constant could be still beneficial.
(2) How should we handle selects on different conditions?
(3) Would it be better to move selects next to constants in ReassociateExpression instead?
| llvm/test/Transforms/Reassociate/select-of-constants.ll | ||
|---|---|---|
| 19 | This test produces the same result before and after your patch (https://llvm.godbolt.org/z/v6oe486Mc). | |
| llvm/test/Transforms/Reassociate/select-of-constants.ll | ||
|---|---|---|
| 19 | The output after reassociate is: define dso_local signext i32 @select_of_constants(i32 noundef signext %a, i1 %c) {
entry:
%select_ = select i1 %c, i32 8, i32 2
%add4 = add i32 %select_, 4 ; note that now we add 4 to %select_
%add_ = add i32 %add4, %a
ret i32 %add_
}So basically, the input corresponds to this expression: %select_ + (%a + 4) and output corresponds to this: (%select + 4) + %a. This allows InstCombine to "swallow` addition of 4 into the select. At the end of opt we'll have: define dso_local signext i32 @select_of_constants(i32 noundef signext %a, i1 %c) local_unnamed_addr #0 {
entry:
%add4 = select i1 %c, i32 12, i32 6
%add_ = add i32 %add4, %a
ret i32 %add_
} | |
This test produces the same result before and after your patch (https://llvm.godbolt.org/z/v6oe486Mc).