diff --git a/llvm/test/CodeGen/AArch64/sqrt-fastmath.ll b/llvm/test/CodeGen/AArch64/sqrt-fastmath.ll index cb1fac16aa9c1c..be13a2ec84cbe0 100644 --- a/llvm/test/CodeGen/AArch64/sqrt-fastmath.ll +++ b/llvm/test/CodeGen/AArch64/sqrt-fastmath.ll @@ -445,6 +445,90 @@ define <4 x double> @d4rsqrt(<4 x double> %a) #0 { ret <4 x double> %2 } +define double @sqrt_fdiv_common_operand(double %x) nounwind { +; FAULT-LABEL: sqrt_fdiv_common_operand: +; FAULT: // %bb.0: +; FAULT-NEXT: fsqrt d1, d0 +; FAULT-NEXT: fdiv d0, d0, d1 +; FAULT-NEXT: ret +; +; CHECK-LABEL: sqrt_fdiv_common_operand: +; CHECK: // %bb.0: +; CHECK-NEXT: frsqrte d1, d0 +; CHECK-NEXT: fmul d2, d1, d1 +; CHECK-NEXT: frsqrts d2, d0, d2 +; CHECK-NEXT: fmul d1, d1, d2 +; CHECK-NEXT: fmul d2, d1, d1 +; CHECK-NEXT: frsqrts d2, d0, d2 +; CHECK-NEXT: fmul d1, d1, d2 +; CHECK-NEXT: fmul d2, d1, d1 +; CHECK-NEXT: frsqrts d2, d0, d2 +; CHECK-NEXT: fmul d1, d1, d2 +; CHECK-NEXT: fmul d0, d0, d1 +; CHECK-NEXT: ret + %sqrt = call fast double @llvm.sqrt.f64(double %x) + %r = fdiv fast double %x, %sqrt + ret double %r +} + +define <2 x double> @sqrt_fdiv_common_operand_vec(<2 x double> %x) nounwind { +; FAULT-LABEL: sqrt_fdiv_common_operand_vec: +; FAULT: // %bb.0: +; FAULT-NEXT: fsqrt v1.2d, v0.2d +; FAULT-NEXT: fdiv v0.2d, v0.2d, v1.2d +; FAULT-NEXT: ret +; +; CHECK-LABEL: sqrt_fdiv_common_operand_vec: +; CHECK: // %bb.0: +; CHECK-NEXT: frsqrte v1.2d, v0.2d +; CHECK-NEXT: fmul v2.2d, v1.2d, v1.2d +; CHECK-NEXT: frsqrts v2.2d, v0.2d, v2.2d +; CHECK-NEXT: fmul v1.2d, v1.2d, v2.2d +; CHECK-NEXT: fmul v2.2d, v1.2d, v1.2d +; CHECK-NEXT: frsqrts v2.2d, v0.2d, v2.2d +; CHECK-NEXT: fmul v1.2d, v1.2d, v2.2d +; CHECK-NEXT: fmul v2.2d, v1.2d, v1.2d +; CHECK-NEXT: frsqrts v2.2d, v0.2d, v2.2d +; CHECK-NEXT: fmul v1.2d, v1.2d, v2.2d +; CHECK-NEXT: fmul v0.2d, v0.2d, v1.2d +; CHECK-NEXT: ret + %sqrt = call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) + %r = fdiv arcp reassoc <2 x double> %x, %sqrt + ret <2 x double> %r +} + +define double @sqrt_fdiv_common_operand_extra_use(double %x, double* %p) nounwind { +; FAULT-LABEL: sqrt_fdiv_common_operand_extra_use: +; FAULT: // %bb.0: +; FAULT-NEXT: fsqrt d1, d0 +; FAULT-NEXT: fdiv d0, d0, d1 +; FAULT-NEXT: str d1, [x0] +; FAULT-NEXT: ret +; +; CHECK-LABEL: sqrt_fdiv_common_operand_extra_use: +; CHECK: // %bb.0: +; CHECK-NEXT: frsqrte d1, d0 +; CHECK-NEXT: fmul d2, d1, d1 +; CHECK-NEXT: frsqrts d2, d0, d2 +; CHECK-NEXT: fmul d1, d1, d2 +; CHECK-NEXT: fmul d2, d1, d1 +; CHECK-NEXT: frsqrts d2, d0, d2 +; CHECK-NEXT: fmul d1, d1, d2 +; CHECK-NEXT: fmul d2, d1, d1 +; CHECK-NEXT: frsqrts d2, d0, d2 +; CHECK-NEXT: fmul d1, d1, d2 +; CHECK-NEXT: fcmp d0, #0.0 +; CHECK-NEXT: fmul d1, d0, d1 +; CHECK-NEXT: fcsel d0, d0, d1, eq +; CHECK-NEXT: str d0, [x0] +; CHECK-NEXT: mov v0.16b, v1.16b +; CHECK-NEXT: ret + %sqrt = call fast double @llvm.sqrt.f64(double %x) + store double %sqrt, double* %p + %r = fdiv fast double %x, %sqrt + ret double %r +} + attributes #0 = { "unsafe-fp-math"="true" } attributes #1 = { "unsafe-fp-math"="true" "denormal-fp-math"="ieee" } diff --git a/llvm/test/CodeGen/X86/sqrt-fastmath.ll b/llvm/test/CodeGen/X86/sqrt-fastmath.ll index d9f56e55333222..a0a65e5f242342 100644 --- a/llvm/test/CodeGen/X86/sqrt-fastmath.ll +++ b/llvm/test/CodeGen/X86/sqrt-fastmath.ll @@ -11,6 +11,7 @@ declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) declare <8 x float> @llvm.sqrt.v8f32(<8 x float>) declare <16 x float> @llvm.sqrt.v16f32(<16 x float>) declare double @llvm.sqrt.f64(double) +declare <2 x double> @llvm.sqrt.v2f64(<2 x double>) declare float @llvm.fabs.f32(float) declare <4 x float> @llvm.fabs.v4f32(<4 x float>) @@ -899,6 +900,60 @@ define <4 x float> @div_sqrt_v4f32(<4 x float> %x, <4 x float> %y) { ret <4 x float> %d } +define double @sqrt_fdiv_common_operand(double %x) nounwind { +; SSE-LABEL: sqrt_fdiv_common_operand: +; SSE: # %bb.0: +; SSE-NEXT: sqrtsd %xmm0, %xmm1 +; SSE-NEXT: divsd %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: sqrt_fdiv_common_operand: +; AVX: # %bb.0: +; AVX-NEXT: vsqrtsd %xmm0, %xmm0, %xmm1 +; AVX-NEXT: vdivsd %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + %sqrt = call fast double @llvm.sqrt.f64(double %x) + %r = fdiv fast double %x, %sqrt + ret double %r +} + +define <2 x double> @sqrt_fdiv_common_operand_vec(<2 x double> %x) nounwind { +; SSE-LABEL: sqrt_fdiv_common_operand_vec: +; SSE: # %bb.0: +; SSE-NEXT: sqrtpd %xmm0, %xmm1 +; SSE-NEXT: divpd %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: sqrt_fdiv_common_operand_vec: +; AVX: # %bb.0: +; AVX-NEXT: vsqrtpd %xmm0, %xmm1 +; AVX-NEXT: vdivpd %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + %sqrt = call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) + %r = fdiv arcp reassoc <2 x double> %x, %sqrt + ret <2 x double> %r +} + +define double @sqrt_fdiv_common_operand_extra_use(double %x, double* %p) nounwind { +; SSE-LABEL: sqrt_fdiv_common_operand_extra_use: +; SSE: # %bb.0: +; SSE-NEXT: sqrtsd %xmm0, %xmm1 +; SSE-NEXT: movsd %xmm1, (%rdi) +; SSE-NEXT: divsd %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: sqrt_fdiv_common_operand_extra_use: +; AVX: # %bb.0: +; AVX-NEXT: vsqrtsd %xmm0, %xmm0, %xmm1 +; AVX-NEXT: vmovsd %xmm1, (%rdi) +; AVX-NEXT: vdivsd %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + %sqrt = call fast double @llvm.sqrt.f64(double %x) + store double %sqrt, double* %p + %r = fdiv fast double %x, %sqrt + ret double %r +} + attributes #0 = { "unsafe-fp-math"="true" "reciprocal-estimates"="!sqrtf,!vec-sqrtf,!divf,!vec-divf" } attributes #1 = { "unsafe-fp-math"="true" "reciprocal-estimates"="sqrt,vec-sqrt" } attributes #2 = { nounwind readnone }