[llvm] [X86] Require legal result types for f32 estimates (PR #217810)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 22 12:55:51 PDT 2026


https://github.com/MattPD updated https://github.com/llvm/llvm-project/pull/217810

>From f75b56808cc7bcb1efd95bec9f80eb962b60197d Mon Sep 17 00:00:00 2001
From: "Matt P. Dziubinski" <matt-p.dziubinski at hpe.com>
Date: Thu, 20 Aug 2026 23:10:41 -0500
Subject: [PATCH] [X86] Require legal result types for f32 estimates

The single-precision paths in `getRecipEstimate` and `getSqrtEstimate`
match a fixed set of scalar and vector f32 types, then check the
corresponding subtarget features. Those checks do not imply that the
result type is legal. Soft-float makes these result types illegal. Scalar
f32 is also illegal on a 32-bit SSE1 target without SSE2 or x87. The hooks
can then build an X86-specific estimate node with an illegal result type
before type legalization. Type legalization has no rule for that node, so
compilation fails.

Require a legal result type before entering the single-precision estimate
paths. The f16 paths in these hooks already require a legal type. After
this patch, the f32 paths match that behavior. The hooks return no estimate
for an illegal result type, so the original division or square root stays
in the DAG and follows its normal lowering. Estimate code generation for
legal result types is unchanged.

Fixes https://github.com/llvm/llvm-project/issues/217801

Assisted-by: Claude Opus 5, GPT-5.6 Sol.
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  19 +-
 ...ecip-sqrt-estimate-illegal-scalar-types.ll |  43 +
 .../X86/recip-sqrt-estimate-illegal-types.ll  | 742 ++++++++++++++++++
 3 files changed, 795 insertions(+), 9 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/recip-sqrt-estimate-illegal-scalar-types.ll
 create mode 100644 llvm/test/CodeGen/X86/recip-sqrt-estimate-illegal-types.ll

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index bf435b0c2f849..320158eb1003f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -24134,11 +24134,12 @@ SDValue X86TargetLowering::getSqrtEstimate(SDValue Op,
   // along with FMA, this could be a throughput win.
   // TODO: SQRT requires SSE2 to prevent the introduction of an illegal v4i32
   // after legalize types.
-  if ((VT == MVT::f32 && Subtarget.hasSSE1()) ||
-      (VT == MVT::v4f32 && Subtarget.hasSSE1() && Reciprocal) ||
-      (VT == MVT::v4f32 && Subtarget.hasSSE2() && !Reciprocal) ||
-      (VT == MVT::v8f32 && Subtarget.hasAVX()) ||
-      (VT == MVT::v16f32 && Subtarget.useAVX512Regs())) {
+  if (isTypeLegal(VT) &&
+      ((VT == MVT::f32 && Subtarget.hasSSE1()) ||
+       (VT == MVT::v4f32 && Subtarget.hasSSE1() && Reciprocal) ||
+       (VT == MVT::v4f32 && Subtarget.hasSSE2() && !Reciprocal) ||
+       (VT == MVT::v8f32 && Subtarget.hasAVX()) ||
+       (VT == MVT::v16f32 && Subtarget.useAVX512Regs()))) {
     if (RefinementSteps == ReciprocalEstimate::Unspecified)
       RefinementSteps = 1;
 
@@ -24185,10 +24186,10 @@ SDValue X86TargetLowering::getRecipEstimate(SDValue Op, SelectionDAG &DAG,
   // (3 steps = 12 insts). If an 'rcpsd' variant was added to the ISA
   // along with FMA, this could be a throughput win.
 
-  if ((VT == MVT::f32 && Subtarget.hasSSE1()) ||
-      (VT == MVT::v4f32 && Subtarget.hasSSE1()) ||
-      (VT == MVT::v8f32 && Subtarget.hasAVX()) ||
-      (VT == MVT::v16f32 && Subtarget.useAVX512Regs())) {
+  if (isTypeLegal(VT) && ((VT == MVT::f32 && Subtarget.hasSSE1()) ||
+                          (VT == MVT::v4f32 && Subtarget.hasSSE1()) ||
+                          (VT == MVT::v8f32 && Subtarget.hasAVX()) ||
+                          (VT == MVT::v16f32 && Subtarget.useAVX512Regs()))) {
     // Enable estimate codegen with 1 refinement step for vector division.
     // Scalar division estimates are disabled because they break too much
     // real-world code. These defaults are intended to match GCC behavior.
diff --git a/llvm/test/CodeGen/X86/recip-sqrt-estimate-illegal-scalar-types.ll b/llvm/test/CodeGen/X86/recip-sqrt-estimate-illegal-scalar-types.ll
new file mode 100644
index 0000000000000..e5a97982f38df
--- /dev/null
+++ b/llvm/test/CodeGen/X86/recip-sqrt-estimate-illegal-scalar-types.ll
@@ -0,0 +1,43 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse,-sse2,-x87 < %s | FileCheck %s
+;
+; Scalar f32 has no register class with SSE1, no SSE2, and no x87.
+
+define float @recip_f32(float %n, float %d) #0 {
+; CHECK-LABEL: recip_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    subl $20, %esp
+; CHECK-NEXT:    .cfi_adjust_cfa_offset 20
+; CHECK-NEXT:    pushl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    .cfi_adjust_cfa_offset 4
+; CHECK-NEXT:    pushl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    .cfi_adjust_cfa_offset 4
+; CHECK-NEXT:    calll __divsf3
+; CHECK-NEXT:    addl $28, %esp
+; CHECK-NEXT:    .cfi_adjust_cfa_offset -28
+; CHECK-NEXT:    retl
+  %q = fdiv arcp ninf float %n, %d
+  ret float %q
+}
+
+define float @rsqrt_f32(float %x) #1 {
+; CHECK-LABEL: rsqrt_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    subl $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl %eax, (%esp)
+; CHECK-NEXT:    calll sqrtf
+; CHECK-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movl $1065353216, (%esp) # imm = 0x3F800000
+; CHECK-NEXT:    calll __divsf3
+; CHECK-NEXT:    addl $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
+; CHECK-NEXT:    retl
+  %sqrt = call afn ninf float @llvm.sqrt.f32(float %x)
+  %q = fdiv arcp ninf float 1.0, %sqrt
+  ret float %q
+}
+
+attributes #0 = { "reciprocal-estimates"="divf" }
+attributes #1 = { "reciprocal-estimates"="sqrtf" }
diff --git a/llvm/test/CodeGen/X86/recip-sqrt-estimate-illegal-types.ll b/llvm/test/CodeGen/X86/recip-sqrt-estimate-illegal-types.ll
new file mode 100644
index 0000000000000..0797d22086bdc
--- /dev/null
+++ b/llvm/test/CodeGen/X86/recip-sqrt-estimate-illegal-types.ll
@@ -0,0 +1,742 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+;
+; Both runs are required. SKX covers the 512-bit RCP14 and RSQRT14 paths.
+; Generic AVX covers non-reciprocal v4f32 and v8f32 square roots because SKX
+; tuning treats vector square root as cheap and skips the estimate transform.
+; Soft-float makes every f32 estimate result illegal, so the checks verify that
+; the original operations reach their fallback lowering.
+;
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=skx -mattr=+soft-float \
+; RUN:   < %s | FileCheck %s --check-prefixes=CHECK,SKX
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=x86-64 \
+; RUN:   -mattr=+avx,+soft-float < %s | FileCheck %s --check-prefixes=CHECK,AVX
+
+define float @recip_f32(float %n, float %d) #0 {
+; CHECK-LABEL: recip_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %q = fdiv arcp ninf float %n, %d
+  ret float %q
+}
+
+define <4 x float> @recip_v4f32(<4 x float> %n, <4 x float> %d) #2 {
+; CHECK-LABEL: recip_v4f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movl %r8d, %ebp
+; CHECK-NEXT:    movl %ecx, %r14d
+; CHECK-NEXT:    movl %edx, %r15d
+; CHECK-NEXT:    movq %rdi, %rbx
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r12d
+; CHECK-NEXT:    movl %esi, %edi
+; CHECK-NEXT:    movl %r9d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r13d
+; CHECK-NEXT:    movl %r15d, %edi
+; CHECK-NEXT:    movl %r12d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r15d
+; CHECK-NEXT:    movl %r14d, %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl %ebp, %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, 12(%rbx)
+; CHECK-NEXT:    movl %r14d, 8(%rbx)
+; CHECK-NEXT:    movl %r15d, 4(%rbx)
+; CHECK-NEXT:    movl %r13d, (%rbx)
+; CHECK-NEXT:    movq %rbx, %rax
+; CHECK-NEXT:    addq $8, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %q = fdiv arcp ninf <4 x float> %n, %d
+  ret <4 x float> %q
+}
+
+define <8 x float> @recip_v8f32(<8 x float> %n, <8 x float> %d) #2 {
+; CHECK-LABEL: recip_v8f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movl %r9d, %ebp
+; CHECK-NEXT:    movl %r8d, %r12d
+; CHECK-NEXT:    movl %ecx, %r13d
+; CHECK-NEXT:    movl %edx, %r14d
+; CHECK-NEXT:    movl %esi, %eax
+; CHECK-NEXT:    movq %rdi, %rbx
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r15d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    movl %eax, %edi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %r14d, %edi
+; CHECK-NEXT:    movl %r15d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, (%rsp) # 4-byte Spill
+; CHECK-NEXT:    movl %r13d, %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r13d
+; CHECK-NEXT:    movl %r12d, %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r15d
+; CHECK-NEXT:    movl %ebp, %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %ebp
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r12d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, 28(%rbx)
+; CHECK-NEXT:    movl %r14d, 24(%rbx)
+; CHECK-NEXT:    movl %r12d, 20(%rbx)
+; CHECK-NEXT:    movl %ebp, 16(%rbx)
+; CHECK-NEXT:    movl %r15d, 12(%rbx)
+; CHECK-NEXT:    movl %r13d, 8(%rbx)
+; CHECK-NEXT:    movl (%rsp), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 4(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, (%rbx)
+; CHECK-NEXT:    movq %rbx, %rax
+; CHECK-NEXT:    addq $8, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %q = fdiv arcp ninf <8 x float> %n, %d
+  ret <8 x float> %q
+}
+
+define <16 x float> @recip_v16f32(<16 x float> %n, <16 x float> %d) #0 {
+; CHECK-LABEL: recip_v16f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $40, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 96
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movl %r9d, %r15d
+; CHECK-NEXT:    movl %r8d, %ebp
+; CHECK-NEXT:    movl %ecx, %r12d
+; CHECK-NEXT:    movl %edx, %r13d
+; CHECK-NEXT:    movl %esi, %eax
+; CHECK-NEXT:    movq %rdi, %rbx
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r14d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    movl %eax, %edi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %r13d, %edi
+; CHECK-NEXT:    movl %r14d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %r12d, %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %ebp, %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %r15d, %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, (%rsp) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r13d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r15d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %ebp
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r12d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, 60(%rbx)
+; CHECK-NEXT:    movl %r12d, 56(%rbx)
+; CHECK-NEXT:    movl %ebp, 52(%rbx)
+; CHECK-NEXT:    movl %r14d, 48(%rbx)
+; CHECK-NEXT:    movl %r15d, 44(%rbx)
+; CHECK-NEXT:    movl %r13d, 40(%rbx)
+; CHECK-NEXT:    movl (%rsp), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 36(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 32(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 28(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 24(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 20(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 16(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 12(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 8(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 4(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, (%rbx)
+; CHECK-NEXT:    movq %rbx, %rax
+; CHECK-NEXT:    addq $40, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %q = fdiv arcp ninf <16 x float> %n, %d
+  ret <16 x float> %q
+}
+
+define float @rsqrt_f32(float %x) #1 {
+; CHECK-LABEL: rsqrt_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %eax, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %sqrt = call afn ninf float @llvm.sqrt.f32(float %x)
+  %q = fdiv arcp ninf float 1.0, %sqrt
+  ret float %q
+}
+
+define <4 x float> @rsqrt_v4f32(<4 x float> %x) #1 {
+; CHECK-LABEL: rsqrt_v4f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    .cfi_offset %rbx, -48
+; CHECK-NEXT:    .cfi_offset %r12, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movl %ecx, %r14d
+; CHECK-NEXT:    movl %edx, %r15d
+; CHECK-NEXT:    movl %esi, %r12d
+; CHECK-NEXT:    movq %rdi, %rbx
+; CHECK-NEXT:    movl %r8d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %ebp
+; CHECK-NEXT:    movl %r14d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl %r15d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r15d
+; CHECK-NEXT:    movl %r12d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %eax, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r12d
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %r15d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r15d
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %r14d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %ebp, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, 12(%rbx)
+; CHECK-NEXT:    movl %r14d, 8(%rbx)
+; CHECK-NEXT:    movl %r15d, 4(%rbx)
+; CHECK-NEXT:    movl %r12d, (%rbx)
+; CHECK-NEXT:    movq %rbx, %rax
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %sqrt = call afn ninf <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
+  %q = fdiv arcp ninf <4 x float> splat (float 1.0), %sqrt
+  ret <4 x float> %q
+}
+
+define <16 x float> @rsqrt_v16f32(<16 x float> %x) #1 {
+; CHECK-LABEL: rsqrt_v16f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $72, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 128
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movl %r9d, %r14d
+; CHECK-NEXT:    movl %r8d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %esi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movq %rdi, %rbx
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r13d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r12d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r15d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebp
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %ebp, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %r15d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %r12d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %r13d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r12d
+; CHECK-NEXT:    movl %r14d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %ebp
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r15d
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r13d
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %eax, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %r13d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %r15d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %ebp, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %r14d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl %r12d, %esi
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r12d
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r13d
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r15d
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, %ebp
+; CHECK-NEXT:    movl $1065353216, %edi # imm = 0x3F800000
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; CHECK-NEXT:    callq __divsf3 at PLT
+; CHECK-NEXT:    movl %eax, 60(%rbx)
+; CHECK-NEXT:    movl %ebp, 56(%rbx)
+; CHECK-NEXT:    movl %r14d, 52(%rbx)
+; CHECK-NEXT:    movl %r15d, 48(%rbx)
+; CHECK-NEXT:    movl %r13d, 44(%rbx)
+; CHECK-NEXT:    movl %r12d, 40(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 36(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 32(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 28(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 24(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 20(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 16(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 12(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 8(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 4(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, (%rbx)
+; CHECK-NEXT:    movq %rbx, %rax
+; CHECK-NEXT:    addq $72, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %sqrt = call afn ninf <16 x float> @llvm.sqrt.v16f32(<16 x float> %x)
+  %q = fdiv arcp ninf <16 x float> splat (float 1.0), %sqrt
+  ret <16 x float> %q
+}
+
+define <4 x float> @sqrt_v4f32(<4 x float> %x) #1 {
+; CHECK-LABEL: sqrt_v4f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    .cfi_offset %rbx, -48
+; CHECK-NEXT:    .cfi_offset %r12, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movl %r8d, %ebx
+; CHECK-NEXT:    movl %ecx, %ebp
+; CHECK-NEXT:    movl %edx, %r14d
+; CHECK-NEXT:    movq %rdi, %r15
+; CHECK-NEXT:    movl %esi, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r12d
+; CHECK-NEXT:    movl %r14d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl %ebp, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %ebp
+; CHECK-NEXT:    movl %ebx, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, 12(%r15)
+; CHECK-NEXT:    movl %ebp, 8(%r15)
+; CHECK-NEXT:    movl %r14d, 4(%r15)
+; CHECK-NEXT:    movl %r12d, (%r15)
+; CHECK-NEXT:    movq %r15, %rax
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %sqrt = call afn ninf <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
+  ret <4 x float> %sqrt
+}
+
+define <8 x float> @sqrt_v8f32(<8 x float> %x) #1 {
+; CHECK-LABEL: sqrt_v8f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movl %r9d, %r13d
+; CHECK-NEXT:    movl %r8d, %r12d
+; CHECK-NEXT:    movl %ecx, %r14d
+; CHECK-NEXT:    movl %edx, %r15d
+; CHECK-NEXT:    movq %rdi, %rbx
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebp
+; CHECK-NEXT:    movl %esi, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl %r15d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, (%rsp) # 4-byte Spill
+; CHECK-NEXT:    movl %r14d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r14d
+; CHECK-NEXT:    movl %r12d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r12d
+; CHECK-NEXT:    movl %r13d, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r13d
+; CHECK-NEXT:    movl %ebp, %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %ebp
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, %r15d
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT:    callq sqrtf at PLT
+; CHECK-NEXT:    movl %eax, 28(%rbx)
+; CHECK-NEXT:    movl %r15d, 24(%rbx)
+; CHECK-NEXT:    movl %ebp, 20(%rbx)
+; CHECK-NEXT:    movl %r13d, 16(%rbx)
+; CHECK-NEXT:    movl %r12d, 12(%rbx)
+; CHECK-NEXT:    movl %r14d, 8(%rbx)
+; CHECK-NEXT:    movl (%rsp), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, 4(%rbx)
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT:    movl %eax, (%rbx)
+; CHECK-NEXT:    movq %rbx, %rax
+; CHECK-NEXT:    addq $8, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %sqrt = call afn ninf <8 x float> @llvm.sqrt.v8f32(<8 x float> %x)
+  ret <8 x float> %sqrt
+}
+
+attributes #0 = { "min-legal-vector-width"="512" "prefer-vector-width"="512"
+                  "reciprocal-estimates"="divf,vec-divf" }
+attributes #1 = { "min-legal-vector-width"="512" "prefer-vector-width"="512"
+                  "reciprocal-estimates"="sqrtf,vec-sqrtf" }
+attributes #2 = { "min-legal-vector-width"="512" "prefer-vector-width"="512" }
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; AVX: {{.*}}
+; SKX: {{.*}}



More information about the llvm-commits mailing list