[llvm] AMDGPU: Add baseline tests for f64 rsq pattern handling (PR #172052)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 12 09:40:39 PST 2025


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/172052

None

>From 76822a02e1800ab51858a4bd59d50936f02bce1c Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 12 Dec 2025 15:38:37 +0100
Subject: [PATCH] AMDGPU: Add baseline tests for f64 rsq pattern handling

---
 .../AMDGPU/amdgpu-codegenprepare-fdiv.f64.ll  | 526 ++++++++++++++++++
 1 file changed, 526 insertions(+)
 create mode 100644 llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-fdiv.f64.ll

diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-fdiv.f64.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-fdiv.f64.ll
new file mode 100644
index 0000000000000..b97cd91f2ab32
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-fdiv.f64.ll
@@ -0,0 +1,526 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -mtriple=amdgcn-- -passes=amdgpu-codegenprepare < %s | FileCheck %s
+
+define double @rsq_f64(double %x) {
+; CHECK-LABEL: define double @rsq_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @neg_rsq_f64(double %x) {
+; CHECK-LABEL: define double @neg_rsq_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double -1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double -1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_nnan(double %x) {
+; CHECK-LABEL: define double @rsq_f64_nnan(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call nnan contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract nnan double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract nnan double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @neg_rsq_f64_nnan(double %x) {
+; CHECK-LABEL: define double @neg_rsq_f64_nnan(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call nnan contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan contract double -1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract nnan double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract nnan double -1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_ninf(double %x) {
+; CHECK-LABEL: define double @rsq_f64_ninf(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call ninf contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv ninf contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract ninf double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract ninf double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @neg_rsq_f64_ninf(double %x) {
+; CHECK-LABEL: define double @neg_rsq_f64_ninf(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call ninf contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv ninf contract double -1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract ninf double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract ninf double -1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_nnan_ninf(double %x) {
+; CHECK-LABEL: define double @rsq_f64_nnan_ninf(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call nnan ninf contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan ninf contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract nnan ninf double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract nnan ninf double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @neg_rsq_f64_nnan_ninf(double %x) {
+; CHECK-LABEL: define double @neg_rsq_f64_nnan_ninf(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call nnan ninf contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan ninf contract double -1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract nnan ninf double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract nnan ninf double -1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_sqrt_nnan_ninf(double %x) {
+; CHECK-LABEL: define double @rsq_f64_sqrt_nnan_ninf(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call nnan ninf contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract nnan ninf double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_fdiv_nnan_ninf(double %x) {
+; CHECK-LABEL: define double @rsq_f64_fdiv_nnan_ninf(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan ninf contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract nnan ninf double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define <2 x double> @rsq_v2f64(<2 x double> %x) {
+; CHECK-LABEL: define <2 x double> @rsq_v2f64(
+; CHECK-SAME: <2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract <2 x double> @llvm.sqrt.v2f64(<2 x double> [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract <2 x double> splat (double 1.000000e+00), [[SQRT_X]]
+; CHECK-NEXT:    ret <2 x double> [[FDIV]]
+;
+  %sqrt.x = call contract <2 x double> @llvm.sqrt.f64(<2 x double> %x)
+  %fdiv = fdiv contract <2 x double> splat (double 1.0), %sqrt.x
+  ret <2 x double> %fdiv
+}
+
+define <2 x double> @neg_rsq_v2f64(<2 x double> %x) {
+; CHECK-LABEL: define <2 x double> @neg_rsq_v2f64(
+; CHECK-SAME: <2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract <2 x double> @llvm.sqrt.v2f64(<2 x double> [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract <2 x double> splat (double 1.000000e+00), [[SQRT_X]]
+; CHECK-NEXT:    ret <2 x double> [[FDIV]]
+;
+  %sqrt.x = call contract <2 x double> @llvm.sqrt.f64(<2 x double> %x)
+  %fdiv = fdiv contract <2 x double> splat (double 1.0), %sqrt.x
+  ret <2 x double> %fdiv
+}
+
+define <2 x double> @mixed_sign_rsq_v2f64(<2 x double> %x) {
+; CHECK-LABEL: define <2 x double> @mixed_sign_rsq_v2f64(
+; CHECK-SAME: <2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract <2 x double> @llvm.sqrt.v2f64(<2 x double> [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract <2 x double> <double 1.000000e+00, double -1.000000e+00>, [[SQRT_X]]
+; CHECK-NEXT:    ret <2 x double> [[FDIV]]
+;
+  %sqrt.x = call contract <2 x double> @llvm.sqrt.f64(<2 x double> %x)
+  %fdiv = fdiv contract <2 x double> <double 1.0, double -1.0>, %sqrt.x
+  ret <2 x double> %fdiv
+}
+
+define <2 x double> @rsq_some_elements_v2f64(<2 x double> %x) {
+; CHECK-LABEL: define <2 x double> @rsq_some_elements_v2f64(
+; CHECK-SAME: <2 x double> [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract <2 x double> @llvm.sqrt.v2f64(<2 x double> [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract <2 x double> <double 1.000000e+00, double 2.000000e+00>, [[SQRT_X]]
+; CHECK-NEXT:    ret <2 x double> [[FDIV]]
+;
+  %sqrt.x = call contract <2 x double> @llvm.sqrt.f64(<2 x double> %x)
+  %fdiv = fdiv contract <2 x double> <double 1.0, double 2.0>, %sqrt.x
+  ret <2 x double> %fdiv
+}
+
+; Negative test
+define double @rsq_f64_missing_contract0(double %x) {
+; CHECK-LABEL: define double @rsq_f64_missing_contract0(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+; Negative test
+define double @rsq_f64_missing_contract1(double %x) {
+; CHECK-LABEL: define double @rsq_f64_missing_contract1(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+declare double @sqrt(double)
+
+define double @rsq_f64_not_sqrt_intrin(double %x) {
+; CHECK-LABEL: define double @rsq_f64_not_sqrt_intrin(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @sqrt(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @sqrt(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rcp_f64(double %x) {
+; CHECK-LABEL: define double @rcp_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv arcp contract double 1.000000e+00, [[X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %fdiv = fdiv contract arcp double 1.0, %x
+  ret double %fdiv
+}
+
+define double @rcp_afn_f64(double %x) {
+; CHECK-LABEL: define double @rcp_afn_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv arcp contract afn double 1.000000e+00, [[X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %fdiv = fdiv contract arcp afn double 1.0, %x
+  ret double %fdiv
+}
+
+define double @neg_rcp_f64(double %x) {
+; CHECK-LABEL: define double @neg_rcp_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv arcp contract double -1.000000e+00, [[X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %fdiv = fdiv contract arcp double -1.0, %x
+  ret double %fdiv
+}
+
+define double @neg_rcp_afn_f64(double %x) {
+; CHECK-LABEL: define double @neg_rcp_afn_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv arcp contract afn double -1.000000e+00, [[X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %fdiv = fdiv contract arcp afn double -1.0, %x
+  ret double %fdiv
+}
+
+; Make sure this doesn't accidentally go down f32 paths
+define double @v_fdiv_f64_ulp25(double %a, double %b) {
+; CHECK-LABEL: define double @v_fdiv_f64_ulp25(
+; CHECK-SAME: double [[A:%.*]], double [[B:%.*]]) {
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv double [[A]], [[B]], !fpmath [[META0:![0-9]+]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %fdiv = fdiv double %a, %b, !fpmath !0
+  ret double %fdiv
+}
+
+; TODO: Handle arcp case
+define double @fdiv_arcp_2_f64(double %x) {
+; CHECK-LABEL: define double @fdiv_arcp_2_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call arcp contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv arcp contract double 2.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call arcp contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv arcp contract double 2.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @fdiv_arcp_var_f64(double %x, double %y) {
+; CHECK-LABEL: define double @fdiv_arcp_var_f64(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call arcp contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv arcp contract double [[Y]], [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call arcp contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv arcp contract double %y, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_amdgcn_f64(double %x) {
+; CHECK-LABEL: define double @rsq_amdgcn_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.amdgcn.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.amdgcn.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @neg_rsq_amdgcn_f64(double %x) {
+; CHECK-LABEL: define double @neg_rsq_amdgcn_f64(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.amdgcn.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double -1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.amdgcn.sqrt.f64(double %x)
+  %fdiv = fdiv contract double -1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_amdgcn_f64_nnan_ninf(double %x) {
+; CHECK-LABEL: define double @rsq_amdgcn_f64_nnan_ninf(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call nnan ninf contract double @llvm.amdgcn.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan ninf contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract nnan ninf double @llvm.amdgcn.sqrt.f64(double %x)
+  %fdiv = fdiv contract nnan ninf double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_input_known_not_zero(double nofpclass(zero) %x) {
+; CHECK-LABEL: define double @rsq_f64_input_known_not_zero(
+; CHECK-SAME: double nofpclass(zero) [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_input_known_not_pinf(double nofpclass(pinf) %x) {
+; CHECK-LABEL: define double @rsq_f64_input_known_not_pinf(
+; CHECK-SAME: double nofpclass(pinf) [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_input_known_not_pinf_zero(double nofpclass(pinf zero) %x) {
+; CHECK-LABEL: define double @rsq_f64_input_known_not_pinf_zero(
+; CHECK-SAME: double nofpclass(pinf zero) [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_input_known_not_pinf_zero_dynamic_fp(double nofpclass(pinf zero) %x) #0 {
+; CHECK-LABEL: define double @rsq_f64_input_known_not_pinf_zero_dynamic_fp(
+; CHECK-SAME: double nofpclass(pinf zero) [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_input_known_not_pinf_zero_daz(double nofpclass(pinf zero) %x) #1 {
+; CHECK-LABEL: define double @rsq_f64_input_known_not_pinf_zero_daz(
+; CHECK-SAME: double nofpclass(pinf zero) [[X:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_input_known_not_pinf_zero_denorm_daz(double nofpclass(pinf zero sub) %x) #1 {
+; CHECK-LABEL: define double @rsq_f64_input_known_not_pinf_zero_denorm_daz(
+; CHECK-SAME: double nofpclass(pinf zero sub) [[X:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_dynamic_denormal(double %x) #0 {
+; CHECK-LABEL: define double @rsq_f64_dynamic_denormal(
+; CHECK-SAME: double [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_dynamic_denormal_no_pinf(double nofpclass(pinf) %x) #0 {
+; CHECK-LABEL: define double @rsq_f64_dynamic_denormal_no_pinf(
+; CHECK-SAME: double nofpclass(pinf) [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_dynamic_denormal_no_zero_no_denorm(double nofpclass(zero sub) %x) #0 {
+; CHECK-LABEL: define double @rsq_f64_dynamic_denormal_no_zero_no_denorm(
+; CHECK-SAME: double nofpclass(zero sub) [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_nnan_sqrt(double %x) {
+; CHECK-LABEL: define double @rsq_f64_nnan_sqrt(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call nnan contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract nnan double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_nnan_fdiv(double %x) {
+; CHECK-LABEL: define double @rsq_f64_nnan_fdiv(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract nnan double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_ninf_sqrt(double %x) {
+; CHECK-LABEL: define double @rsq_f64_ninf_sqrt(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call ninf contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract ninf double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_ninf_fdiv(double %x) {
+; CHECK-LABEL: define double @rsq_f64_ninf_fdiv(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv ninf contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract ninf double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_ninf_sqrt_nnan_fdiv(double %x) {
+; CHECK-LABEL: define double @rsq_f64_ninf_sqrt_nnan_fdiv(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call ninf contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract ninf double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract nnan double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_nann_sqrt_ninf_fdiv(double %x) {
+; CHECK-LABEL: define double @rsq_f64_nann_sqrt_ninf_fdiv(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call nnan contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv ninf contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %sqrt.x = call contract nnan double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract ninf double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+define double @rsq_f64_assume_nonzero(double %x) {
+; CHECK-LABEL: define double @rsq_f64_assume_nonzero(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:    [[NONZERO:%.*]] = fcmp one double [[X]], 0.000000e+00
+; CHECK-NEXT:    call void @llvm.assume(i1 [[NONZERO]])
+; CHECK-NEXT:    [[SQRT_X:%.*]] = call contract double @llvm.sqrt.f64(double [[X]])
+; CHECK-NEXT:    [[FDIV:%.*]] = fdiv contract double 1.000000e+00, [[SQRT_X]]
+; CHECK-NEXT:    ret double [[FDIV]]
+;
+  %nonzero = fcmp one double %x, 0.0
+  call void @llvm.assume(i1 %nonzero)
+  %sqrt.x = call contract double @llvm.sqrt.f64(double %x)
+  %fdiv = fdiv contract double 1.0, %sqrt.x
+  ret double %fdiv
+}
+
+attributes #0 = { "denormal-fp-math"="ieee,dynamic" }
+attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" }
+
+!0 = !{float 2.500000e+00}
+;.
+; CHECK: [[META0]] = !{float 2.500000e+00}
+;.



More information about the llvm-commits mailing list