[llvm] [InstSimplify] Fold poison/nnan/ninf on @llvm.sqrt (PR #141821)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Wed May 28 11:46:52 PDT 2025
https://github.com/lukel97 created https://github.com/llvm/llvm-project/pull/141821
I noticed this when a sqrt produced by VectorCombine with a poison operand wasn't getting folded away to poison.
This patch calls simplifyFPOp to simplify sqrt, similar to fma/fmuladd, and folds poison as well as nnan/ninf with nan/inf.
There's a lot of other FP intrinsics that probably need to go through this. And most intrinsics in general could probably be folded to poison if one of their arguments are poison too. Are there any exceptions to this we need to be aware of?
>From de445949df136729993cadd9c0c6fea9c49ad0c2 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Wed, 28 May 2025 19:25:57 +0100
Subject: [PATCH 1/2] Precommit tests
---
.../InstSimplify/fp-undef-poison.ll | 45 +++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll b/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll
index cb2026df962c8..59d9925adf8ed 100644
--- a/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll
+++ b/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll
@@ -293,3 +293,48 @@ define double @fmul_nnan_inf_op1(double %x) {
%r = fmul nnan double %x, 0xfff0000000000000
ret double %r
}
+
+define float @sqrt_poison() {
+; CHECK-LABEL: @sqrt_poison(
+; CHECK-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float poison)
+; CHECK-NEXT: ret float [[SQRT]]
+;
+ %sqrt = call float @llvm.sqrt(float poison)
+ ret float %sqrt
+}
+
+define <2 x float> @sqrt_poison_fixed_vec() {
+; CHECK-LABEL: @sqrt_poison_fixed_vec(
+; CHECK-NEXT: [[SQRT:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> poison)
+; CHECK-NEXT: ret <2 x float> [[SQRT]]
+;
+ %sqrt = call <2 x float> @llvm.sqrt(<2 x float> poison)
+ ret <2 x float> %sqrt
+}
+
+define <vscale x 2 x float> @sqrt_poison_scalable_vec() {
+; CHECK-LABEL: @sqrt_poison_scalable_vec(
+; CHECK-NEXT: [[SQRT:%.*]] = call <vscale x 2 x float> @llvm.sqrt.nxv2f32(<vscale x 2 x float> poison)
+; CHECK-NEXT: ret <vscale x 2 x float> [[SQRT]]
+;
+ %sqrt = call <vscale x 2 x float> @llvm.sqrt(<vscale x 2 x float> poison)
+ ret <vscale x 2 x float> %sqrt
+}
+
+define float @sqrt_nnan_nan() {
+; CHECK-LABEL: @sqrt_nnan_nan(
+; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float 0x7FF8000000000000)
+; CHECK-NEXT: ret float [[SQRT]]
+;
+ %sqrt = call nnan float @llvm.sqrt(float 0x7ff8000000000000)
+ ret float %sqrt
+}
+
+define float @sqrt_ninf_inf() {
+; CHECK-LABEL: @sqrt_ninf_inf(
+; CHECK-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float 0xFFF0000000000000)
+; CHECK-NEXT: ret float [[SQRT]]
+;
+ %sqrt = call ninf float @llvm.sqrt(float 0xfff0000000000000)
+ ret float %sqrt
+}
>From bb2a84af9ce03abc0248dbfbfdbde82c42b6117d Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Wed, 28 May 2025 19:44:37 +0100
Subject: [PATCH 2/2] [InstSimplify] Fold poison/nnan/ninf on @llvm.sqrt
I noticed this when a sqrt produced by VectorCombine with a poison operand wasn't getting folded away to poison.
This patch calls simplifyFPOp to simplify sqrt, similar to fma/fmuladd, and folds poison as well as nnan/ninf with nan/inf.
There's a lot of other FP intrinsics that probably need to go through this. And most intrinsics in general could probably be folded to poison if one of their arguments are poison too. Are there any exceptions to this we need to be aware of?
---
llvm/lib/Analysis/InstructionSimplify.cpp | 5 +++++
.../Transforms/InstSimplify/fp-undef-poison.ll | 15 +++++----------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 23e147ba8c6a1..f4d1bfb1e9554 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6306,6 +6306,11 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
if (computeKnownFPSignBit(Op0, /*Depth=*/0, Q) == false)
return Op0;
break;
+ case Intrinsic::sqrt:
+ if (Value *V = simplifyFPOp(Op0, Call->getFastMathFlags(), Q, fp::ebIgnore,
+ RoundingMode::NearestTiesToEven))
+ return V;
+ break;
case Intrinsic::bswap:
// bswap(bswap(x)) -> x
if (match(Op0, m_BSwap(m_Value(X))))
diff --git a/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll b/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll
index 59d9925adf8ed..537473873486e 100644
--- a/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll
+++ b/llvm/test/Transforms/InstSimplify/fp-undef-poison.ll
@@ -296,8 +296,7 @@ define double @fmul_nnan_inf_op1(double %x) {
define float @sqrt_poison() {
; CHECK-LABEL: @sqrt_poison(
-; CHECK-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float poison)
-; CHECK-NEXT: ret float [[SQRT]]
+; CHECK-NEXT: ret float poison
;
%sqrt = call float @llvm.sqrt(float poison)
ret float %sqrt
@@ -305,8 +304,7 @@ define float @sqrt_poison() {
define <2 x float> @sqrt_poison_fixed_vec() {
; CHECK-LABEL: @sqrt_poison_fixed_vec(
-; CHECK-NEXT: [[SQRT:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> poison)
-; CHECK-NEXT: ret <2 x float> [[SQRT]]
+; CHECK-NEXT: ret <2 x float> poison
;
%sqrt = call <2 x float> @llvm.sqrt(<2 x float> poison)
ret <2 x float> %sqrt
@@ -314,8 +312,7 @@ define <2 x float> @sqrt_poison_fixed_vec() {
define <vscale x 2 x float> @sqrt_poison_scalable_vec() {
; CHECK-LABEL: @sqrt_poison_scalable_vec(
-; CHECK-NEXT: [[SQRT:%.*]] = call <vscale x 2 x float> @llvm.sqrt.nxv2f32(<vscale x 2 x float> poison)
-; CHECK-NEXT: ret <vscale x 2 x float> [[SQRT]]
+; CHECK-NEXT: ret <vscale x 2 x float> poison
;
%sqrt = call <vscale x 2 x float> @llvm.sqrt(<vscale x 2 x float> poison)
ret <vscale x 2 x float> %sqrt
@@ -323,8 +320,7 @@ define <vscale x 2 x float> @sqrt_poison_scalable_vec() {
define float @sqrt_nnan_nan() {
; CHECK-LABEL: @sqrt_nnan_nan(
-; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float 0x7FF8000000000000)
-; CHECK-NEXT: ret float [[SQRT]]
+; CHECK-NEXT: ret float poison
;
%sqrt = call nnan float @llvm.sqrt(float 0x7ff8000000000000)
ret float %sqrt
@@ -332,8 +328,7 @@ define float @sqrt_nnan_nan() {
define float @sqrt_ninf_inf() {
; CHECK-LABEL: @sqrt_ninf_inf(
-; CHECK-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float 0xFFF0000000000000)
-; CHECK-NEXT: ret float [[SQRT]]
+; CHECK-NEXT: ret float poison
;
%sqrt = call ninf float @llvm.sqrt(float 0xfff0000000000000)
ret float %sqrt
More information about the llvm-commits
mailing list