/// 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);
// 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;
}
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();
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
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