[llvm] [InstCombine] Add demanded-bits pext handling (PR #205092)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 16 04:27:37 PDT 2026


https://github.com/mygitljf updated https://github.com/llvm/llvm-project/pull/205092

>From 62933db2657cbd831821897fc21479b6b16d1e16 Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Mon, 22 Jun 2026 18:01:53 +0000
Subject: [PATCH 1/7] [InstCombine] Add demanded-bits pext handling

---
 .../InstCombine/InstCombineCalls.cpp          |  3 +
 .../InstCombineSimplifyDemanded.cpp           | 29 +++++++
 llvm/test/Transforms/InstCombine/pext.ll      | 79 +++++++++++++++++++
 3 files changed, 111 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 6992602f54fe9..29618d53fdb75 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2678,6 +2678,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     break;
   }
   case Intrinsic::pext: {
+    if (SimplifyDemandedInstructionBits(*II))
+      return II;
+
     const APInt *MaskC;
     if (match(II->getArgOperand(1), m_APInt(MaskC))) {
       unsigned MaskIdx, MaskLen;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index cca297a5b8dc2..ed0a2836447f6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1104,6 +1104,35 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
         break;
       }
 
+      case Intrinsic::pext: {
+        APInt DemandedMaskRHS(APInt::getAllOnes(BitWidth));
+        if (SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Q, Depth + 1))
+          return I;
+
+        APInt DemandedMaskLHS(BitWidth, 0);
+        unsigned M0 = 0, M1 = 0;
+        for (unsigned I = 0; I != BitWidth; ++I) {
+          if (!RHSKnown.Zero[I]) {
+            APInt Range = APInt::getBitsSet(BitWidth, M0, M1 + 1);
+            if (DemandedMask.intersects(Range))
+              DemandedMaskLHS.setBit(I);
+          }
+
+          if (RHSKnown.One[I])
+            ++M0, ++M1;
+          else if (!RHSKnown.Zero[I])
+            ++M1;
+        }
+
+        if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Q, Depth + 1))
+          return I;
+
+        Known = KnownBits::pext(LHSKnown, RHSKnown);
+        KnownBitsComputed = true;
+
+        break;
+      }
+
       case Intrinsic::fshr:
       case Intrinsic::fshl: {
         const APInt *SA;
diff --git a/llvm/test/Transforms/InstCombine/pext.ll b/llvm/test/Transforms/InstCombine/pext.ll
index 135d72ea5c223..6d2a5c4d0da25 100644
--- a/llvm/test/Transforms/InstCombine/pext.ll
+++ b/llvm/test/Transforms/InstCombine/pext.ll
@@ -102,3 +102,82 @@ define i64 @test_pext_64_constant_fold_2() nounwind readnone {
   ret i64 %1
 }
 
+define i32 @test_pext_and_constant_supermask_32(i32 %x) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_constant_supermask_32(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 42)
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %and = and i32 %x, 255
+  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 42)
+  ret i32 %1
+}
+
+define i64 @test_pext_and_constant_supermask_64(i64 %x) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_constant_supermask_64(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.pext.i64(i64 [[X:%.*]], i64 42)
+; CHECK-NEXT:    ret i64 [[TMP1]]
+;
+  %and = and i64 %x, 255
+  %1 = tail call i64 @llvm.pext.i64(i64 %and, i64 42)
+  ret i64 %1
+}
+
+define i32 @test_pext_and_known_zero_mask_32(i32 %x, i32 %y) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_known_zero_mask_32(
+; CHECK-NEXT:    [[M:%.*]] = and i32 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[M]])
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %m = and i32 %y, 42
+  %and = and i32 %x, 63
+  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
+  ret i32 %1
+}
+
+define i32 @test_pext_and_known_zero_mask_multi_use_32(i32 %x, i32 %y) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_known_zero_mask_multi_use_32(
+; CHECK-NEXT:    [[M:%.*]] = and i32 [[Y:%.*]], 42
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 63
+; CHECK-NEXT:    [[PEXT:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X]], i32 [[M]])
+; CHECK-NEXT:    [[USE:%.*]] = add nuw nsw i32 [[AND]], [[PEXT]]
+; CHECK-NEXT:    ret i32 [[USE]]
+;
+  %m = and i32 %y, 42
+  %and = and i32 %x, 63
+  %pext = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
+  %use = add i32 %and, %pext
+  ret i32 %use
+}
+
+define i32 @test_pext_and_constant_mask_32(i32 %x) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_constant_mask_32(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 42)
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %and = and i32 %x, 42
+  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 42)
+  ret i32 %1
+}
+
+define i32 @test_pext_and_unknown_mask_32(i32 %x, i32 %m) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_unknown_mask_32(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 63
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[AND]], i32 [[M:%.*]])
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %and = and i32 %x, 63
+  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
+  ret i32 %1
+}
+
+define i32 @test_pext_and_partial_demand_32(i32 %x) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_partial_demand_32(
+; CHECK-NEXT:    [[PEXT:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 42)
+; CHECK-NEXT:    [[USE:%.*]] = and i32 [[PEXT]], 1
+; CHECK-NEXT:    ret i32 [[USE]]
+;
+  %and = and i32 %x, 2
+  %pext = tail call i32 @llvm.pext.i32(i32 %and, i32 42)
+  %use = and i32 %pext, 1
+  ret i32 %use
+}

>From f4d248a6f714d0af634dc51bc9793f06f62edb4f Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Thu, 9 Jul 2026 21:15:55 +0000
Subject: [PATCH 2/7] Fold pext same mask

---
 .../InstCombine/InstCombineCalls.cpp          |  5 +++++
 llvm/test/Transforms/InstCombine/pext.ll      | 20 +++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 29618d53fdb75..bf350e3e26cab 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2681,6 +2681,11 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     if (SimplifyDemandedInstructionBits(*II))
       return II;
 
+    Value *X;
+    if (match(II->getArgOperand(0),
+              m_c_And(m_Value(X), m_Specific(II->getArgOperand(1)))))
+      return replaceOperand(*II, 0, X);
+
     const APInt *MaskC;
     if (match(II->getArgOperand(1), m_APInt(MaskC))) {
       unsigned MaskIdx, MaskLen;
diff --git a/llvm/test/Transforms/InstCombine/pext.ll b/llvm/test/Transforms/InstCombine/pext.ll
index 6d2a5c4d0da25..0281a7877e71a 100644
--- a/llvm/test/Transforms/InstCombine/pext.ll
+++ b/llvm/test/Transforms/InstCombine/pext.ll
@@ -159,6 +159,26 @@ define i32 @test_pext_and_constant_mask_32(i32 %x) nounwind readnone {
   ret i32 %1
 }
 
+define i32 @test_pext_and_same_variable_mask_32(i32 %x, i32 %m) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_same_variable_mask_32(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[M:%.*]])
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %and = and i32 %x, %m
+  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
+  ret i32 %1
+}
+
+define i32 @test_pext_and_same_variable_mask_commuted_32(i32 %x, i32 %m) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_same_variable_mask_commuted_32(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[M:%.*]])
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %and = and i32 %m, %x
+  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
+  ret i32 %1
+}
+
 define i32 @test_pext_and_unknown_mask_32(i32 %x, i32 %m) nounwind readnone {
 ; CHECK-LABEL: @test_pext_and_unknown_mask_32(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 63

>From e8393c3017fa5abcd6848fc56aff2311df672c55 Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Thu, 9 Jul 2026 21:30:34 +0000
Subject: [PATCH 3/7] Revert "Fold pext same mask"

This reverts commit f4d248a6f714d0af634dc51bc9793f06f62edb4f.
---
 .../InstCombine/InstCombineCalls.cpp          |  5 -----
 llvm/test/Transforms/InstCombine/pext.ll      | 20 -------------------
 2 files changed, 25 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index bf350e3e26cab..29618d53fdb75 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2681,11 +2681,6 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     if (SimplifyDemandedInstructionBits(*II))
       return II;
 
-    Value *X;
-    if (match(II->getArgOperand(0),
-              m_c_And(m_Value(X), m_Specific(II->getArgOperand(1)))))
-      return replaceOperand(*II, 0, X);
-
     const APInt *MaskC;
     if (match(II->getArgOperand(1), m_APInt(MaskC))) {
       unsigned MaskIdx, MaskLen;
diff --git a/llvm/test/Transforms/InstCombine/pext.ll b/llvm/test/Transforms/InstCombine/pext.ll
index 0281a7877e71a..6d2a5c4d0da25 100644
--- a/llvm/test/Transforms/InstCombine/pext.ll
+++ b/llvm/test/Transforms/InstCombine/pext.ll
@@ -159,26 +159,6 @@ define i32 @test_pext_and_constant_mask_32(i32 %x) nounwind readnone {
   ret i32 %1
 }
 
-define i32 @test_pext_and_same_variable_mask_32(i32 %x, i32 %m) nounwind readnone {
-; CHECK-LABEL: @test_pext_and_same_variable_mask_32(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[M:%.*]])
-; CHECK-NEXT:    ret i32 [[TMP1]]
-;
-  %and = and i32 %x, %m
-  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
-  ret i32 %1
-}
-
-define i32 @test_pext_and_same_variable_mask_commuted_32(i32 %x, i32 %m) nounwind readnone {
-; CHECK-LABEL: @test_pext_and_same_variable_mask_commuted_32(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[M:%.*]])
-; CHECK-NEXT:    ret i32 [[TMP1]]
-;
-  %and = and i32 %m, %x
-  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
-  ret i32 %1
-}
-
 define i32 @test_pext_and_unknown_mask_32(i32 %x, i32 %m) nounwind readnone {
 ; CHECK-LABEL: @test_pext_and_unknown_mask_32(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 63

>From c680ba44b6abc030514a20b7c2279bca3c588c10 Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Thu, 9 Jul 2026 22:12:48 +0000
Subject: [PATCH 4/7] Handle pext same mask

---
 .../InstCombineSimplifyDemanded.cpp           |  7 +++++++
 llvm/test/Transforms/InstCombine/pext.ll      | 20 +++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index ed0a2836447f6..46894546ef411 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1109,6 +1109,13 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
         if (SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Q, Depth + 1))
           return I;
 
+        Value *X;
+        if (match(I->getOperand(0),
+                  m_c_And(m_Value(X), m_Specific(I->getOperand(1))))) {
+          replaceOperand(*I, 0, X);
+          return I;
+        }
+
         APInt DemandedMaskLHS(BitWidth, 0);
         unsigned M0 = 0, M1 = 0;
         for (unsigned I = 0; I != BitWidth; ++I) {
diff --git a/llvm/test/Transforms/InstCombine/pext.ll b/llvm/test/Transforms/InstCombine/pext.ll
index 6d2a5c4d0da25..0281a7877e71a 100644
--- a/llvm/test/Transforms/InstCombine/pext.ll
+++ b/llvm/test/Transforms/InstCombine/pext.ll
@@ -159,6 +159,26 @@ define i32 @test_pext_and_constant_mask_32(i32 %x) nounwind readnone {
   ret i32 %1
 }
 
+define i32 @test_pext_and_same_variable_mask_32(i32 %x, i32 %m) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_same_variable_mask_32(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[M:%.*]])
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %and = and i32 %x, %m
+  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
+  ret i32 %1
+}
+
+define i32 @test_pext_and_same_variable_mask_commuted_32(i32 %x, i32 %m) nounwind readnone {
+; CHECK-LABEL: @test_pext_and_same_variable_mask_commuted_32(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[M:%.*]])
+; CHECK-NEXT:    ret i32 [[TMP1]]
+;
+  %and = and i32 %m, %x
+  %1 = tail call i32 @llvm.pext.i32(i32 %and, i32 %m)
+  ret i32 %1
+}
+
 define i32 @test_pext_and_unknown_mask_32(i32 %x, i32 %m) nounwind readnone {
 ; CHECK-LABEL: @test_pext_and_unknown_mask_32(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 63

>From 79418bd778e6f03fba1d1b9e384b3270a78ec500 Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Thu, 16 Jul 2026 17:23:30 +0800
Subject: [PATCH 5/7] [InstCombine] Propagate demanded bits to pext masks

---
 .../InstCombineSimplifyDemanded.cpp           | 14 +++-
 llvm/test/Transforms/InstCombine/pext.ll      | 77 ++++++++++++++++++-
 2 files changed, 87 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 46894546ef411..45aef18037d2d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1105,8 +1105,18 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
       }
 
       case Intrinsic::pext: {
-        APInt DemandedMaskRHS(APInt::getAllOnes(BitWidth));
-        if (SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Q, Depth + 1))
+        RHSKnown = computeKnownBits(I->getOperand(1), I, Depth + 1);
+        unsigned N = DemandedMask.getActiveBits();
+        APInt DemandedMaskRHS(BitWidth, 0);
+        // pext result bits depend on the mask prefix through their rank.
+        for (unsigned Bit = 0; Bit != BitWidth && N != 0; ++Bit) {
+          DemandedMaskRHS.setBit(Bit);
+          if (RHSKnown.One[Bit])
+            --N;
+        }
+        if (ShrinkDemandedConstant(I, 1, DemandedMaskRHS) ||
+            SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Q,
+                                 Depth + 1))
           return I;
 
         Value *X;
diff --git a/llvm/test/Transforms/InstCombine/pext.ll b/llvm/test/Transforms/InstCombine/pext.ll
index 0281a7877e71a..12b250fd1acba 100644
--- a/llvm/test/Transforms/InstCombine/pext.ll
+++ b/llvm/test/Transforms/InstCombine/pext.ll
@@ -192,8 +192,8 @@ define i32 @test_pext_and_unknown_mask_32(i32 %x, i32 %m) nounwind readnone {
 
 define i32 @test_pext_and_partial_demand_32(i32 %x) nounwind readnone {
 ; CHECK-LABEL: @test_pext_and_partial_demand_32(
-; CHECK-NEXT:    [[PEXT:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 42)
-; CHECK-NEXT:    [[USE:%.*]] = and i32 [[PEXT]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[USE:%.*]] = and i32 [[TMP1]], 1
 ; CHECK-NEXT:    ret i32 [[USE]]
 ;
   %and = and i32 %x, 2
@@ -201,3 +201,76 @@ define i32 @test_pext_and_partial_demand_32(i32 %x) nounwind readnone {
   %use = and i32 %pext, 1
   ret i32 %use
 }
+
+define i32 @test_pext_rhs_lowest_known_one_32(i32 %x, i32 %y) nounwind readnone {
+; CHECK-LABEL: @test_pext_rhs_lowest_known_one_32(
+; CHECK-NEXT:    [[USE:%.*]] = and i32 [[X:%.*]], 1
+; CHECK-NEXT:    ret i32 [[USE]]
+;
+  %mask = or i32 %y, 1
+  %pext = tail call i32 @llvm.pext.i32(i32 %x, i32 %mask)
+  %use = and i32 %pext, 1
+  ret i32 %use
+}
+
+define i32 @test_pext_rhs_sparse_demand_32(i32 %x, i32 %y) nounwind readnone {
+; CHECK-LABEL: @test_pext_rhs_sparse_demand_32(
+; CHECK-NEXT:    [[MASK:%.*]] = or i32 [[Y:%.*]], 170
+; CHECK-NEXT:    [[PEXT:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[MASK]])
+; CHECK-NEXT:    [[USE:%.*]] = and i32 [[PEXT]], 8
+; CHECK-NEXT:    ret i32 [[USE]]
+;
+  %masked = and i32 %y, 341
+  %mask = or i32 %masked, 170
+  %pext = tail call i32 @llvm.pext.i32(i32 %x, i32 %mask)
+  %use = and i32 %pext, 8
+  ret i32 %use
+}
+
+define i32 @test_pext_rhs_insufficient_known_ones_32(i32 %x, i32 %y) nounwind readnone {
+; CHECK-LABEL: @test_pext_rhs_insufficient_known_ones_32(
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[Y:%.*]], 21
+; CHECK-NEXT:    [[MASK:%.*]] = or disjoint i32 [[MASKED]], 2
+; CHECK-NEXT:    [[PEXT:%.*]] = tail call i32 @llvm.pext.i32(i32 [[X:%.*]], i32 [[MASK]])
+; CHECK-NEXT:    [[USE:%.*]] = and i32 [[PEXT]], 3
+; CHECK-NEXT:    ret i32 [[USE]]
+;
+  %masked = and i32 %y, 21
+  %mask = or i32 %masked, 2
+  %pext = tail call i32 @llvm.pext.i32(i32 %x, i32 %mask)
+  %use = and i32 %pext, 3
+  ret i32 %use
+}
+
+define i32 @test_pext_rhs_low_four_known_ones_32(i32 %x, i32 %y) nounwind readnone {
+; CHECK-LABEL: @test_pext_rhs_low_four_known_ones_32(
+; CHECK-NEXT:    [[USE:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    ret i32 [[USE]]
+;
+  %mask = or i32 %y, 15
+  %pext = tail call i32 @llvm.pext.i32(i32 %x, i32 %mask)
+  %use = and i32 %pext, 15
+  ret i32 %use
+}
+
+define i64 @test_pext_rhs_lowest_known_one_64(i64 %x, i64 %y) nounwind readnone {
+; CHECK-LABEL: @test_pext_rhs_lowest_known_one_64(
+; CHECK-NEXT:    [[USE:%.*]] = and i64 [[X:%.*]], 1
+; CHECK-NEXT:    ret i64 [[USE]]
+;
+  %mask = or i64 %y, 1
+  %pext = tail call i64 @llvm.pext.i64(i64 %x, i64 %mask)
+  %use = and i64 %pext, 1
+  ret i64 %use
+}
+
+define <2 x i32> @test_pext_rhs_lowest_known_one_v2i32(<2 x i32> %x, <2 x i32> %y) nounwind readnone {
+; CHECK-LABEL: @test_pext_rhs_lowest_known_one_v2i32(
+; CHECK-NEXT:    [[USE:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 1)
+; CHECK-NEXT:    ret <2 x i32> [[USE]]
+;
+  %mask = or <2 x i32> %y, <i32 1, i32 1>
+  %pext = tail call <2 x i32> @llvm.pext.v2i32(<2 x i32> %x, <2 x i32> %mask)
+  %use = and <2 x i32> %pext, <i32 1, i32 1>
+  ret <2 x i32> %use
+}

>From 20fd0a124927bb3ad1eccae866dbf32037f6affe Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Thu, 16 Jul 2026 17:32:35 +0800
Subject: [PATCH 6/7] [InstCombine] Format pext demanded-bits call (NFC)

---
 .../lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 45aef18037d2d..fc468345ca702 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1115,8 +1115,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
             --N;
         }
         if (ShrinkDemandedConstant(I, 1, DemandedMaskRHS) ||
-            SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Q,
-                                 Depth + 1))
+            SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Q, Depth + 1))
           return I;
 
         Value *X;

>From 031c7f967504a8fc811db6335b004b56f111c732 Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Thu, 16 Jul 2026 19:25:25 +0800
Subject: [PATCH 7/7] [ValueTracking] Update pext checks (NFC)

---
 llvm/test/Analysis/ValueTracking/knownbits-pext.ll | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/test/Analysis/ValueTracking/knownbits-pext.ll b/llvm/test/Analysis/ValueTracking/knownbits-pext.ll
index 8ad80199c18de..ef0f585b6d20e 100644
--- a/llvm/test/Analysis/ValueTracking/knownbits-pext.ll
+++ b/llvm/test/Analysis/ValueTracking/knownbits-pext.ll
@@ -66,8 +66,7 @@ define <2 x i1> @pext_zero_mask_known_zero_vector(<2 x i8> %x) nounwind {
 ; Negative: pext(x, 0b11001100) can have bits 0-3 set; can't prove bit 0 is zero.
 define i1 @pext_low_bits_not_known(i8 %x) nounwind {
 ; CHECK-LABEL: @pext_low_bits_not_known(
-; CHECK-NEXT:    [[PEXT:%.*]] = call i8 @llvm.pext.i8(i8 [[X:%.*]], i8 -52)
-; CHECK-NEXT:    [[AND:%.*]] = and i8 [[PEXT]], 1
+; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], 4
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
@@ -79,8 +78,7 @@ define i1 @pext_low_bits_not_known(i8 %x) nounwind {
 
 define <2 x i1> @pext_low_bits_not_known_vector(<2 x i8> %x) nounwind {
 ; CHECK-LABEL: @pext_low_bits_not_known_vector(
-; CHECK-NEXT:    [[PEXT:%.*]] = call <2 x i8> @llvm.pext.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 -52))
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[PEXT]], splat (i8 1)
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 4)
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;



More information about the llvm-commits mailing list