diff --git a/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-rsq.ll b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-rsq.ll new file mode 100644 index 0000000000000..91b72c8873073 --- /dev/null +++ b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-rsq.ll @@ -0,0 +1,290 @@ +; 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.rsq.f16(half) +declare float @llvm.amdgcn.rsq.f32(float) +declare double @llvm.amdgcn.rsq.f64(double) + +define half @ret_rsq_f16(half %arg) { +; CHECK-LABEL: define half @ret_rsq_f16( +; CHECK-SAME: half [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.amdgcn.rsq.f16(half [[ARG]]) #[[ATTR4:[0-9]+]] +; CHECK-NEXT: ret half [[CALL]] +; + %call = call half @llvm.amdgcn.rsq.f16(half %arg) + ret half %call +} + +define float @ret_rsq_f32(float %arg) { +; CHECK-LABEL: define float @ret_rsq_f32( +; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define double @ret_rsq_f64(double %arg) { +; CHECK-LABEL: define double @ret_rsq_f64( +; CHECK-SAME: double [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.amdgcn.rsq.f64(double [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret double [[CALL]] +; + %call = call double @llvm.amdgcn.rsq.f64(double %arg) + ret double %call +} + +; Result could still be -0 if negative argument is flushed. +define float @ret_rsq_f32_dynamic_denormal_input(float %arg) #0 { +; CHECK-LABEL: define float @ret_rsq_f32_dynamic_denormal_input( +; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2:[0-9]+]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_dynamic_denormal_input_known_nzero(float nofpclass(nzero) %arg) #0 { +; CHECK-LABEL: define float @ret_rsq_f32_dynamic_denormal_input_known_nzero( +; CHECK-SAME: float nofpclass(nzero) [[ARG:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(nzero) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_dynamic_denormal_input_known_nzero_nsub(float nofpclass(nzero nsub) %arg) #0 { +; CHECK-LABEL: define float @ret_rsq_f32_dynamic_denormal_input_known_nzero_nsub( +; CHECK-SAME: float nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(nzero nsub) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define double @ret_rsq_f64_dynamic_denormal_input(double %arg) #1 { +; CHECK-LABEL: define double @ret_rsq_f64_dynamic_denormal_input( +; CHECK-SAME: double [[ARG:%.*]]) #[[ATTR3:[0-9]+]] { +; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.amdgcn.rsq.f64(double [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret double [[CALL]] +; + %call = call double @llvm.amdgcn.rsq.f64(double %arg) + ret double %call +} + +define double @ret_rsq_f64_dynamic_denormal_input_known_nzero(double nofpclass(nzero) %arg) #0 { +; CHECK-LABEL: define double @ret_rsq_f64_dynamic_denormal_input_known_nzero( +; CHECK-SAME: double nofpclass(nzero) [[ARG:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.amdgcn.rsq.f64(double nofpclass(nzero) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret double [[CALL]] +; + %call = call double @llvm.amdgcn.rsq.f64(double %arg) + ret double %call +} + +define double @ret_rsq_f64_dynamic_denormal_input_known_nzero_nsub(double nofpclass(nzero nsub) %arg) #0 { +; CHECK-LABEL: define double @ret_rsq_f64_dynamic_denormal_input_known_nzero_nsub( +; CHECK-SAME: double nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.amdgcn.rsq.f64(double nofpclass(nzero nsub) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret double [[CALL]] +; + %call = call double @llvm.amdgcn.rsq.f64(double %arg) + ret double %call +} + +define float @ret_rsq_f32__no_snan_input(float nofpclass(snan) %arg) { +; CHECK-LABEL: define float @ret_rsq_f32__no_snan_input( +; CHECK-SAME: float nofpclass(snan) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(snan) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_nsz(float %arg) { +; CHECK-LABEL: define float @ret_rsq_f32_nsz( +; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call nsz float @llvm.amdgcn.rsq.f32(float [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call nsz float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_known_no_neg_zero(float nofpclass(nzero) %arg) { +; CHECK-LABEL: define float @ret_rsq_f32_known_no_neg_zero( +; CHECK-SAME: float nofpclass(nzero) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(nzero) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_known_no_pos_zero(float nofpclass(pzero) %arg) { +; CHECK-LABEL: define float @ret_rsq_f32_known_no_pos_zero( +; CHECK-SAME: float nofpclass(pzero) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(pzero) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define double @ret_rsq_f64_known_zero(double nofpclass(zero) %arg) { +; CHECK-LABEL: define double @ret_rsq_f64_known_zero( +; CHECK-SAME: double nofpclass(zero) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.amdgcn.rsq.f64(double nofpclass(zero) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret double [[CALL]] +; + %call = call double @llvm.amdgcn.rsq.f64(double %arg) + ret double %call +} + +define float @ret_rsq_f32_known_no_nan(float nofpclass(nan) %arg) { +; CHECK-LABEL: define float @ret_rsq_f32_known_no_nan( +; CHECK-SAME: float nofpclass(nan) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call nsz float @llvm.amdgcn.rsq.f32(float nofpclass(nan) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call nsz float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_known_no_inf(float nofpclass(inf) %arg) { +; CHECK-LABEL: define float @ret_rsq_f32_known_no_inf( +; CHECK-SAME: float nofpclass(inf) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(inf) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_known_no_nan_no_inf(float nofpclass(nan inf) %arg) { +; CHECK-LABEL: define float @ret_rsq_f32_known_no_nan_no_inf( +; CHECK-SAME: float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(nan inf) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_poison() { +; CHECK-LABEL: define float @ret_rsq_f32_poison( +; CHECK-SAME: ) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float poison) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float poison) + ret float %call +} + +define float @ret_rsq_f32_known_no_neg_normal_no_neg_subnormal(float nofpclass(nsub nnorm) %arg) { +; CHECK-LABEL: define float @ret_rsq_f32_known_no_neg_normal_no_neg_subnormal( +; CHECK-SAME: float nofpclass(nsub nnorm) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(nsub nnorm) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_known_no_neg_normal_no_neg_subnormal_no_neg_inf(float nofpclass(ninf nsub nnorm) %arg) { +; CHECK-LABEL: define float @ret_rsq_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.rsq.f32(float nofpclass(ninf nsub nnorm) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_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_rsq_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.rsq.f32(float nofpclass(ninf nzero nsub nnorm) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_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_rsq_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.rsq.f32(float nofpclass(nan ninf nsub nnorm) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_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_rsq_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.rsq.f32(float nofpclass(ninf nsub nnorm) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call nnan float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_dynamic_denormal_input_known_pzero(float nofpclass(pzero) %arg) #0 { +; CHECK-LABEL: define float @ret_rsq_f32_dynamic_denormal_input_known_pzero( +; CHECK-SAME: float nofpclass(pzero) [[ARG:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(pzero) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define float @ret_rsq_f32_dynamic_denormal_input_known_pzero_psub(float nofpclass(pzero) %arg) #1 { +; CHECK-LABEL: define float @ret_rsq_f32_dynamic_denormal_input_known_pzero_psub( +; CHECK-SAME: float nofpclass(pzero) [[ARG:%.*]]) #[[ATTR3]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.rsq.f32(float nofpclass(pzero) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.rsq.f32(float %arg) + ret float %call +} + +define double @ret_rsq_f64_known_not_pinf(double nofpclass(pinf) %arg) { +; CHECK-LABEL: define double @ret_rsq_f64_known_not_pinf( +; CHECK-SAME: double nofpclass(pinf) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.amdgcn.rsq.f64(double nofpclass(pinf) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret double [[CALL]] +; + %call = call double @llvm.amdgcn.rsq.f64(double %arg) + ret double %call +} + +define double @ret_rsq_f64_known_not_ninf(double nofpclass(ninf) %arg) { +; CHECK-LABEL: define double @ret_rsq_f64_known_not_ninf( +; CHECK-SAME: double nofpclass(ninf) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.amdgcn.rsq.f64(double nofpclass(ninf) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret double [[CALL]] +; + %call = call double @llvm.amdgcn.rsq.f64(double %arg) + ret double %call +} + +define double @ret_rsq_f64_known_not_inf(double nofpclass(inf) %arg) { +; CHECK-LABEL: define double @ret_rsq_f64_known_not_inf( +; CHECK-SAME: double nofpclass(inf) [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.amdgcn.rsq.f64(double nofpclass(inf) [[ARG]]) #[[ATTR4]] +; CHECK-NEXT: ret double [[CALL]] +; + %call = call double @llvm.amdgcn.rsq.f64(double %arg) + ret double %call +} + +attributes #0 = { "denormal-fp-math-f32"="ieee,dynamic" } +attributes #1 = { "denormal-fp-math"="ieee,dynamic" }