Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1347,28 +1347,18 @@ 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(Y) || !isa(Op1))) { // (X / Y) / Z => X / (Y * Z) - Value *YZ = Builder.CreateFMul(Y, Op1); - if (auto *YZInst = dyn_cast(YZ)) { - FastMathFlags FMFIntersect = I.getFastMathFlags(); - FMFIntersect &= cast(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(Y) || !isa(Op0))) { // Z / (X / Y) => (Y * Z) / X - Value *YZ = Builder.CreateFMul(Y, Op0); - if (auto *YZInst = dyn_cast(YZ)) { - FastMathFlags FMFIntersect = I.getFastMathFlags(); - FMFIntersect &= cast(Op1)->getFastMathFlags(); - YZInst->setFastMathFlags(FMFIntersect); - } + Value *YZ = Builder.CreateFMulFMF(Y, Op0, &I); return BinaryOperator::CreateFDivFMF(YZ, X, &I); } } Index: llvm/trunk/test/Transforms/InstCombine/fdiv.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/fdiv.ll +++ llvm/trunk/test/Transforms/InstCombine/fdiv.ll @@ -126,12 +126,12 @@ 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 } @@ -139,12 +139,12 @@ 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 } @@ -342,8 +342,8 @@ define <2 x float> @div_constant_dividend3(<2 x float> %x) { ; CHECK-LABEL: @div_constant_dividend3( -; CHECK-NEXT: [[T1:%.*]] = fdiv <2 x float> , [[X:%.*]] -; CHECK-NEXT: [[T2:%.*]] = fdiv reassoc arcp <2 x float> , [[T1]] +; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], +; CHECK-NEXT: [[T2:%.*]] = fmul reassoc arcp <2 x float> [[TMP1]], ; CHECK-NEXT: ret <2 x float> [[T2]] ; %t1 = fdiv <2 x float> , %x