From 8fd3ed9e3a3ee5d78c871c0e0d961bf21e5d1b71 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 28 Jul 2015 23:28:22 +0000 Subject: [PATCH] ignore duplicate divisor uses when transforming into reciprocal multiplies (PR24141) PR24141: https://llvm.org/bugs/show_bug.cgi?id=24141 contains a test case where we have duplicate entries in a node's uses() list. After r241826, we use CombineTo() to delete dead nodes when combining the uses into reciprocal multiplies, but this fails if we encounter the just-deleted node again in the list. The solution in this patch is to not add duplicate entries to the list of users that we will subsequently iterate over. For the test case, this avoids triggering the combine divisors logic entirely because there really is only one user of the divisor. Differential Revision: http://reviews.llvm.org/D11345 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243500 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 8 ++++---- test/CodeGen/X86/fdiv-combine.ll | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index de2651650ef..3fe663630d5 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -8261,11 +8261,11 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) { return SDValue(); // Find all FDIV users of the same divisor. - SmallVector Users; - for (auto *U : N1->uses()) { + // Use a set because duplicates may be present in the user list. + SetVector Users; + for (auto *U : N1->uses()) if (U->getOpcode() == ISD::FDIV && U->getOperand(1) == N1) - Users.push_back(U); - } + Users.insert(U); // Now that we have the actual number of divisor uses, make sure it meets // the minimum threshold specified by the target. diff --git a/test/CodeGen/X86/fdiv-combine.ll b/test/CodeGen/X86/fdiv-combine.ll index 34eac62e367..b65e9d01ab8 100644 --- a/test/CodeGen/X86/fdiv-combine.ll +++ b/test/CodeGen/X86/fdiv-combine.ll @@ -44,5 +44,24 @@ define double @div3_arcp(double %x, double %y, double %z) #0 { ret double %ret } +define void @PR24141() #0 { +; CHECK-LABEL: PR24141: +; CHECK: callq +; CHECK-NEXT: divsd +; CHECK-NEXT: jmp +entry: + br label %while.body + +while.body: + %x.0 = phi double [ undef, %entry ], [ %div, %while.body ] + %call = call { double, double } @g(double %x.0) + %xv0 = extractvalue { double, double } %call, 0 + %xv1 = extractvalue { double, double } %call, 1 + %div = fdiv double %xv0, %xv1 + br label %while.body +} + +declare { double, double } @g(double) + ; FIXME: If the backend understands 'arcp', then this attribute is unnecessary. attributes #0 = { "unsafe-fp-math"="true" } -- 2.34.1