https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/173882
>From 4c21a908683908767fda0b4e61804a285c3cdde7 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Tue, 23 Dec 2025 20:39:02 +0100 Subject: [PATCH] InstCombine: Add baseline tests for sqrt SimplifyDemandedFPClass --- .../simplify-demanded-fpclass-sqrt.ll | 206 ++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll new file mode 100644 index 0000000000000..9288bb7be3ecd --- /dev/null +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll @@ -0,0 +1,206 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 +; RUN: opt -S -passes=instcombine < %s | FileCheck %s + +declare float @func() + +declare nofpclass(ninf nnorm nsub nzero nan) float @returns_positive() +declare nofpclass(ninf nnorm nsub nzero) float @returns_positive_or_nan() + +declare nofpclass(pinf pnorm psub pzero nan) float @returns_negative() +declare nofpclass(pinf pnorm psub pzero) float @returns_negative_or_nan() + +declare nofpclass(pinf pnorm psub zero nan) float @returns_negative_nonzero() +declare nofpclass(pinf pnorm psub zero nan) <2 x float> @returns_negative_nonzero_vec() +declare nofpclass(pinf pnorm psub zero) float @returns_negative_nonzero_or_nan() + + +; -> qnan +define nofpclass(inf norm sub zero) float @ret_only_nan_sqrt(float %x) { +; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_only_nan_sqrt( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[X]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float @llvm.sqrt.f32(float %x) + ret float %result +} + +; -> copysign(0, x) +; https://alive2.llvm.org/ce/z/ab5wX8 +define nofpclass(inf nan norm sub) float @ret_only_zero_sqrt(float %x) { +; CHECK-LABEL: define nofpclass(nan inf sub norm) float @ret_only_zero_sqrt( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[X]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float @llvm.sqrt.f32(float %x) + ret float %result +} + +define nofpclass(inf nan norm sub) <2 x float> @ret_only_zero_sqrt_vec(<2 x float> %x) { +; CHECK-LABEL: define nofpclass(nan inf sub norm) <2 x float> @ret_only_zero_sqrt_vec( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> [[X]]) +; CHECK-NEXT: ret <2 x float> [[RESULT]] +; + %result = call <2 x float> @llvm.sqrt.v2f32(<2 x float> %x) + ret <2 x float> %result +} + +; -> pinf +define nofpclass(nan norm sub zero) float @ret_only_inf_sqrt(float %x) { +; CHECK-LABEL: define nofpclass(nan zero sub norm) float @ret_only_inf_sqrt( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: ret float 0x7FF0000000000000 +; + %result = call float @llvm.sqrt.f32(float %x) + ret float %result +} + +define nofpclass(norm sub zero) float @ret_only_inf_nan_sqrt(float %x) { +; CHECK-LABEL: define nofpclass(zero sub norm) float @ret_only_inf_nan_sqrt( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[X]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %result = call float @llvm.sqrt.f32(float %x) + ret float %result +} + +; Could still be -0 +define nofpclass(ninf) float @ret_only_ninf__sqrt__known_negative() { +; CHECK-LABEL: define nofpclass(ninf) float @ret_only_ninf__sqrt__known_negative() { +; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative() +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[KNOWN_NEGATIVE]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %known.negative = call float @returns_negative() + %result = call float @llvm.sqrt.f32(float %known.negative) + ret float %result +} + +; -> qnan +define nofpclass(ninf) float @ret_only_ninf__sqrt__known_negative_nonzero() { +; CHECK-LABEL: define nofpclass(ninf) float @ret_only_ninf__sqrt__known_negative_nonzero() { +; CHECK-NEXT: [[KNOWN_NEGATIVE_NONZERO:%.*]] = call float @returns_negative_nonzero() +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[KNOWN_NEGATIVE_NONZERO]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %known.negative.nonzero = call float @returns_negative_nonzero() + %result = call float @llvm.sqrt.f32(float %known.negative.nonzero) + ret float %result +} + +; -> qnan +define nofpclass(ninf) <2 x float> @ret_only_ninf__sqrt__known_negative_nonzero_vec() { +; CHECK-LABEL: define nofpclass(ninf) <2 x float> @ret_only_ninf__sqrt__known_negative_nonzero_vec() { +; CHECK-NEXT: [[KNOWN_NEGATIVE_NONZERO:%.*]] = call <2 x float> @returns_negative_nonzero_vec() +; CHECK-NEXT: [[RESULT:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> [[KNOWN_NEGATIVE_NONZERO]]) +; CHECK-NEXT: ret <2 x float> [[RESULT]] +; + %known.negative.nonzero = call <2 x float> @returns_negative_nonzero_vec() + %result = call <2 x float> @llvm.sqrt.v2f32(<2 x float> %known.negative.nonzero) + ret <2 x float> %result +} + +; The negative subnormal may be flushed to -0, which returns a non-nan result. +define nofpclass(ninf) float @ret_only_ninf__sqrt__known_negative_nonzero_daz() #0 { +; CHECK-LABEL: define nofpclass(ninf) float @ret_only_ninf__sqrt__known_negative_nonzero_daz( +; CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[KNOWN_NEGATIVE_NONZERO:%.*]] = call float @returns_negative_nonzero() +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[KNOWN_NEGATIVE_NONZERO]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %known.negative.nonzero = call float @returns_negative_nonzero() + %result = call float @llvm.sqrt.f32(float %known.negative.nonzero) + ret float %result +} + +; The negative subnormal may be flushed to -0, which returns a non-nan result. +define nofpclass(ninf) float @ret_only_ninf__sqrt__known_negative_nonzero_dynamic() #1 { +; CHECK-LABEL: define nofpclass(ninf) float @ret_only_ninf__sqrt__known_negative_nonzero_dynamic( +; CHECK-SAME: ) #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: [[KNOWN_NEGATIVE_NONZERO:%.*]] = call float @returns_negative_nonzero() +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[KNOWN_NEGATIVE_NONZERO]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %known.negative.nonzero = call float @returns_negative_nonzero() + %result = call float @llvm.sqrt.f32(float %known.negative.nonzero) + ret float %result +} + +; Cannot fold select. Demanded nan results demand negative inputs. +define nofpclass(inf norm zero) float @ret_only_nan_or_sub__sqrt__select_unknown_or_known_neg_nonzero(i1 %cond, float %x) { +; CHECK-LABEL: define nofpclass(inf zero norm) float @ret_only_nan_or_sub__sqrt__select_unknown_or_known_neg_nonzero( +; CHECK-SAME: i1 [[COND:%.*]], float [[X:%.*]]) { +; CHECK-NEXT: [[KNOWN_NEGATIVE_NONZERO:%.*]] = call float @returns_negative_nonzero() +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float [[KNOWN_NEGATIVE_NONZERO]] +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %known.negative.nonzero = call float @returns_negative_nonzero() + %select = select i1 %cond, float %x, float %known.negative.nonzero + %result = call float @llvm.sqrt.f32(float %select) + ret float %result +} + +; Cannot fold select. Demanded nan results permits negative infinity +define nofpclass(inf norm zero) float @ret_only_nan_or_sub__sqrt__select_unknown_or_maybe_ninf(i1 %cond, float nofpclass(nan) %x) { +; CHECK-LABEL: define nofpclass(inf zero norm) float @ret_only_nan_or_sub__sqrt__select_unknown_or_maybe_ninf( +; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[X:%.*]]) { +; CHECK-NEXT: [[MAYBE_NINF:%.*]] = call nofpclass(nan pinf sub norm) float @func() +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float [[MAYBE_NINF]] +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %maybe.ninf = call nofpclass(pinf norm sub nan) float @func() + %select = select i1 %cond, float %x, float %maybe.ninf + %result = call float @llvm.sqrt.f32(float %select) + ret float %result +} + +; Cannot fold select. Demanded nan results permits negative normals +define nofpclass(inf norm zero) float @ret_only_nan_or_sub__sqrt__select_unknown_or_maybe_nnorm(i1 %cond, float nofpclass(nan) %x) { +; CHECK-LABEL: define nofpclass(inf zero norm) float @ret_only_nan_or_sub__sqrt__select_unknown_or_maybe_nnorm( +; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[X:%.*]]) { +; CHECK-NEXT: [[MAYBE_NNORM:%.*]] = call nofpclass(nan inf sub pnorm) float @func() +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float [[MAYBE_NNORM]] +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %maybe.nnorm = call nofpclass(inf pnorm sub nan) float @func() + %select = select i1 %cond, float %x, float %maybe.nnorm + %result = call float @llvm.sqrt.f32(float %select) + ret float %result +} + +; Cannot fold select. Demanded nan results permits negative subnormals +define nofpclass(inf norm zero) float @ret_only_nan_or_sub__sqrt__select_unknown_or_maybe_nsub(i1 %cond, float nofpclass(nan) %x) { +; CHECK-LABEL: define nofpclass(inf zero norm) float @ret_only_nan_or_sub__sqrt__select_unknown_or_maybe_nsub( +; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[X:%.*]]) { +; CHECK-NEXT: [[MAYBE_NSUB:%.*]] = call nofpclass(nan inf psub norm) float @func() +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float [[MAYBE_NSUB]] +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %maybe.nsub = call nofpclass(inf norm psub nan) float @func() + %select = select i1 %cond, float %x, float %maybe.nsub + %result = call float @llvm.sqrt.f32(float %select) + ret float %result +} + +; -> sqrt +define nofpclass(pinf) float @no_pinf_result_implies_no_pinf_source(i1 %cond, float %unknown) { +; CHECK-LABEL: define nofpclass(pinf) float @no_pinf_result_implies_no_pinf_source( +; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) { +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[UNKNOWN]], float 0x7FF0000000000000 +; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]]) +; CHECK-NEXT: ret float [[RESULT]] +; + %select = select i1 %cond, float %unknown, float 0x7ff0000000000000 + %result = call float @llvm.sqrt.f32(float %select) + ret float %result +} + +attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" } +attributes #1 = { "denormal-fp-math"="dynamic,dynamic" } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
