1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; More than one 'arcp' division using a single divisor operand 4*9880d681SAndroid Build Coastguard Worker; should be converted into a reciprocal and multiplication. 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker; Don't do anything for just one division. 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdefine float @div1_arcp(float %x, float %y, float %z) { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: div1_arcp: 10*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 11*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divss %xmm1, %xmm0 12*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 13*9880d681SAndroid Build Coastguard Worker %div1 = fdiv arcp float %x, %y 14*9880d681SAndroid Build Coastguard Worker ret float %div1 15*9880d681SAndroid Build Coastguard Worker} 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker; All math instructions are 'arcp', so optimize. 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Workerdefine float @div2_arcp_all(float %x, float %y, float %z) { 20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: div2_arcp_all: 21*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 22*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movss {{.*#+}} xmm3 = mem[0],zero,zero,zero 23*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divss %xmm2, %xmm3 24*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulss %xmm3, %xmm0 25*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulss %xmm1, %xmm0 26*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulss %xmm3, %xmm0 27*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 28*9880d681SAndroid Build Coastguard Worker %div1 = fdiv arcp float %x, %z 29*9880d681SAndroid Build Coastguard Worker %mul = fmul arcp float %div1, %y 30*9880d681SAndroid Build Coastguard Worker %div2 = fdiv arcp float %mul, %z 31*9880d681SAndroid Build Coastguard Worker ret float %div2 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; The first division is not 'arcp', so do not optimize. 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerdefine float @div2_arcp_partial1(float %x, float %y, float %z) { 37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: div2_arcp_partial1: 38*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 39*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divss %xmm2, %xmm0 40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulss %xmm1, %xmm0 41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divss %xmm2, %xmm0 42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 43*9880d681SAndroid Build Coastguard Worker %div1 = fdiv float %x, %z 44*9880d681SAndroid Build Coastguard Worker %mul = fmul arcp float %div1, %y 45*9880d681SAndroid Build Coastguard Worker %div2 = fdiv arcp float %mul, %z 46*9880d681SAndroid Build Coastguard Worker ret float %div2 47*9880d681SAndroid Build Coastguard Worker} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; The second division is not 'arcp', so do not optimize. 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Workerdefine float @div2_arcp_partial2(float %x, float %y, float %z) { 52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: div2_arcp_partial2: 53*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divss %xmm2, %xmm0 55*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulss %xmm1, %xmm0 56*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divss %xmm2, %xmm0 57*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 58*9880d681SAndroid Build Coastguard Worker %div1 = fdiv arcp float %x, %z 59*9880d681SAndroid Build Coastguard Worker %mul = fmul arcp float %div1, %y 60*9880d681SAndroid Build Coastguard Worker %div2 = fdiv float %mul, %z 61*9880d681SAndroid Build Coastguard Worker ret float %div2 62*9880d681SAndroid Build Coastguard Worker} 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker; The multiply is not 'arcp', but that does not prevent optimizing the divisions. 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Workerdefine float @div2_arcp_partial3(float %x, float %y, float %z) { 67*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: div2_arcp_partial3: 68*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 69*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movss {{.*#+}} xmm3 = mem[0],zero,zero,zero 70*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divss %xmm2, %xmm3 71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulss %xmm3, %xmm0 72*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulss %xmm1, %xmm0 73*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulss %xmm3, %xmm0 74*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 75*9880d681SAndroid Build Coastguard Worker %div1 = fdiv arcp float %x, %z 76*9880d681SAndroid Build Coastguard Worker %mul = fmul float %div1, %y 77*9880d681SAndroid Build Coastguard Worker %div2 = fdiv arcp float %mul, %z 78*9880d681SAndroid Build Coastguard Worker ret float %div2 79*9880d681SAndroid Build Coastguard Worker} 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker; If the reciprocal is already calculated, we should not 82*9880d681SAndroid Build Coastguard Worker; generate an extra multiplication by 1.0. 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Workerdefine double @div3_arcp(double %x, double %y, double %z) { 85*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: div3_arcp: 86*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movsd{{.*#+}} xmm2 = mem[0],zero 88*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divsd %xmm1, %xmm2 89*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mulsd %xmm2, %xmm0 90*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: addsd %xmm2, %xmm0 91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 92*9880d681SAndroid Build Coastguard Worker %div1 = fdiv fast double 1.0, %y 93*9880d681SAndroid Build Coastguard Worker %div2 = fdiv fast double %x, %y 94*9880d681SAndroid Build Coastguard Worker %ret = fadd fast double %div2, %div1 95*9880d681SAndroid Build Coastguard Worker ret double %ret 96*9880d681SAndroid Build Coastguard Worker} 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerdefine void @PR24141() { 99*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: PR24141: 100*9880d681SAndroid Build Coastguard Worker; CHECK: callq 101*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: divsd 102*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jmp 103*9880d681SAndroid Build Coastguard Workerentry: 104*9880d681SAndroid Build Coastguard Worker br label %while.body 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Workerwhile.body: 107*9880d681SAndroid Build Coastguard Worker %x.0 = phi double [ undef, %entry ], [ %div, %while.body ] 108*9880d681SAndroid Build Coastguard Worker %call = call { double, double } @g(double %x.0) 109*9880d681SAndroid Build Coastguard Worker %xv0 = extractvalue { double, double } %call, 0 110*9880d681SAndroid Build Coastguard Worker %xv1 = extractvalue { double, double } %call, 1 111*9880d681SAndroid Build Coastguard Worker %div = fdiv arcp double %xv0, %xv1 112*9880d681SAndroid Build Coastguard Worker br label %while.body 113*9880d681SAndroid Build Coastguard Worker} 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workerdeclare { double, double } @g(double) 116*9880d681SAndroid Build Coastguard Worker 117