[llvm] ValueTracking: Add baseline test for amdgcn_rcp handling (PR #172489)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 16 07:01:44 PST 2025


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

None

>From 1963a8eef3d1064b4696d7151b9d0d4340f351de Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 16 Dec 2025 14:34:43 +0100
Subject: [PATCH] ValueTracking: Add baseline test for amdgcn_rcp handling

---
 .../Attributor/AMDGPU/nofpclass-amdgcn-rcp.ll | 430 ++++++++++++++++++
 1 file changed, 430 insertions(+)
 create mode 100644 llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-rcp.ll

diff --git a/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-rcp.ll b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-rcp.ll
new file mode 100644
index 0000000000000..e048d76479752
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-rcp.ll
@@ -0,0 +1,430 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=attributor -attributor-manifest-internal < %s | FileCheck %s
+
+declare half @llvm.amdgcn.rcp.f16(half) #0
+declare float @llvm.amdgcn.rcp.f32(float) #0
+declare double @llvm.amdgcn.rcp.f64(double) #0
+
+define half @ret_rcp_f16(half %arg) {
+; CHECK-LABEL: define half @ret_rcp_f16(
+; CHECK-SAME: half [[ARG:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call half @llvm.amdgcn.rcp.f16(half [[ARG]]) #[[ATTR4:[0-9]+]]
+; CHECK-NEXT:    ret half [[CALL]]
+;
+  %call = call half @llvm.amdgcn.rcp.f16(half %arg)
+  ret half %call
+}
+
+define float @ret_rcp_f32(float %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32(
+; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define double @ret_rcp_f64(double %arg) {
+; CHECK-LABEL: define double @ret_rcp_f64(
+; CHECK-SAME: double [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.amdgcn.rcp.f64(double [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret double [[CALL]]
+;
+  %call = call double @llvm.amdgcn.rcp.f64(double %arg)
+  ret double %call
+}
+
+define float @ret_rcp_f32_dynamic_denormal_input(float %arg) #1 {
+; CHECK-LABEL: define float @ret_rcp_f32_dynamic_denormal_input(
+; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2:[0-9]+]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_dynamic_denormal_input_known_nzero(float nofpclass(nzero) %arg) #1 {
+; CHECK-LABEL: define float @ret_rcp_f32_dynamic_denormal_input_known_nzero(
+; CHECK-SAME: float nofpclass(nzero) [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nzero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_dynamic_denormal_input_known_nzero_nsub(float nofpclass(nzero nsub) %arg) #1 {
+; CHECK-LABEL: define float @ret_rcp_f32_dynamic_denormal_input_known_nzero_nsub(
+; CHECK-SAME: float nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nzero nsub) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define double @ret_rcp_f64_dynamic_denormal_input(double %arg) #2 {
+; CHECK-LABEL: define double @ret_rcp_f64_dynamic_denormal_input(
+; CHECK-SAME: double [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.amdgcn.rcp.f64(double [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret double [[CALL]]
+;
+  %call = call double @llvm.amdgcn.rcp.f64(double %arg)
+  ret double %call
+}
+
+define double @ret_rcp_f64_dynamic_denormal_input_known_nzero(double nofpclass(nzero) %arg) #1 {
+; CHECK-LABEL: define double @ret_rcp_f64_dynamic_denormal_input_known_nzero(
+; CHECK-SAME: double nofpclass(nzero) [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.amdgcn.rcp.f64(double nofpclass(nzero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret double [[CALL]]
+;
+  %call = call double @llvm.amdgcn.rcp.f64(double %arg)
+  ret double %call
+}
+
+define double @ret_rcp_f64_dynamic_denormal_input_known_nzero_nsub(double nofpclass(nzero nsub) %arg) #1 {
+; CHECK-LABEL: define double @ret_rcp_f64_dynamic_denormal_input_known_nzero_nsub(
+; CHECK-SAME: double nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.amdgcn.rcp.f64(double nofpclass(nzero nsub) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret double [[CALL]]
+;
+  %call = call double @llvm.amdgcn.rcp.f64(double %arg)
+  ret double %call
+}
+
+define float @ret_rcp_f32__no_snan_input(float nofpclass(snan) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32__no_snan_input(
+; CHECK-SAME: float nofpclass(snan) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(snan) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_nsz(float %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_nsz(
+; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nsz float @llvm.amdgcn.rcp.f32(float [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call nsz float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_nnan_flag(float %arg) {
+; CHECK-LABEL: define nofpclass(nan) float @ret_rcp_f32_nnan_flag(
+; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nnan nofpclass(nan) float @llvm.amdgcn.rcp.f32(float [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call nnan float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_ninf_flag(float %arg) {
+; CHECK-LABEL: define nofpclass(inf) float @ret_rcp_f32_ninf_flag(
+; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call ninf nofpclass(inf) float @llvm.amdgcn.rcp.f32(float [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call ninf float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_nnan_ninf_flag(float %arg) {
+; CHECK-LABEL: define nofpclass(nan inf) float @ret_rcp_f32_nnan_ninf_flag(
+; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) float @llvm.amdgcn.rcp.f32(float [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call nnan ninf float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_neg_zero(float nofpclass(nzero) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_neg_zero(
+; CHECK-SAME: float nofpclass(nzero) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nzero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_pos_zero(float nofpclass(pzero) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_pos_zero(
+; CHECK-SAME: float nofpclass(pzero) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(pzero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_zero(float nofpclass(zero) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_zero(
+; CHECK-SAME: float nofpclass(zero) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(zero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_zero_dynamic_denorm(float nofpclass(zero) %arg) #2 {
+; CHECK-LABEL: define float @ret_rcp_f32_known_zero_dynamic_denorm(
+; CHECK-SAME: float nofpclass(zero) [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(zero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_nzero_dynamic_denorm(float nofpclass(nzero) %arg) #2 {
+; CHECK-LABEL: define float @ret_rcp_f32_known_nzero_dynamic_denorm(
+; CHECK-SAME: float nofpclass(nzero) [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nzero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_pzero_dynamic_denorm(float nofpclass(pzero) %arg) #2 {
+; CHECK-LABEL: define float @ret_rcp_f32_known_pzero_dynamic_denorm(
+; CHECK-SAME: float nofpclass(pzero) [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(pzero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_not_pzero_dynamic_denorm(float nofpclass(pzero psub) %arg) #2 {
+; CHECK-LABEL: define float @ret_rcp_f32_known_not_pzero_dynamic_denorm(
+; CHECK-SAME: float nofpclass(pzero psub) [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(pzero psub) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_not_nzero_dynamic_denorm(float nofpclass(nzero nsub) %arg) #2 {
+; CHECK-LABEL: define float @ret_rcp_f32_known_not_nzero_dynamic_denorm(
+; CHECK-SAME: float nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nzero nsub) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_nan(float nofpclass(nan) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_nan(
+; CHECK-SAME: float nofpclass(nan) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nsz float @llvm.amdgcn.rcp.f32(float nofpclass(nan) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call nsz float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_inf(float nofpclass(inf) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_inf(
+; CHECK-SAME: float nofpclass(inf) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(inf) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_nan_no_inf(float nofpclass(nan inf) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_nan_no_inf(
+; CHECK-SAME: float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nan inf) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_poison() {
+; CHECK-LABEL: define float @ret_rcp_f32_poison(
+; CHECK-SAME: ) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float poison) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float poison)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_neg_normal_no_neg_subnormal(float nofpclass(nsub nnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_neg_normal_no_neg_subnormal(
+; CHECK-SAME: float nofpclass(nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nsub nnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_neg_normal_no_neg_subnormal_no_neg_inf(float nofpclass(ninf nsub nnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_neg_normal_no_neg_subnormal_no_neg_inf(
+; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(ninf nsub nnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_neg_normal_no_neg_subnormal_no_neg_inf_no_neg_zero(float nofpclass(ninf nzero nsub nnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_neg_normal_no_neg_subnormal_no_neg_inf_no_neg_zero(
+; CHECK-SAME: float nofpclass(ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(ninf nzero nsub nnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_no_neg_normal_no_neg_subnormal_no_neg_inf_no_nan(float nofpclass(nan ninf nsub nnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_no_neg_normal_no_neg_subnormal_no_neg_inf_no_nan(
+; CHECK-SAME: float nofpclass(nan ninf nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nan ninf nsub nnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_nnan_known_no_neg_normal_no_neg_subnormal_no_neg_inf(float nofpclass(ninf nsub nnorm) %arg) {
+; CHECK-LABEL: define nofpclass(nan) float @ret_rcp_f32_nnan_known_no_neg_normal_no_neg_subnormal_no_neg_inf(
+; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nnan nofpclass(nan) float @llvm.amdgcn.rcp.f32(float nofpclass(ninf nsub nnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call nnan float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_dynamic_denormal_input_known_pzero(float nofpclass(pzero) %arg) #1 {
+; CHECK-LABEL: define float @ret_rcp_f32_dynamic_denormal_input_known_pzero(
+; CHECK-SAME: float nofpclass(pzero) [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(pzero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_dynamic_denormal_input_known_pzero_psub(float nofpclass(pzero) %arg) #2 {
+; CHECK-LABEL: define float @ret_rcp_f32_dynamic_denormal_input_known_pzero_psub(
+; CHECK-SAME: float nofpclass(pzero) [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(pzero) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define double @ret_rcp_f64_known_not_pinf(double nofpclass(pinf) %arg) {
+; CHECK-LABEL: define double @ret_rcp_f64_known_not_pinf(
+; CHECK-SAME: double nofpclass(pinf) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.amdgcn.rcp.f64(double nofpclass(pinf) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret double [[CALL]]
+;
+  %call = call double @llvm.amdgcn.rcp.f64(double %arg)
+  ret double %call
+}
+
+define double @ret_rcp_f64_known_not_ninf(double nofpclass(ninf) %arg) {
+; CHECK-LABEL: define double @ret_rcp_f64_known_not_ninf(
+; CHECK-SAME: double nofpclass(ninf) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.amdgcn.rcp.f64(double nofpclass(ninf) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret double [[CALL]]
+;
+  %call = call double @llvm.amdgcn.rcp.f64(double %arg)
+  ret double %call
+}
+
+define double @ret_rcp_f64_known_not_inf(double nofpclass(inf) %arg) {
+; CHECK-LABEL: define double @ret_rcp_f64_known_not_inf(
+; CHECK-SAME: double nofpclass(inf) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.amdgcn.rcp.f64(double nofpclass(inf) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret double [[CALL]]
+;
+  %call = call double @llvm.amdgcn.rcp.f64(double %arg)
+  ret double %call
+}
+
+define float @ret_rcp_f32_known_positive(float nofpclass(ninf nzero nsub nnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_positive(
+; CHECK-SAME: float nofpclass(ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(ninf nzero nsub nnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_negative(float nofpclass(pinf pzero psub pnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_negative(
+; CHECK-SAME: float nofpclass(pinf pzero psub pnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(pinf pzero psub pnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_positive_except_zero(float nofpclass(ninf nsub nnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_positive_except_zero(
+; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(ninf nsub nnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_negative_except_zero(float nofpclass(pinf psub pnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_negative_except_zero(
+; CHECK-SAME: float nofpclass(pinf psub pnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(pinf psub pnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_positive_not_nan(float nofpclass(nan ninf nzero nsub nnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_positive_not_nan(
+; CHECK-SAME: float nofpclass(nan ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nan ninf nzero nsub nnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+define float @ret_rcp_f32_known_negative_not_nan(float nofpclass(nan pinf pzero psub pnorm) %arg) {
+; CHECK-LABEL: define float @ret_rcp_f32_known_negative_not_nan(
+; CHECK-SAME: float nofpclass(nan pinf pzero psub pnorm) [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.amdgcn.rcp.f32(float nofpclass(nan pinf pzero psub pnorm) [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.amdgcn.rcp.f32(float %arg)
+  ret float %call
+}
+
+attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #1 = { "denormal-fp-math-f32"="ieee,dynamic" }
+attributes #2 = { "denormal-fp-math"="ieee,dynamic" }



More information about the llvm-commits mailing list