ignore duplicate divisor uses when transforming into reciprocal multiplies (PR24141)
authorSanjay Patel <spatel@rotateright.com>
Tue, 28 Jul 2015 23:28:22 +0000 (23:28 +0000)
committerSanjay Patel <spatel@rotateright.com>
Tue, 28 Jul 2015 23:28:22 +0000 (23:28 +0000)
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
test/CodeGen/X86/fdiv-combine.ll

index de2651650ef27cc14ad8b916ef482a614863d49f..3fe663630d54a6f055f7d18cc347e9aa92631f98 100644 (file)
@@ -8261,11 +8261,11 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {
     return SDValue();
 
   // Find all FDIV users of the same divisor.
-  SmallVector<SDNode *, 4> Users;
-  for (auto *U : N1->uses()) {
+  // Use a set because duplicates may be present in the user list.
+  SetVector<SDNode *> 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.
index 34eac62e367335af0916e638300c9ba22cf55782..b65e9d01ab8ba7118f3603e87563853afb074194 100644 (file)
@@ -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" }