[InstCombine] fold more constant divisor to select-of-constants divisor

By adding a parameter to function FoldOpIntoSelect, we can fold more Ops to Select.
For this example, we tend to fold the division instruction,
so we no longer care whether SelectInst is one use.

This patch slove TODO left in InstCombine/div.ll.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D122967
This commit is contained in:
Chenbing Zheng 2022-04-08 10:19:24 +08:00
parent 21949de62f
commit 467cbb6249
4 changed files with 10 additions and 12 deletions

View File

@ -622,7 +622,8 @@ public:
/// other operand, try to fold the binary operator into the select arguments.
/// This also works for Cast instructions, which obviously do not have a
/// second operand.
Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI);
Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
bool FoldWithMultiUse = false);
/// This is a convenience wrapper function for the above two functions.
Instruction *foldBinOpIntoSelectOrPhi(BinaryOperator &I);

View File

@ -772,7 +772,8 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
// TODO: Adapt simplifyDivRemOfSelectWithZeroOp to allow this and other folds.
if (match(Op0, m_ImmConstant()) &&
match(Op1, m_Select(m_Value(), m_ImmConstant(), m_ImmConstant()))) {
if (Instruction *R = FoldOpIntoSelect(I, cast<SelectInst>(Op1)))
if (Instruction *R = FoldOpIntoSelect(I, cast<SelectInst>(Op1),
/*FoldWithMultiUse*/ true))
return R;
}

View File

@ -1037,10 +1037,10 @@ static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO,
return NewBO;
}
Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op,
SelectInst *SI) {
// Don't modify shared select instructions.
if (!SI->hasOneUse())
Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
bool FoldWithMultiUse) {
// Don't modify shared select instructions unless set FoldWithMultiUse
if (!SI->hasOneUse() && !FoldWithMultiUse)
return nullptr;
Value *TV = SI->getTrueValue();

View File

@ -1098,13 +1098,11 @@ define i32 @sdiv_constant_dividend_select_of_constants_divisor(i1 %b) {
ret i32 %r
}
; TODO: sdiv should still be replaced by select.
define i32 @sdiv_constant_dividend_select_of_constants_divisor_use(i1 %b) {
; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
; CHECK-NEXT: call void @use(i32 [[S]])
; CHECK-NEXT: [[R:%.*]] = sdiv i32 42, [[S]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i32 3, i32 -14
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 12, i32 -3
@ -1204,13 +1202,11 @@ define i32 @udiv_constant_dividend_select_of_constants_divisor(i1 %b) {
ret i32 %r
}
; TODO: udiv should still be replaced by select.
define i32 @udiv_constant_dividend_select_of_constants_divisor_use(i1 %b) {
; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
; CHECK-NEXT: call void @use(i32 [[S]])
; CHECK-NEXT: [[R:%.*]] = udiv i32 42, [[S]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i32 3, i32 0
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 12, i32 -3