mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-28 06:22:51 +01:00
8b07d115c8
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 llvm-svn: 243500
68 lines
1.9 KiB
LLVM
68 lines
1.9 KiB
LLVM
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s
|
|
|
|
; Anything more than one division using a single divisor operand
|
|
; should be converted into a reciprocal and multiplication.
|
|
|
|
define float @div1_arcp(float %x, float %y, float %z) #0 {
|
|
; CHECK-LABEL: div1_arcp:
|
|
; CHECK: # BB#0:
|
|
; CHECK-NEXT: divss %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%div1 = fdiv arcp float %x, %y
|
|
ret float %div1
|
|
}
|
|
|
|
define float @div2_arcp(float %x, float %y, float %z) #0 {
|
|
; CHECK-LABEL: div2_arcp:
|
|
; CHECK: # BB#0:
|
|
; CHECK-NEXT: movss {{.*#+}} xmm3 = mem[0],zero,zero,zero
|
|
; CHECK-NEXT: divss %xmm2, %xmm3
|
|
; CHECK-NEXT: mulss %xmm1, %xmm0
|
|
; CHECK-NEXT: mulss %xmm3, %xmm0
|
|
; CHECK-NEXT: mulss %xmm3, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%div1 = fdiv arcp float %x, %z
|
|
%mul = fmul arcp float %div1, %y
|
|
%div2 = fdiv arcp float %mul, %z
|
|
ret float %div2
|
|
}
|
|
|
|
; If the reciprocal is already calculated, we should not
|
|
; generate an extra multiplication by 1.0.
|
|
|
|
define double @div3_arcp(double %x, double %y, double %z) #0 {
|
|
; CHECK-LABEL: div3_arcp:
|
|
; CHECK: # BB#0:
|
|
; CHECK-NEXT: movsd{{.*#+}} xmm2 = mem[0],zero
|
|
; CHECK-NEXT: divsd %xmm1, %xmm2
|
|
; CHECK-NEXT: mulsd %xmm2, %xmm0
|
|
; CHECK-NEXT: addsd %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%div1 = fdiv fast double 1.0, %y
|
|
%div2 = fdiv fast double %x, %y
|
|
%ret = fadd fast double %div2, %div1
|
|
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" }
|