[llvm] InstCombine: Handle extractelement in SimplifyDemandedFPClass (PR #174081)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 31 02:30:03 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
A lot of boilerplate changes are necessary to do proper elementwise
tracking like SimplifyDemandedBits
---
Full diff: https://github.com/llvm/llvm-project/pull/174081.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (+6)
- (added) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-extractelement.ll (+120)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 85672cdfe1377..26243c34a8fa7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2280,6 +2280,12 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
Known = KnownLHS | KnownRHS;
break;
}
+ case Instruction::ExtractElement: {
+ // TODO: Handle demanded element mask
+ if (SimplifyDemandedFPClass(I, 0, DemandedMask, Known, Depth + 1))
+ return I;
+ break;
+ }
default:
Known = computeKnownFPClass(I, DemandedMask, CxtI, Depth + 1);
break;
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-extractelement.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-extractelement.ll
new file mode 100644
index 0000000000000..e571774c72f2b
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-extractelement.ll
@@ -0,0 +1,120 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+declare nofpclass(inf norm sub zero) <4 x half> @returns_nan()
+declare nofpclass(nan norm sub zero) <4 x half> @returns_inf()
+
+define nofpclass(inf norm sub zero) half @ret_only_nan__extractelement_unknown(<4 x half> %vec, i32 %idx) {
+; CHECK-LABEL: define nofpclass(inf zero sub norm) half @ret_only_nan__extractelement_unknown(
+; CHECK-SAME: <4 x half> [[VEC:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: [[EXT:%.*]] = extractelement <4 x half> [[VEC]], i32 [[IDX]]
+; CHECK-NEXT: ret half [[EXT]]
+;
+ %ext = extractelement <4 x half> %vec, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(snan inf norm sub zero) half @ret_only_qnan__extractelement_unknown(<4 x half> %vec, i32 %idx) {
+; CHECK-LABEL: define nofpclass(snan inf zero sub norm) half @ret_only_qnan__extractelement_unknown(
+; CHECK-SAME: <4 x half> [[VEC:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: [[EXT:%.*]] = extractelement <4 x half> [[VEC]], i32 [[IDX]]
+; CHECK-NEXT: ret half [[EXT]]
+;
+ %ext = extractelement <4 x half> %vec, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(qnan inf norm sub zero) half @ret_only_snan__extractelement_unknown(<4 x half> %vec, i32 %idx) {
+; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) half @ret_only_snan__extractelement_unknown(
+; CHECK-SAME: <4 x half> [[VEC:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: [[EXT:%.*]] = extractelement <4 x half> [[VEC]], i32 [[IDX]]
+; CHECK-NEXT: ret half [[EXT]]
+;
+ %ext = extractelement <4 x half> %vec, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(nan inf norm sub nzero) half @ret_only_pzero__extractelement_unknown(<4 x half> %vec, i32 %idx) {
+; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) half @ret_only_pzero__extractelement_unknown(
+; CHECK-SAME: <4 x half> [[VEC:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: ret half 0xH0000
+;
+ %ext = extractelement <4 x half> %vec, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(nan inf norm sub pzero) half @ret_only_nzero__extractelement_unknown(<4 x half> %vec, i32 %idx) {
+; CHECK-LABEL: define nofpclass(nan inf pzero sub norm) half @ret_only_nzero__extractelement_unknown(
+; CHECK-SAME: <4 x half> [[VEC:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: ret half 0xH8000
+;
+ %ext = extractelement <4 x half> %vec, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(nan inf norm sub) half @ret_only_zero__extractelement_unknown(<4 x half> %vec, i32 %idx) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) half @ret_only_zero__extractelement_unknown(
+; CHECK-SAME: <4 x half> [[VEC:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: [[EXT:%.*]] = extractelement <4 x half> [[VEC]], i32 [[IDX]]
+; CHECK-NEXT: ret half [[EXT]]
+;
+ %ext = extractelement <4 x half> %vec, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(nan pinf norm sub zero) half @ret_only_ninf__extractelement_unknown(<4 x half> %vec, i32 %idx) {
+; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) half @ret_only_ninf__extractelement_unknown(
+; CHECK-SAME: <4 x half> [[VEC:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: ret half 0xHFC00
+;
+ %ext = extractelement <4 x half> %vec, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(nan ninf norm sub zero) half @ret_only_pinf__extractelement_unknown(<4 x half> %vec, i32 %idx) {
+; CHECK-LABEL: define nofpclass(nan ninf zero sub norm) half @ret_only_pinf__extractelement_unknown(
+; CHECK-SAME: <4 x half> [[VEC:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: ret half 0xH7C00
+;
+ %ext = extractelement <4 x half> %vec, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(nan) half @ret_no_nan__extractelement_select_unknown_or_nan(i1 %cond, <4 x half> %unknown, i32 %idx) {
+; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan__extractelement_select_unknown_or_nan(
+; CHECK-SAME: i1 [[COND:%.*]], <4 x half> [[UNKNOWN:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: [[NAN:%.*]] = call <4 x half> @returns_nan()
+; CHECK-NEXT: [[EXT:%.*]] = extractelement <4 x half> [[UNKNOWN]], i32 [[IDX]]
+; CHECK-NEXT: ret half [[EXT]]
+;
+ %nan = call <4 x half> @returns_nan()
+ %select = select i1 %cond, <4 x half> %nan, <4 x half> %unknown
+ %ext = extractelement <4 x half> %select, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(nan) half @ret_no_nan__extractelement_vselect_unknown_or_nan(<4 x i1> %cond, <4 x half> %unknown, i32 %idx) {
+; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan__extractelement_vselect_unknown_or_nan(
+; CHECK-SAME: <4 x i1> [[COND:%.*]], <4 x half> [[UNKNOWN:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: [[NAN:%.*]] = call <4 x half> @returns_nan()
+; CHECK-NEXT: [[EXT:%.*]] = extractelement <4 x half> [[UNKNOWN]], i32 [[IDX]]
+; CHECK-NEXT: ret half [[EXT]]
+;
+ %nan = call <4 x half> @returns_nan()
+ %select = select <4 x i1> %cond, <4 x half> %nan, <4 x half> %unknown
+ %ext = extractelement <4 x half> %select, i32 %idx
+ ret half %ext
+}
+
+define nofpclass(inf) half @ret_no_nan__extractelement_vselect_unknown_or_inf(<4 x i1> %cond, <4 x half> %unknown, i32 %idx) {
+; CHECK-LABEL: define nofpclass(inf) half @ret_no_nan__extractelement_vselect_unknown_or_inf(
+; CHECK-SAME: <4 x i1> [[COND:%.*]], <4 x half> [[UNKNOWN:%.*]], i32 [[IDX:%.*]]) {
+; CHECK-NEXT: [[INF:%.*]] = call <4 x half> @returns_inf()
+; CHECK-NEXT: [[EXT:%.*]] = extractelement <4 x half> [[UNKNOWN]], i32 [[IDX]]
+; CHECK-NEXT: ret half [[EXT]]
+;
+ %inf = call <4 x half> @returns_inf()
+ %select = select <4 x i1> %cond, <4 x half> %unknown, <4 x half> %inf
+ %ext = extractelement <4 x half> %select, i32 %idx
+ ret half %ext
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/174081
More information about the llvm-commits
mailing list