From 2aa1295adee567d0906af2daf8f809459c20568a Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Sun, 5 Oct 2014 23:41:26 +0000 Subject: [PATCH] Give the Reassociate pass a bit more flexibility and autonomy when optimizing expressions. Particularly, it addresses cases where Reassociate breaks Subtracts but then fails to optimize combinations like I1 + -I2 where I1 and I2 have the same rank and are identical. Patch by Dmitri Shtilman. llvm-svn: 219092 --- lib/Transforms/Scalar/Reassociate.cpp | 14 ++++++++++++-- test/Transforms/Reassociate/negation1.ll | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/Transforms/Reassociate/negation1.ll diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index d0cd48a3a26..b8fb25d0b9a 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -1034,13 +1034,23 @@ static unsigned FindInOperandList(SmallVectorImpl &Ops, unsigned i, Value *X) { unsigned XRank = Ops[i].Rank; unsigned e = Ops.size(); - for (unsigned j = i+1; j != e && Ops[j].Rank == XRank; ++j) + for (unsigned j = i+1; j != e && Ops[j].Rank == XRank; ++j) { if (Ops[j].Op == X) return j; + if (Instruction *I1 = dyn_cast(Ops[j].Op)) + if (Instruction *I2 = dyn_cast(X)) + if (I1->isIdenticalTo(I2)) + return j; + } // Scan backwards. - for (unsigned j = i-1; j != ~0U && Ops[j].Rank == XRank; --j) + for (unsigned j = i-1; j != ~0U && Ops[j].Rank == XRank; --j) { if (Ops[j].Op == X) return j; + if (Instruction *I1 = dyn_cast(Ops[j].Op)) + if (Instruction *I2 = dyn_cast(X)) + if (I1->isIdenticalTo(I2)) + return j; + } return i; } diff --git a/test/Transforms/Reassociate/negation1.ll b/test/Transforms/Reassociate/negation1.ll new file mode 100644 index 00000000000..34b943cf496 --- /dev/null +++ b/test/Transforms/Reassociate/negation1.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -reassociate -instcombine -S | FileCheck %s + +; Test that we can turn things like A*B + X - A*B -> X. + +define i32 @test1(i32 %a, i32 %b, i32 %x) { +; CHECK-LABEL: test1 +; CHECK: ret i32 %x + + %c = mul i32 %a, %b + %d = add i32 %c, %x + %c1 = mul i32 %a, %b + %f = sub i32 %d, %c1 + ret i32 %f +} +