if (Instruction *R = FoldOpIntoSelect(I, SI))
return R;
- if (I.isFast()) {
+ if (I.hasAllowReassoc() && I.hasAllowReciprocal()) {
Value *X, *Y;
if (match(Op0, m_OneUse(m_FDiv(m_Value(X), m_Value(Y)))) &&
(!isa<Constant>(Y) || !isa<Constant>(Op1))) {
// (X / Y) / Z => X / (Y * Z)
- Value *YZ = Builder.CreateFMul(Y, Op1);
- if (auto *YZInst = dyn_cast<Instruction>(YZ)) {
- FastMathFlags FMFIntersect = I.getFastMathFlags();
- FMFIntersect &= cast<Instruction>(Op0)->getFastMathFlags();
- YZInst->setFastMathFlags(FMFIntersect);
- }
+ Value *YZ = Builder.CreateFMulFMF(Y, Op1, &I);
return BinaryOperator::CreateFDivFMF(X, YZ, &I);
}
if (match(Op1, m_OneUse(m_FDiv(m_Value(X), m_Value(Y)))) &&
(!isa<Constant>(Y) || !isa<Constant>(Op0))) {
// Z / (X / Y) => (Y * Z) / X
- Value *YZ = Builder.CreateFMul(Y, Op0);
- if (auto *YZInst = dyn_cast<Instruction>(YZ)) {
- FastMathFlags FMFIntersect = I.getFastMathFlags();
- FMFIntersect &= cast<Instruction>(Op1)->getFastMathFlags();
- YZInst->setFastMathFlags(FMFIntersect);
- }
+ Value *YZ = Builder.CreateFMulFMF(Y, Op0, &I);
return BinaryOperator::CreateFDivFMF(YZ, X, &I);
}
}
define float @div_with_div_numerator(float %x, float %y, float %z) {
; CHECK-LABEL: @div_with_div_numerator(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul ninf float [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast float [[X:%.*]], [[TMP1]]
+; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp float [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[DIV2:%.*]] = fdiv reassoc arcp float [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret float [[DIV2]]
;
%div1 = fdiv ninf float %x, %y
- %div2 = fdiv fast float %div1, %z
+ %div2 = fdiv arcp reassoc float %div1, %z
ret float %div2
}
define <2 x float> @div_with_div_denominator(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @div_with_div_denominator(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul nnan <2 x float> [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast <2 x float> [[TMP1]], [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[DIV2:%.*]] = fdiv reassoc arcp <2 x float> [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret <2 x float> [[DIV2]]
;
%div1 = fdiv nnan <2 x float> %x, %y
- %div2 = fdiv fast <2 x float> %z, %div1
+ %div2 = fdiv arcp reassoc <2 x float> %z, %div1
ret <2 x float> %div2
}
define <2 x float> @div_constant_dividend3(<2 x float> %x) {
; CHECK-LABEL: @div_constant_dividend3(
-; CHECK-NEXT: [[T1:%.*]] = fdiv <2 x float> <float 3.000000e+00, float 7.000000e+00>, [[X:%.*]]
-; CHECK-NEXT: [[T2:%.*]] = fdiv reassoc arcp <2 x float> <float 1.500000e+01, float -7.000000e+00>, [[T1]]
+; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], <float 1.500000e+01, float -7.000000e+00>
+; CHECK-NEXT: [[T2:%.*]] = fmul reassoc arcp <2 x float> [[TMP1]], <float 0x3FD5555560000000, float 0x3FC24924A0000000>
; CHECK-NEXT: ret <2 x float> [[T2]]
;
%t1 = fdiv <2 x float> <float 3.0e0, float 7.0e0>, %x