[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