[llvm] [PatternMatch] Add m_SpecificType(Type*) matcher (PR #208427)

Benjamin Jurk via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 10 01:12:55 PDT 2026


https://github.com/bnjmnjrk updated https://github.com/llvm/llvm-project/pull/208427

>From a128e6bcffbc4d51df94f275ccf278a490ef4256 Mon Sep 17 00:00:00 2001
From: Benjamin Jurk <beni.jurk.20 at gmail.com>
Date: Thu, 9 Jul 2026 13:10:39 +0200
Subject: [PATCH 1/2] [PatternMatch] Add m_SpecificType(Type*) matcher

---
 llvm/include/llvm/IR/PatternMatch.h           | 25 +++++
 .../InstCombine/InstCombineCasts.cpp          | 95 +++++++++----------
 llvm/unittests/IR/PatternMatch.cpp            | 23 +++++
 3 files changed, 95 insertions(+), 48 deletions(-)

diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 0fb3fa83004df..98bfe26a614a4 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -824,6 +824,31 @@ inline cstfp_pred_ty<is_non_zero_not_denormal_fp> m_NonZeroNotDenormalFP() {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+template <typename Pattern> struct SpecificType_match {
+  Type *RefTy;
+  Pattern P;
+
+  SpecificType_match(Type *RefTy, const Pattern &P) : RefTy(RefTy), P(P) {}
+
+  template <typename ITy> bool match(ITy *V) const {
+    return V->getType() == RefTy && P.match(V);
+  }
+};
+
+// Explicit deduction guide.
+template <typename Pattern>
+SpecificType_match(const Type *, const Pattern &)
+    -> SpecificType_match<Pattern>;
+
+/// Match a value of a specific type.
+template <typename Pattern>
+inline auto m_SpecificType(Type *RefTy, const Pattern &P) {
+  return SpecificType_match<Pattern>(RefTy, P);
+}
+inline auto m_SpecificType(Type *RefTy) {
+  return m_SpecificType(RefTy, m_Value());
+}
+
 /// Match a value, capturing it if we match.
 inline match_bind<Value> m_Value(Value *&V) { return V; }
 inline match_bind<const Value> m_Value(const Value *&V) { return V; }
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index f630d1efbd7e7..074474306e714 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -478,8 +478,8 @@ bool TypeEvaluationHelper::canAlwaysEvaluateInType(Value *V, Type *Ty) {
     return match(V, m_ImmConstant());
 
   Value *X;
-  if ((match(V, m_ZExtOrSExt(m_Value(X))) || match(V, m_Trunc(m_Value(X)))) &&
-      X->getType() == Ty)
+  if (match(V, m_ZExtOrSExt(m_Value(X, m_SpecificType(Ty)))) ||
+      match(V, m_Trunc(m_Value(X, m_SpecificType(Ty)))))
     return true;
 
   return false;
@@ -947,12 +947,12 @@ Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) {
       return BinaryOperator::Create(BinOp->getOpcode(), TruncX, NarrowC);
     }
     Value *X;
-    if (match(BinOp0, m_ZExtOrSExt(m_Value(X))) && X->getType() == DestTy) {
+    if (match(BinOp0, m_ZExtOrSExt(m_Value(X, m_SpecificType(DestTy))))) {
       // trunc (binop (ext X), Y) --> binop X, (trunc Y)
       Value *NarrowOp1 = Builder.CreateTrunc(BinOp1, DestTy);
       return BinaryOperator::Create(BinOp->getOpcode(), X, NarrowOp1);
     }
-    if (match(BinOp1, m_ZExtOrSExt(m_Value(X))) && X->getType() == DestTy) {
+    if (match(BinOp1, m_ZExtOrSExt(m_Value(X, m_SpecificType(DestTy))))) {
       // trunc (binop Y, (ext X)) --> binop (trunc Y), X
       Value *NarrowOp0 = Builder.CreateTrunc(BinOp0, DestTy);
       return BinaryOperator::Create(BinOp->getOpcode(), NarrowOp0, X);
@@ -1157,20 +1157,21 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
   // trunc(u/smin(zext(a) + zext(b), MAX)) --> uadd.sat(a, b)
   if (match(Src,
             m_OneUse(m_CombineOr(
-                m_UMin(m_OneUse(m_Add(m_ZExt(m_Value(A)), m_ZExt(m_Value(B)))),
+                m_UMin(m_OneUse(m_Add(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
+                                      m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
                        m_SpecificInt(APInt::getMaxValue(DestWidth))),
-                m_SMin(m_OneUse(m_Add(m_ZExt(m_Value(A)), m_ZExt(m_Value(B)))),
-                       m_SpecificInt(APInt::getMaxValue(DestWidth)))))) &&
-      A->getType() == DestTy && B->getType() == DestTy) {
+                m_SMin(m_OneUse(m_Add(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
+                                      m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
+                       m_SpecificInt(APInt::getMaxValue(DestWidth))))))) {
     return replaceInstUsesWith(
         Trunc, Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, A, B));
   }
 
   // trunc(smax(zext(a) - zext(b), 0)) --> usub.sat(a, b)
   if (match(Src, m_OneUse(m_SMax(
-                     m_OneUse(m_Sub(m_ZExt(m_Value(A)), m_ZExt(m_Value(B)))),
-                     m_Zero()))) &&
-      A->getType() == DestTy && B->getType() == DestTy) {
+                     m_OneUse(m_Sub(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
+                                    m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
+                     m_Zero())))) {
     return replaceInstUsesWith(
         Trunc, Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A, B));
   }
@@ -1680,15 +1681,14 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &Zext) {
   // zext((trunc(X) & C) ^ C) -> ((X & zext(C)) ^ zext(C)).
   Value *And;
   if (match(Src, m_OneUse(m_Xor(m_Value(And), m_Constant(C)))) &&
-      match(And, m_OneUse(m_And(m_Trunc(m_Value(X)), m_Specific(C)))) &&
-      X->getType() == DestTy) {
+      match(And, m_OneUse(m_And(m_Trunc(m_Value(X, m_SpecificType(DestTy))),
+                                m_Specific(C))))) {
     Value *ZC = Builder.CreateZExt(C, DestTy);
     return BinaryOperator::CreateXor(Builder.CreateAnd(X, ZC), ZC);
   }
 
   // zext(sub(0, trunc(X))) -> and(sub(0, X), mask)
-  if (match(Src, m_Sub(m_Zero(), m_Trunc(m_Value(X)))) &&
-      X->getType() == DestTy) {
+  if (match(Src, m_Sub(m_Zero(), m_Trunc(m_Value(X, m_SpecificType(DestTy)))))) {
     APInt Mask = APInt::getLowBitsSet(DestTy->getScalarSizeInBits(),
                                       SrcTy->getScalarSizeInBits());
     Value *Neg = Builder.CreateSub(ConstantInt::get(DestTy, 0), X);
@@ -1700,16 +1700,15 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &Zext) {
   // intermediate values have extra uses. This could be generalized further for
   // a non-constant mask operand.
   // zext (and (trunc X), C) --> and X, (zext C)
-  if (match(Src, m_And(m_Trunc(m_Value(X)), m_Constant(C))) &&
-      X->getType() == DestTy) {
+  if (match(Src, m_And(m_Trunc(m_Value(X, m_SpecificType(DestTy))),
+                       m_Constant(C)))) {
     Value *ZextC = Builder.CreateZExt(C, DestTy);
     return BinaryOperator::CreateAnd(X, ZextC);
   }
 
   Value *Y;
-  if (match(Src,
-            m_OneUse(m_c_BitwiseLogic(m_NUWTrunc(m_Value(X)), m_Value(Y)))) &&
-      X->getType() == DestTy) {
+  if (match(Src, m_OneUse(m_c_BitwiseLogic(
+                     m_NUWTrunc(m_Value(X, m_SpecificType(DestTy))), m_Value(Y))))) {
     Value *ZextY = Builder.CreateZExt(Y, DestTy);
     return BinaryOperator::Create(cast<BinaryOperator>(Src)->getOpcode(), X,
                                   ZextY);
@@ -1991,9 +1990,10 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
   Value *A = nullptr;
   // TODO: Eventually this could be subsumed by EvaluateInDifferentType.
   Constant *BA = nullptr, *CA = nullptr;
-  if (match(Src, m_AShr(m_Shl(m_Trunc(m_Value(A)), m_Constant(BA)),
+  if (match(Src, m_AShr(m_Shl(m_Trunc(m_Value(A, m_SpecificType(DestTy))),
+                               m_Constant(BA)),
                         m_ImmConstant(CA))) &&
-      BA->isElementWiseEqual(CA) && A->getType() == DestTy) {
+      BA->isElementWiseEqual(CA)) {
     Constant *WideCurrShAmt =
         ConstantFoldCastOperand(Instruction::SExt, CA, DestTy, DL);
     assert(WideCurrShAmt && "Constant folding of ImmConstant cannot fail");
@@ -2047,9 +2047,8 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
                                       {CI->getLHS(), CI->getRHS()}));
 
   Value *Y;
-  if (match(Src,
-            m_OneUse(m_c_BitwiseLogic(m_NSWTrunc(m_Value(X)), m_Value(Y)))) &&
-      X->getType() == DestTy) {
+  if (match(Src, m_OneUse(m_c_BitwiseLogic(
+                     m_NSWTrunc(m_Value(X, m_SpecificType(DestTy))), m_Value(Y))))) {
     Value *SextY = Builder.CreateSExt(Y, DestTy);
     return BinaryOperator::Create(cast<BinaryOperator>(Src)->getOpcode(), X,
                                   SextY);
@@ -2352,16 +2351,16 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
     // If we are truncating a select that has an extended operand, we can
     // narrow the other operand and do the select as a narrow op.
     Value *Cond, *X, *Y;
-    if (match(Op, m_Select(m_Value(Cond), m_FPExt(m_Value(X)), m_Value(Y))) &&
-        X->getType() == Ty) {
+    if (match(Op, m_Select(m_Value(Cond), m_FPExt(m_Value(X, m_SpecificType(Ty))),
+                           m_Value(Y)))) {
       // fptrunc (select Cond, (fpext X), Y --> select Cond, X, (fptrunc Y)
       Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
       Value *Sel =
           Builder.CreateSelectFMF(Cond, X, NarrowY, FMF, "narrow.sel", Op);
       return replaceInstUsesWith(FPT, Sel);
     }
-    if (match(Op, m_Select(m_Value(Cond), m_Value(Y), m_FPExt(m_Value(X)))) &&
-        X->getType() == Ty) {
+    if (match(Op, m_Select(m_Value(Cond), m_Value(Y),
+                           m_FPExt(m_Value(X, m_SpecificType(Ty)))))) {
       // fptrunc (select Cond, Y, (fpext X) --> select Cond, (fptrunc Y), X
       Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
       Value *Sel =
@@ -2719,18 +2718,16 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
   //    -> (and (ptrtoint P), M)
   // This is generally beneficial as `and` is better supported than `ptrmask`.
   Value *Ptr, *Mask;
-  if (match(SrcOp, m_OneUse(m_Intrinsic<Intrinsic::ptrmask>(m_Value(Ptr),
-                                                            m_Value(Mask)))) &&
-      Mask->getType() == Ty)
+  if (match(SrcOp, m_OneUse(m_Intrinsic<Intrinsic::ptrmask>(
+                       m_Value(Ptr), m_Value(Mask, m_SpecificType(Ty))))))
     return BinaryOperator::CreateAnd(Builder.CreatePtrToInt(Ptr, Ty), Mask);
 
   if (Value *V = foldPtrToIntOrAddrOfGEP(Ty, SrcOp))
     return replaceInstUsesWith(CI, V);
 
   Value *Vec, *Scalar, *Index;
-  if (match(SrcOp, m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec)),
-                                        m_Value(Scalar), m_Value(Index)))) &&
-      Vec->getType() == Ty) {
+  if (match(SrcOp, m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec, m_SpecificType(Ty))),
+                                        m_Value(Scalar), m_Value(Index))))) {
     assert(Vec->getType()->getScalarSizeInBits() == PtrSize && "Wrong type");
     // Convert the scalar to int followed by insert to eliminate one cast:
     // p2i (ins (i2p Vec), Scalar, Index --> ins Vec, (p2i Scalar), Index
@@ -2749,9 +2746,8 @@ Instruction *InstCombinerImpl::visitPtrToAddr(PtrToAddrInst &CI) {
   //    -> (and (ptrtoaddr P), M)
   // This is generally beneficial as `and` is better supported than `ptrmask`.
   Value *Ptr, *Mask;
-  if (match(SrcOp, m_OneUse(m_Intrinsic<Intrinsic::ptrmask>(m_Value(Ptr),
-                                                            m_Value(Mask)))) &&
-      Mask->getType() == Ty)
+  if (match(SrcOp, m_OneUse(m_Intrinsic<Intrinsic::ptrmask>(
+                       m_Value(Ptr), m_Value(Mask, m_SpecificType(Ty))))))
     return BinaryOperator::CreateAnd(Builder.CreatePtrToAddr(Ptr), Mask);
 
   if (Value *V = foldPtrToIntOrAddrOfGEP(Ty, SrcOp))
@@ -3084,15 +3080,17 @@ static Instruction *foldBitCastBitwiseLogic(BitCastInst &BitCast,
     return nullptr;
 
   Value *X;
-  if (match(BO->getOperand(0), m_OneUse(m_BitCast(m_Value(X)))) &&
-      X->getType() == DestTy && !isa<Constant>(X)) {
+  if (match(BO->getOperand(0),
+            m_OneUse(m_BitCast(m_Value(X, m_SpecificType(DestTy))))) &&
+      !isa<Constant>(X)) {
     // bitcast(logic(bitcast(X), Y)) --> logic'(X, bitcast(Y))
     Value *CastedOp1 = Builder.CreateBitCast(BO->getOperand(1), DestTy);
     return BinaryOperator::Create(BO->getOpcode(), X, CastedOp1);
   }
 
-  if (match(BO->getOperand(1), m_OneUse(m_BitCast(m_Value(X)))) &&
-      X->getType() == DestTy && !isa<Constant>(X)) {
+  if (match(BO->getOperand(1),
+            m_OneUse(m_BitCast(m_Value(X, m_SpecificType(DestTy))))) &&
+      !isa<Constant>(X)) {
     // bitcast(logic(Y, bitcast(X))) --> logic'(bitcast(Y), X)
     Value *CastedOp0 = Builder.CreateBitCast(BO->getOperand(0), DestTy);
     return BinaryOperator::Create(BO->getOpcode(), CastedOp0, X);
@@ -3154,14 +3152,14 @@ static Instruction *foldBitCastSelect(BitCastInst &BitCast,
     return nullptr;
 
   Value *X;
-  if (match(TVal, m_OneUse(m_BitCast(m_Value(X)))) && X->getType() == DestTy &&
+  if (match(TVal, m_OneUse(m_BitCast(m_Value(X, m_SpecificType(DestTy))))) &&
       !isa<Constant>(X)) {
     // bitcast(select(Cond, bitcast(X), Y)) --> select'(Cond, X, bitcast(Y))
     Value *CastedVal = Builder.CreateBitCast(FVal, DestTy);
     return SelectInst::Create(Cond, X, CastedVal, "", nullptr, Sel);
   }
 
-  if (match(FVal, m_OneUse(m_BitCast(m_Value(X)))) && X->getType() == DestTy &&
+  if (match(FVal, m_OneUse(m_BitCast(m_Value(X, m_SpecificType(DestTy))))) &&
       !isa<Constant>(X)) {
     // bitcast(select(Cond, Y, bitcast(X))) --> select'(Cond, bitcast(Y), X)
     Value *CastedVal = Builder.CreateBitCast(TVal, DestTy);
@@ -3433,10 +3431,11 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) {
     unsigned BitWidth = DestTy->getScalarSizeInBits();
     Value *X, *Y;
     uint64_t IndexC;
-    if (match(Src, m_OneUse(m_InsertElt(m_OneUse(m_BitCast(m_Value(X))),
-                                        m_Value(Y), m_ConstantInt(IndexC)))) &&
-        DestTy->isIntegerTy() && X->getType() == DestTy &&
-        Y->getType()->isIntegerTy() && isDesirableIntType(BitWidth)) {
+    if (match(Src, m_OneUse(m_InsertElt(
+                       m_OneUse(m_BitCast(m_Value(X, m_SpecificType(DestTy)))),
+                       m_Value(Y), m_ConstantInt(IndexC)))) &&
+        DestTy->isIntegerTy() && Y->getType()->isIntegerTy() &&
+        isDesirableIntType(BitWidth)) {
       // Adjust for big endian - the LSBs are at the high index.
       if (DL.isBigEndian())
         IndexC = SrcVTy->getNumElements() - 1 - IndexC;
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 3f81739ef3c7b..e126aa8c7d9b9 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -2758,6 +2758,29 @@ TEST_F(PatternMatchTest, ShiftOrSelf) {
   EXPECT_EQ(ShAmtC, 0U);
 }
 
+TEST_F(PatternMatchTest, SpecificType) {
+  Type *I32 = IRB.getInt32Ty();
+  Type *I64 = IRB.getInt64Ty();
+  Value *X = IRB.CreateAdd(IRB.getInt32(1), IRB.getInt32(2));
+  Value *Y = IRB.CreateZExt(X, I64);
+
+  EXPECT_TRUE(match(X, m_SpecificType(I32)));
+  EXPECT_FALSE(match(X, m_SpecificType(I64)));
+
+  Value *Bound = nullptr;
+  EXPECT_TRUE(match(X, m_Value(Bound, m_SpecificType(I32))));
+  EXPECT_EQ(X, Bound);
+  Bound = nullptr;
+  EXPECT_FALSE(match(X, m_Value(Bound, m_SpecificType(I64))));
+
+  Bound = nullptr;
+  EXPECT_TRUE(match(Y, m_ZExt(m_Value(Bound, m_SpecificType(I32)))));
+  EXPECT_EQ(X, Bound);
+
+  EXPECT_TRUE(match(X, m_SpecificType(I32, m_Add(m_Value(), m_Value()))));
+  EXPECT_FALSE(match(X, m_SpecificType(I64, m_Add(m_Value(), m_Value()))));
+}
+
 TEST_F(PatternMatchTest, CommutativeDeferredIntrinsicMatch) {
   Value *X = ConstantFP::get(IRB.getDoubleTy(), 1.0);
   Value *Y = ConstantFP::get(IRB.getDoubleTy(), 2.0);

>From 0c89268d6715aa59b096fd8a12b44bfcca801e91 Mon Sep 17 00:00:00 2001
From: Benjamin Jurk <beni.jurk.20 at gmail.com>
Date: Fri, 10 Jul 2026 10:12:56 +0200
Subject: [PATCH 2/2] revision 1

---
 llvm/include/llvm/IR/PatternMatch.h           | 50 +++++++++----------
 .../InstCombine/InstCombineCasts.cpp          | 48 ++++++++++--------
 2 files changed, 53 insertions(+), 45 deletions(-)

diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 98bfe26a614a4..6b820bcba6097 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -824,31 +824,6 @@ inline cstfp_pred_ty<is_non_zero_not_denormal_fp> m_NonZeroNotDenormalFP() {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-template <typename Pattern> struct SpecificType_match {
-  Type *RefTy;
-  Pattern P;
-
-  SpecificType_match(Type *RefTy, const Pattern &P) : RefTy(RefTy), P(P) {}
-
-  template <typename ITy> bool match(ITy *V) const {
-    return V->getType() == RefTy && P.match(V);
-  }
-};
-
-// Explicit deduction guide.
-template <typename Pattern>
-SpecificType_match(const Type *, const Pattern &)
-    -> SpecificType_match<Pattern>;
-
-/// Match a value of a specific type.
-template <typename Pattern>
-inline auto m_SpecificType(Type *RefTy, const Pattern &P) {
-  return SpecificType_match<Pattern>(RefTy, P);
-}
-inline auto m_SpecificType(Type *RefTy) {
-  return m_SpecificType(RefTy, m_Value());
-}
-
 /// Match a value, capturing it if we match.
 inline match_bind<Value> m_Value(Value *&V) { return V; }
 inline match_bind<const Value> m_Value(const Value *&V) { return V; }
@@ -1107,6 +1082,31 @@ inline specific_bbval m_SpecificBB(BasicBlock *BB) {
   return specific_bbval(BB);
 }
 
+template <typename Pattern> struct SpecificType_match {
+  Type *RefTy;
+  Pattern P;
+
+  SpecificType_match(Type *RefTy, const Pattern &P) : RefTy(RefTy), P(P) {}
+
+  template <typename ITy> bool match(ITy *V) const {
+    return V->getType() == RefTy && P.match(V);
+  }
+};
+
+// Explicit deduction guide.
+template <typename Pattern>
+SpecificType_match(const Type *, const Pattern &)
+    -> SpecificType_match<Pattern>;
+
+/// Match a value of a specific type.
+template <typename Pattern>
+inline auto m_SpecificType(Type *RefTy, const Pattern &P) {
+  return SpecificType_match<Pattern>(RefTy, P);
+}
+inline auto m_SpecificType(Type *RefTy) {
+  return m_SpecificType(RefTy, m_Value());
+}
+
 /// A commutative-friendly version of m_Specific().
 inline match_deferred<BasicBlock> m_Deferred(BasicBlock *const &BB) {
   return BB;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 074474306e714..0ab3618e654e4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1157,21 +1157,24 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
   // trunc(u/smin(zext(a) + zext(b), MAX)) --> uadd.sat(a, b)
   if (match(Src,
             m_OneUse(m_CombineOr(
-                m_UMin(m_OneUse(m_Add(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
-                                      m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
-                       m_SpecificInt(APInt::getMaxValue(DestWidth))),
-                m_SMin(m_OneUse(m_Add(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
-                                      m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
-                       m_SpecificInt(APInt::getMaxValue(DestWidth))))))) {
+                m_UMin(
+                    m_OneUse(m_Add(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
+                                   m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
+                    m_SpecificInt(APInt::getMaxValue(DestWidth))),
+                m_SMin(
+                    m_OneUse(m_Add(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
+                                   m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
+                    m_SpecificInt(APInt::getMaxValue(DestWidth))))))) {
     return replaceInstUsesWith(
         Trunc, Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, A, B));
   }
 
   // trunc(smax(zext(a) - zext(b), 0)) --> usub.sat(a, b)
-  if (match(Src, m_OneUse(m_SMax(
-                     m_OneUse(m_Sub(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
-                                    m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
-                     m_Zero())))) {
+  if (match(Src,
+            m_OneUse(m_SMax(
+                m_OneUse(m_Sub(m_ZExt(m_Value(A, m_SpecificType(DestTy))),
+                               m_ZExt(m_Value(B, m_SpecificType(DestTy))))),
+                m_Zero())))) {
     return replaceInstUsesWith(
         Trunc, Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A, B));
   }
@@ -1688,7 +1691,8 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &Zext) {
   }
 
   // zext(sub(0, trunc(X))) -> and(sub(0, X), mask)
-  if (match(Src, m_Sub(m_Zero(), m_Trunc(m_Value(X, m_SpecificType(DestTy)))))) {
+  if (match(Src,
+            m_Sub(m_Zero(), m_Trunc(m_Value(X, m_SpecificType(DestTy)))))) {
     APInt Mask = APInt::getLowBitsSet(DestTy->getScalarSizeInBits(),
                                       SrcTy->getScalarSizeInBits());
     Value *Neg = Builder.CreateSub(ConstantInt::get(DestTy, 0), X);
@@ -1707,8 +1711,9 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &Zext) {
   }
 
   Value *Y;
-  if (match(Src, m_OneUse(m_c_BitwiseLogic(
-                     m_NUWTrunc(m_Value(X, m_SpecificType(DestTy))), m_Value(Y))))) {
+  if (match(Src,
+            m_OneUse(m_c_BitwiseLogic(
+                m_NUWTrunc(m_Value(X, m_SpecificType(DestTy))), m_Value(Y))))) {
     Value *ZextY = Builder.CreateZExt(Y, DestTy);
     return BinaryOperator::Create(cast<BinaryOperator>(Src)->getOpcode(), X,
                                   ZextY);
@@ -1991,7 +1996,7 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
   // TODO: Eventually this could be subsumed by EvaluateInDifferentType.
   Constant *BA = nullptr, *CA = nullptr;
   if (match(Src, m_AShr(m_Shl(m_Trunc(m_Value(A, m_SpecificType(DestTy))),
-                               m_Constant(BA)),
+                              m_Constant(BA)),
                         m_ImmConstant(CA))) &&
       BA->isElementWiseEqual(CA)) {
     Constant *WideCurrShAmt =
@@ -2047,8 +2052,9 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
                                       {CI->getLHS(), CI->getRHS()}));
 
   Value *Y;
-  if (match(Src, m_OneUse(m_c_BitwiseLogic(
-                     m_NSWTrunc(m_Value(X, m_SpecificType(DestTy))), m_Value(Y))))) {
+  if (match(Src,
+            m_OneUse(m_c_BitwiseLogic(
+                m_NSWTrunc(m_Value(X, m_SpecificType(DestTy))), m_Value(Y))))) {
     Value *SextY = Builder.CreateSExt(Y, DestTy);
     return BinaryOperator::Create(cast<BinaryOperator>(Src)->getOpcode(), X,
                                   SextY);
@@ -2351,8 +2357,9 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
     // If we are truncating a select that has an extended operand, we can
     // narrow the other operand and do the select as a narrow op.
     Value *Cond, *X, *Y;
-    if (match(Op, m_Select(m_Value(Cond), m_FPExt(m_Value(X, m_SpecificType(Ty))),
-                           m_Value(Y)))) {
+    if (match(Op,
+              m_Select(m_Value(Cond), m_FPExt(m_Value(X, m_SpecificType(Ty))),
+                       m_Value(Y)))) {
       // fptrunc (select Cond, (fpext X), Y --> select Cond, X, (fptrunc Y)
       Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
       Value *Sel =
@@ -2726,8 +2733,9 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
     return replaceInstUsesWith(CI, V);
 
   Value *Vec, *Scalar, *Index;
-  if (match(SrcOp, m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec, m_SpecificType(Ty))),
-                                        m_Value(Scalar), m_Value(Index))))) {
+  if (match(SrcOp,
+            m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec, m_SpecificType(Ty))),
+                                 m_Value(Scalar), m_Value(Index))))) {
     assert(Vec->getType()->getScalarSizeInBits() == PtrSize && "Wrong type");
     // Convert the scalar to int followed by insert to eliminate one cast:
     // p2i (ins (i2p Vec), Scalar, Index --> ins Vec, (p2i Scalar), Index



More information about the llvm-commits mailing list