[llvm] 96df108 - InstCombine: Handle extractelement in SimplifyDemandedFPClass (#174081)

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 31 06:51:48 PST 2025


Author: Matt Arsenault
Date: 2025-12-31T15:51:44+01:00
New Revision: 96df108ea18a4a97e741924c1ee441f1a1ae9dc9

URL: https://github.com/llvm/llvm-project/commit/96df108ea18a4a97e741924c1ee441f1a1ae9dc9
DIFF: https://github.com/llvm/llvm-project/commit/96df108ea18a4a97e741924c1ee441f1a1ae9dc9.diff

LOG: InstCombine: Handle extractelement in SimplifyDemandedFPClass (#174081)

A lot of boilerplate changes are necessary to do proper elementwise
tracking like SimplifyDemandedBits

Added: 
    llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-extractelement.ll

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 104ec5a9651af..07fad1f542e84 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2287,6 +2287,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
+}


        


More information about the llvm-commits mailing list