[llvm] r253240 - Add intermediate subtract instructions to reassociation worklist.
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 22 13:54:37 PDT 2017
Aditya: this seems to have caused https://bugs.llvm.org/show_bug.cgi?id=34078
Can you take a look?
On Mon, Nov 16, 2015 at 10:07 AM, Owen Anderson via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: resistor
> Date: Mon Nov 16 12:07:30 2015
> New Revision: 253240
>
> URL: http://llvm.org/viewvc/llvm-project?rev=253240&view=rev
> Log:
> Add intermediate subtract instructions to reassociation worklist.
>
> We sometimes create intermediate subtract instructions during
> reassociation. Adding these to the worklist to revisit exposes many
> additional reassociation opportunities.
>
> Patch by Aditya Nandakumar.
>
> Added:
> llvm/trunk/test/Transforms/Reassociate/reassoc-intermediate-fnegs.ll
> Modified:
> llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
> llvm/trunk/test/Transforms/Reassociate/fast-ReassociateVector.ll
> llvm/trunk/test/Transforms/Reassociate/fast-basictest.ll
> llvm/trunk/test/Transforms/Reassociate/fast-fp-commute.ll
> llvm/trunk/test/Transforms/Reassociate/fast-multistep.ll
> llvm/trunk/test/Transforms/Reassociate/multistep.ll
> llvm/trunk/test/Transforms/Reassociate/secondary.ll
> llvm/trunk/test/Transforms/Reassociate/xor_reassoc.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp?rev=253240&r1=253239&r2=253240&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp Mon Nov 16 12:07:30 2015
> @@ -881,7 +881,11 @@ void Reassociate::RewriteExprTree(Binary
> /// that computes the negative version of the value specified. The negative
> /// version of the value is returned, and BI is left pointing at the instruction
> /// that should be processed next by the reassociation pass.
> -static Value *NegateValue(Value *V, Instruction *BI) {
> +/// Also add intermediate instructions to the redo list that are modified while
> +/// pushing the negates through adds. These will be revisited to see if
> +/// additional opportunities have been exposed.
> +static Value *NegateValue(Value *V, Instruction *BI,
> + SetVector<AssertingVH<Instruction>> &ToRedo) {
> if (Constant *C = dyn_cast<Constant>(V)) {
> if (C->getType()->isFPOrFPVectorTy()) {
> return ConstantExpr::getFNeg(C);
> @@ -902,8 +906,8 @@ static Value *NegateValue(Value *V, Inst
> if (BinaryOperator *I =
> isReassociableOp(V, Instruction::Add, Instruction::FAdd)) {
> // Push the negates through the add.
> - I->setOperand(0, NegateValue(I->getOperand(0), BI));
> - I->setOperand(1, NegateValue(I->getOperand(1), BI));
> + I->setOperand(0, NegateValue(I->getOperand(0), BI, ToRedo));
> + I->setOperand(1, NegateValue(I->getOperand(1), BI, ToRedo));
> if (I->getOpcode() == Instruction::Add) {
> I->setHasNoUnsignedWrap(false);
> I->setHasNoSignedWrap(false);
> @@ -916,6 +920,10 @@ static Value *NegateValue(Value *V, Inst
> //
> I->moveBefore(BI);
> I->setName(I->getName()+".neg");
> +
> + // Add the intermediate negates to the redo list as processing them later
> + // could expose more reassociating opportunities.
> + ToRedo.insert(I);
> return I;
> }
>
> @@ -955,12 +963,15 @@ static Value *NegateValue(Value *V, Inst
> } else {
> TheNeg->andIRFlags(BI);
> }
> + ToRedo.insert(TheNeg);
> return TheNeg;
> }
>
> // Insert a 'neg' instruction that subtracts the value from zero to get the
> // negation.
> - return CreateNeg(V, V->getName() + ".neg", BI, BI);
> + BinaryOperator *NewNeg = CreateNeg(V, V->getName() + ".neg", BI, BI);
> + ToRedo.insert(NewNeg);
> + return NewNeg;
> }
>
> /// Return true if we should break up this subtract of X-Y into (X + -Y).
> @@ -994,14 +1005,15 @@ static bool ShouldBreakUpSubtract(Instru
>
> /// If we have (X-Y), and if either X is an add, or if this is only used by an
> /// add, transform this into (X+(0-Y)) to promote better reassociation.
> -static BinaryOperator *BreakUpSubtract(Instruction *Sub) {
> +static BinaryOperator *
> +BreakUpSubtract(Instruction *Sub, SetVector<AssertingVH<Instruction>> &ToRedo) {
> // Convert a subtract into an add and a neg instruction. This allows sub
> // instructions to be commuted with other add instructions.
> //
> // Calculate the negative value of Operand 1 of the sub instruction,
> // and set it as the RHS of the add instruction we just made.
> //
> - Value *NegVal = NegateValue(Sub->getOperand(1), Sub);
> + Value *NegVal = NegateValue(Sub->getOperand(1), Sub, ToRedo);
> BinaryOperator *New = CreateAdd(Sub->getOperand(0), NegVal, "", Sub, Sub);
> Sub->setOperand(0, Constant::getNullValue(Sub->getType())); // Drop use of op.
> Sub->setOperand(1, Constant::getNullValue(Sub->getType())); // Drop use of op.
> @@ -2068,7 +2080,7 @@ void Reassociate::OptimizeInst(Instructi
> // see if we can convert it to X+-Y.
> if (I->getOpcode() == Instruction::Sub) {
> if (ShouldBreakUpSubtract(I)) {
> - Instruction *NI = BreakUpSubtract(I);
> + Instruction *NI = BreakUpSubtract(I, RedoInsts);
> RedoInsts.insert(I);
> MadeChange = true;
> I = NI;
> @@ -2079,6 +2091,12 @@ void Reassociate::OptimizeInst(Instructi
> (!I->hasOneUse() ||
> !isReassociableOp(I->user_back(), Instruction::Mul))) {
> Instruction *NI = LowerNegateToMultiply(I);
> + // If the negate was simplified, revisit the users to see if we can
> + // reassociate further.
> + for (User *U : NI->users()) {
> + if (BinaryOperator *Tmp = dyn_cast<BinaryOperator>(U))
> + RedoInsts.insert(Tmp);
> + }
> RedoInsts.insert(I);
> MadeChange = true;
> I = NI;
> @@ -2086,7 +2104,7 @@ void Reassociate::OptimizeInst(Instructi
> }
> } else if (I->getOpcode() == Instruction::FSub) {
> if (ShouldBreakUpSubtract(I)) {
> - Instruction *NI = BreakUpSubtract(I);
> + Instruction *NI = BreakUpSubtract(I, RedoInsts);
> RedoInsts.insert(I);
> MadeChange = true;
> I = NI;
> @@ -2096,7 +2114,13 @@ void Reassociate::OptimizeInst(Instructi
> if (isReassociableOp(I->getOperand(1), Instruction::FMul) &&
> (!I->hasOneUse() ||
> !isReassociableOp(I->user_back(), Instruction::FMul))) {
> + // If the negate was simplified, revisit the users to see if we can
> + // reassociate further.
> Instruction *NI = LowerNegateToMultiply(I);
> + for (User *U : NI->users()) {
> + if (BinaryOperator *Tmp = dyn_cast<BinaryOperator>(U))
> + RedoInsts.insert(Tmp);
> + }
> RedoInsts.insert(I);
> MadeChange = true;
> I = NI;
> @@ -2111,8 +2135,14 @@ void Reassociate::OptimizeInst(Instructi
> // If this is an interior node of a reassociable tree, ignore it until we
> // get to the root of the tree, to avoid N^2 analysis.
> unsigned Opcode = BO->getOpcode();
> - if (BO->hasOneUse() && BO->user_back()->getOpcode() == Opcode)
> + if (BO->hasOneUse() && BO->user_back()->getOpcode() == Opcode) {
> + // During the initial run we will get to the root of the tree.
> + // But if we get here while we are redoing instructions, there is no
> + // guarantee that the root will be visited. So Redo later
> + if (BO->user_back() != BO)
> + RedoInsts.insert(BO->user_back());
> return;
> + }
>
> // If this is an add tree that is used by a sub instruction, ignore it
> // until we process the subtract.
>
> Modified: llvm/trunk/test/Transforms/Reassociate/fast-ReassociateVector.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/fast-ReassociateVector.ll?rev=253240&r1=253239&r2=253240&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/Reassociate/fast-ReassociateVector.ll (original)
> +++ llvm/trunk/test/Transforms/Reassociate/fast-ReassociateVector.ll Mon Nov 16 12:07:30 2015
> @@ -16,9 +16,9 @@ define <4 x float> @test1(<4 x float> %a
> ; Check that a*a*b+a*a*c is turned into a*(a*(b+c)).
> define <2 x float> @test2(<2 x float> %a, <2 x float> %b, <2 x float> %c) {
> ; CHECK-LABEL: @test2
> -; CHECK-NEXT: fadd fast <2 x float> %c, %b
> -; CHECK-NEXT: fmul fast <2 x float> %a, %tmp2
> -; CHECK-NEXT: fmul fast <2 x float> %tmp3, %a
> +; CHECK-NEXT: [[TMP1:%tmp.*]] = fadd fast <2 x float> %c, %b
> +; CHECK-NEXT: [[TMP2:%tmp.*]] = fmul fast <2 x float> %a, %a
> +; CHECK-NEXT: fmul fast <2 x float> [[TMP2]], [[TMP1]]
> ; CHECK-NEXT: ret <2 x float>
>
> %t0 = fmul fast <2 x float> %a, %b
> @@ -133,8 +133,8 @@ define <2 x float> @test10(<2 x float> %
> ; Check x*y+y*x -> x*y*2.
> define <2 x double> @test11(<2 x double> %x, <2 x double> %y) {
> ; CHECK-LABEL: @test11
> -; CHECK-NEXT: %factor = fmul fast <2 x double> %y, <double 2.000000e+00, double 2.000000e+00>
> -; CHECK-NEXT: %tmp1 = fmul fast <2 x double> %factor, %x
> +; CHECK-NEXT: %factor = fmul fast <2 x double> %x, <double 2.000000e+00, double 2.000000e+00>
> +; CHECK-NEXT: %tmp1 = fmul fast <2 x double> %factor, %y
> ; CHECK-NEXT: ret <2 x double> %tmp1
>
> %1 = fmul fast <2 x double> %x, %y
>
> Modified: llvm/trunk/test/Transforms/Reassociate/fast-basictest.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/fast-basictest.ll?rev=253240&r1=253239&r2=253240&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/Reassociate/fast-basictest.ll (original)
> +++ llvm/trunk/test/Transforms/Reassociate/fast-basictest.ll Mon Nov 16 12:07:30 2015
> @@ -108,7 +108,7 @@ define float @test7(float %A, float %B,
> ; CHECK-LABEL: @test7
> ; CHECK-NEXT: fadd fast float %C, %B
> ; CHECK-NEXT: fmul fast float %A, %A
> -; CHECK-NEXT: fmul fast float %1, %tmp2
> +; CHECK-NEXT: fmul fast float %tmp3, %tmp2
> ; CHECK-NEXT: ret float
>
> %aa = fmul fast float %A, %A
>
> Modified: llvm/trunk/test/Transforms/Reassociate/fast-fp-commute.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/fast-fp-commute.ll?rev=253240&r1=253239&r2=253240&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/Reassociate/fast-fp-commute.ll (original)
> +++ llvm/trunk/test/Transforms/Reassociate/fast-fp-commute.ll Mon Nov 16 12:07:30 2015
> @@ -33,8 +33,8 @@ define float @test2(float %x, float %y)
>
> define float @test3(float %x, float %y) {
> ; CHECK-LABEL: test3
> -; CHECK-NEXT: %factor = fmul fast float %y, 2.000000e+00
> -; CHECK-NEXT: %tmp1 = fmul fast float %factor, %x
> +; CHECK-NEXT: %factor = fmul fast float %x, 2.000000e+00
> +; CHECK-NEXT: %tmp1 = fmul fast float %factor, %y
> ; CHECK-NEXT: ret float %tmp1
>
> %1 = fmul fast float %x, %y
>
> Modified: llvm/trunk/test/Transforms/Reassociate/fast-multistep.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/fast-multistep.ll?rev=253240&r1=253239&r2=253240&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/Reassociate/fast-multistep.ll (original)
> +++ llvm/trunk/test/Transforms/Reassociate/fast-multistep.ll Mon Nov 16 12:07:30 2015
> @@ -3,9 +3,9 @@
> define float @fmultistep1(float %a, float %b, float %c) {
> ; Check that a*a*b+a*a*c is turned into a*(a*(b+c)).
> ; CHECK-LABEL: @fmultistep1
> -; CHECK-NEXT: fadd fast float %c, %b
> -; CHECK-NEXT: fmul fast float %a, %tmp2
> -; CHECK-NEXT: fmul fast float %tmp3, %a
> +; CHECK-NEXT: [[TMP1:%tmp.*]] = fadd fast float %c, %b
> +; CHECK-NEXT: [[TMP2:%tmp.*]] = fmul fast float %a, %a
> +; CHECK-NEXT: fmul fast float [[TMP2]], [[TMP1]]
> ; CHECK-NEXT: ret float
>
> %t0 = fmul fast float %a, %b
>
> Modified: llvm/trunk/test/Transforms/Reassociate/multistep.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/multistep.ll?rev=253240&r1=253239&r2=253240&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/Reassociate/multistep.ll (original)
> +++ llvm/trunk/test/Transforms/Reassociate/multistep.ll Mon Nov 16 12:07:30 2015
> @@ -8,9 +8,9 @@ define i64 @multistep1(i64 %a, i64 %b, i
> %t2 = mul i64 %a, %c
> %t3 = mul i64 %a, %t2 ; a*(a*c)
> %t4 = add i64 %t1, %t3
> -; CHECK-NEXT: add i64 %c, %b
> -; CHECK-NEXT: mul i64 %a, %tmp{{.*}}
> -; CHECK-NEXT: mul i64 %tmp{{.*}}, %a
> +; CHECK-NEXT: [[TMP1:%tmp.*]] = add i64 %c, %b
> +; CHECK-NEXT: [[TMP2:%tmp.*]] = mul i64 %a, %a
> +; CHECK-NEXT: mul i64 [[TMP2]], [[TMP1]]
> ; CHECK-NEXT: ret
> ret i64 %t4
> }
>
> Added: llvm/trunk/test/Transforms/Reassociate/reassoc-intermediate-fnegs.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/reassoc-intermediate-fnegs.ll?rev=253240&view=auto
> ==============================================================================
> --- llvm/trunk/test/Transforms/Reassociate/reassoc-intermediate-fnegs.ll (added)
> +++ llvm/trunk/test/Transforms/Reassociate/reassoc-intermediate-fnegs.ll Mon Nov 16 12:07:30 2015
> @@ -0,0 +1,31 @@
> +; RUN: opt < %s -reassociate -S | FileCheck %s
> +; CHECK-LABEL: faddsubAssoc1
> +; CHECK: [[TMP1:%tmp.*]] = fmul fast half %a, 0xH4500
> +; CHECK: [[TMP2:%tmp.*]] = fmul fast half %b, 0xH4500
> +; CHECK: fsub fast half [[TMP2]], [[TMP1]]
> +; CHECK: ret
> +; Input is A op (B op C)
> +define half @faddsubAssoc1(half %a, half %b) {
> + %tmp1 = fmul fast half %b, 0xH4200 ; 3*b
> + %tmp2 = fmul fast half %a, 0xH4500 ; 5*a
> + %tmp3 = fmul fast half %b, 0xH4000 ; 2*b
> + %tmp4 = fsub fast half %tmp2, %tmp1 ; 5 * a - 3 * b
> + %tmp5 = fsub fast half %tmp3, %tmp4 ; 2 * b - ( 5 * a - 3 * b)
> + ret half %tmp5 ; = 5 * (b - a)
> +}
> +
> +; CHECK-LABEL: faddsubAssoc2
> +; CHECK: [[TMP1:%tmp.*]] = fmul fast half %a, 0xH4500
> +; CHECK: [[TMP2:%tmp.*]] = fmul fast half %b, 0xH3C00
> +; CHECK: fadd fast half [[TMP2]], [[TMP1]]
> +; CHECK: ret
> +; Input is (A op B) op C
> +define half @faddsubAssoc2(half %a, half %b) {
> + %tmp1 = fmul fast half %b, 0xH4200 ; 3*b
> + %tmp2 = fmul fast half %a, 0xH4500 ; 5*a
> + %tmp3 = fmul fast half %b, 0xH4000 ; 2*b
> + %tmp4 = fadd fast half %tmp2, %tmp1 ; 5 * a + 3 * b
> + %tmp5 = fsub fast half %tmp4, %tmp3 ; (5 * a + 3 * b) - (2 * b)
> + ret half %tmp5 ; = 5 * a + b
> +}
> +
>
> Modified: llvm/trunk/test/Transforms/Reassociate/secondary.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/secondary.ll?rev=253240&r1=253239&r2=253240&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/Reassociate/secondary.ll (original)
> +++ llvm/trunk/test/Transforms/Reassociate/secondary.ll Mon Nov 16 12:07:30 2015
> @@ -6,7 +6,7 @@
>
> ; CHECK: define
> ; CHECK-NOT: undef
> -; CHECK: %factor = mul i32 %tmp3, -2
> +; CHECK: %factor = mul i32 %tmp3.neg, 2
> ; CHECK-NOT: undef
> ; CHECK: }
>
>
> Modified: llvm/trunk/test/Transforms/Reassociate/xor_reassoc.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/xor_reassoc.ll?rev=253240&r1=253239&r2=253240&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/Reassociate/xor_reassoc.ll (original)
> +++ llvm/trunk/test/Transforms/Reassociate/xor_reassoc.ll Mon Nov 16 12:07:30 2015
> @@ -88,8 +88,8 @@ define i32 @xor_special2(i32 %x, i32 %y)
> %xor1 = xor i32 %xor, %and
> ret i32 %xor1
> ; CHECK-LABEL: @xor_special2(
> -; CHECK: %xor = xor i32 %y, 123
> -; CHECK: %xor1 = xor i32 %xor, %x
> +; CHECK: %xor = xor i32 %x, 123
> +; CHECK: %xor1 = xor i32 %xor, %y
> ; CHECK: ret i32 %xor1
> }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list