[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:
parent
21949de62f
commit
467cbb6249
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue