Index: llvm/lib/Transforms/Scalar/Reassociate.cpp =================================================================== --- llvm/lib/Transforms/Scalar/Reassociate.cpp +++ llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -449,7 +449,8 @@ /// of the expression) if it can turn them into binary operators of the right /// type and thus make the expression bigger. static bool LinearizeExprTree(Instruction *I, - SmallVectorImpl &Ops) { + SmallVectorImpl &Ops, + ReassociatePass::OrderedSet &ToRedo) { assert((isa(I) || isa(I)) && "Expected a UnaryOperator or BinaryOperator!"); LLVM_DEBUG(dbgs() << "LINEARIZE: " << *I << '\n'); @@ -583,9 +584,14 @@ (Opcode == Instruction::FMul && match(Tmp, m_FNeg(m_Value())))) { LLVM_DEBUG(dbgs() << "MORPH LEAF: " << *Op << " (" << Weight << ") TO "); - Tmp = LowerNegateToMultiply(Tmp); - LLVM_DEBUG(dbgs() << *Tmp << '\n'); - Worklist.push_back(std::make_pair(Tmp, Weight)); + Instruction *NI = LowerNegateToMultiply(Tmp); + LLVM_DEBUG(dbgs() << *NI << '\n'); + Worklist.push_back(std::make_pair(NI, Weight)); + for (User *U : NI->users()) { + if (BinaryOperator *UTmp = dyn_cast(U)) + ToRedo.insert(UTmp); + } + ToRedo.insert(Tmp); Changed = true; continue; } @@ -1141,7 +1147,7 @@ return nullptr; SmallVector Tree; - MadeChange |= LinearizeExprTree(BO, Tree); + MadeChange |= LinearizeExprTree(BO, Tree, RedoInsts); SmallVector Factors; Factors.reserve(Tree.size()); for (unsigned i = 0, e = Tree.size(); i != e; ++i) { @@ -2320,7 +2326,7 @@ // First, walk the expression tree, linearizing the tree, collecting the // operand information. SmallVector Tree; - MadeChange |= LinearizeExprTree(I, Tree); + MadeChange |= LinearizeExprTree(I, Tree, RedoInsts); SmallVector Ops; Ops.reserve(Tree.size()); for (const RepeatedValue &E : Tree) Index: llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll =================================================================== --- llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll +++ llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll @@ -281,11 +281,10 @@ define <2 x float> @test10(<2 x float> %a, <2 x float> %b, <2 x float> %z) { ; CHECK-LABEL: @test10( -; CHECK-NEXT: [[TMP1:%.*]] = fsub fast <2 x float> zeroinitializer, zeroinitializer ; CHECK-NEXT: [[C:%.*]] = fmul fast <2 x float> [[A:%.*]], ; CHECK-NEXT: [[E:%.*]] = fmul fast <2 x float> [[C]], [[Z:%.*]] -; CHECK-NEXT: [[TMP2:%.*]] = fadd fast <2 x float> [[E]], zeroinitializer -; CHECK-NEXT: ret <2 x float> [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = fadd fast <2 x float> [[E]], zeroinitializer +; CHECK-NEXT: ret <2 x float> [[TMP1]] ; %d = fmul fast <2 x float> %z, %c = fsub fast <2 x float> , %d @@ -296,7 +295,6 @@ define <2 x float> @test10_unary_fneg(<2 x float> %a, <2 x float> %b, <2 x float> %z) { ; CHECK-LABEL: @test10_unary_fneg( -; CHECK-NEXT: [[TMP1:%.*]] = fneg fast <2 x float> zeroinitializer ; CHECK-NEXT: [[E:%.*]] = fmul fast <2 x float> [[A:%.*]], ; CHECK-NEXT: [[F:%.*]] = fmul fast <2 x float> [[E]], [[Z:%.*]] ; CHECK-NEXT: ret <2 x float> [[F]] Index: llvm/test/Transforms/Reassociate/fast-basictest.ll =================================================================== --- llvm/test/Transforms/Reassociate/fast-basictest.ll +++ llvm/test/Transforms/Reassociate/fast-basictest.ll @@ -181,16 +181,12 @@ } ; (-X)*Y + Z -> Z-X*Y -; TODO: check why IR transformation of test7 with 'fast' math flag -; is worse than without it (and even without transformation) define float @test7(float %X, float %Y, float %Z) { ; CHECK-LABEL: @test7( -; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float 0.000000e+00, 0.000000e+00 -; CHECK-NEXT: [[A:%.*]] = fmul fast float [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[B:%.*]] = fmul fast float [[A]], 1.000000e+00 -; CHECK-NEXT: [[TMP2:%.*]] = fsub fast float [[Z:%.*]], [[B]] -; CHECK-NEXT: ret float [[TMP2]] +; CHECK-NEXT: [[B:%.*]] = fmul fast float [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float [[Z:%.*]], [[B]] +; CHECK-NEXT: ret float [[TMP1]] ; %A = fsub fast float 0.0, %X %B = fmul fast float %A, %Y @@ -200,11 +196,9 @@ define float @test7_unary_fneg(float %X, float %Y, float %Z) { ; CHECK-LABEL: @test7_unary_fneg( -; CHECK-NEXT: [[TMP1:%.*]] = fneg fast float 0.000000e+00 -; CHECK-NEXT: [[A:%.*]] = fmul fast float [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[B:%.*]] = fmul fast float [[A]], 1.000000e+00 -; CHECK-NEXT: [[TMP2:%.*]] = fsub fast float [[Z:%.*]], [[B]] -; CHECK-NEXT: ret float [[TMP2]] +; CHECK-NEXT: [[B:%.*]] = fmul fast float [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float [[Z:%.*]], [[B]] +; CHECK-NEXT: ret float [[TMP1]] ; %A = fneg fast float %X %B = fmul fast float %A, %Y @@ -276,7 +270,6 @@ define float @test11(float %X) { ; CHECK-LABEL: @test11( -; CHECK-NEXT: [[TMP1:%.*]] = fneg fast float 0.000000e+00 ; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float [[X:%.*]], -3.000000e+00 ; CHECK-NEXT: [[Z:%.*]] = fadd fast float [[FACTOR]], 6.000000e+00 ; CHECK-NEXT: ret float [[Z]] @@ -289,17 +282,12 @@ ret float %Z } -; TODO: check why IR transformation of test12 with 'fast' math flag -; is worse than without it (and even without transformation) - define float @test12(float %X1, float %X2, float %X3) { ; CHECK-LABEL: @test12( -; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float 0.000000e+00, 0.000000e+00 -; CHECK-NEXT: [[A:%.*]] = fmul fast float [[X2:%.*]], [[X1:%.*]] -; CHECK-NEXT: [[B:%.*]] = fmul fast float [[A]], 1.000000e+00 +; CHECK-NEXT: [[B:%.*]] = fmul fast float [[X2:%.*]], [[X1:%.*]] ; CHECK-NEXT: [[C:%.*]] = fmul fast float [[X3:%.*]], [[X1]] -; CHECK-NEXT: [[TMP2:%.*]] = fsub fast float [[C]], [[B]] -; CHECK-NEXT: ret float [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float [[C]], [[B]] +; CHECK-NEXT: ret float [[TMP1]] ; %A = fsub fast float 0.000000e+00, %X1 %B = fmul fast float %A, %X2 ; -X1*X2 @@ -310,12 +298,10 @@ define float @test12_unary_fneg(float %X1, float %X2, float %X3) { ; CHECK-LABEL: @test12_unary_fneg( -; CHECK-NEXT: [[TMP1:%.*]] = fneg fast float 0.000000e+00 -; CHECK-NEXT: [[A:%.*]] = fmul fast float [[X2:%.*]], [[X1:%.*]] -; CHECK-NEXT: [[B:%.*]] = fmul fast float [[A]], 1.000000e+00 +; CHECK-NEXT: [[B:%.*]] = fmul fast float [[X2:%.*]], [[X1:%.*]] ; CHECK-NEXT: [[C:%.*]] = fmul fast float [[X3:%.*]], [[X1]] -; CHECK-NEXT: [[TMP2:%.*]] = fsub fast float [[C]], [[B]] -; CHECK-NEXT: ret float [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float [[C]], [[B]] +; CHECK-NEXT: ret float [[TMP1]] ; %A = fneg fast float %X1 %B = fmul fast float %A, %X2 ; -X1*X2 @@ -490,12 +476,11 @@ define float @test16(float %a, float %b, float %z) { ; CHECK-LABEL: @test16( -; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float 0.000000e+00, 0.000000e+00 ; CHECK-NEXT: [[C:%.*]] = fmul fast float [[A:%.*]], 1.234500e+04 ; CHECK-NEXT: [[E:%.*]] = fmul fast float [[C]], [[B:%.*]] ; CHECK-NEXT: [[F:%.*]] = fmul fast float [[E]], [[Z:%.*]] -; CHECK-NEXT: [[TMP2:%.*]] = fadd fast float [[F]], 0.000000e+00 -; CHECK-NEXT: ret float [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = fadd fast float [[F]], 0.000000e+00 +; CHECK-NEXT: ret float [[TMP1]] ; %c = fsub fast float 0.000000e+00, %z %d = fmul fast float %a, %b @@ -507,7 +492,6 @@ define float @test16_unary_fneg(float %a, float %b, float %z) { ; CHECK-LABEL: @test16_unary_fneg( -; CHECK-NEXT: [[TMP1:%.*]] = fneg fast float 0.000000e+00 ; CHECK-NEXT: [[E:%.*]] = fmul fast float [[A:%.*]], 1.234500e+04 ; CHECK-NEXT: [[F:%.*]] = fmul fast float [[E]], [[B:%.*]] ; CHECK-NEXT: [[G:%.*]] = fmul fast float [[F]], [[Z:%.*]] @@ -539,16 +523,14 @@ } ; TODO: check if we can remove: -; - fsub fast 0, 0 ; - fadd fast x, 0 ; ... as 'fast' implies 'nsz' define float @test17(float %a, float %b, float %z) { ; CHECK-LABEL: @test17( -; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float 0.000000e+00, 0.000000e+00 ; CHECK-NEXT: [[C:%.*]] = fmul fast float [[A:%.*]], 4.000000e+01 ; CHECK-NEXT: [[E:%.*]] = fmul fast float [[C]], [[Z:%.*]] -; CHECK-NEXT: [[TMP2:%.*]] = fadd fast float [[E]], 0.000000e+00 -; CHECK-NEXT: ret float [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = fadd fast float [[E]], 0.000000e+00 +; CHECK-NEXT: ret float [[TMP1]] ; %d = fmul fast float %z, 4.000000e+01 %c = fsub fast float 0.000000e+00, %d @@ -557,10 +539,8 @@ ret float %f } -; TODO: check if we can remove fneg fast 0 as 'fast' implies 'nsz' define float @test17_unary_fneg(float %a, float %b, float %z) { ; CHECK-LABEL: @test17_unary_fneg( -; CHECK-NEXT: [[TMP1:%.*]] = fneg fast float 0.000000e+00 ; CHECK-NEXT: [[E:%.*]] = fmul fast float [[A:%.*]], 4.000000e+01 ; CHECK-NEXT: [[F:%.*]] = fmul fast float [[E]], [[Z:%.*]] ; CHECK-NEXT: ret float [[F]] Index: llvm/test/Transforms/Reassociate/pr42349.ll =================================================================== --- llvm/test/Transforms/Reassociate/pr42349.ll +++ llvm/test/Transforms/Reassociate/pr42349.ll @@ -5,7 +5,6 @@ ; CHECK-LABEL: @wibble( ; CHECK-NEXT: bb: ; CHECK-NEXT: [[TMP7:%.*]] = fmul float [[TMP6:%.*]], -1.000000e+00 -; CHECK-NEXT: [[TMP0:%.*]] = fsub float -0.000000e+00, 0.000000e+00 ; CHECK-NEXT: [[TMP9:%.*]] = fmul fast float [[TMP6]], 0xFFF0000000000000 ; CHECK-NEXT: ret float [[TMP9]] ;