https://github.com/AnushaK6 updated 
https://github.com/llvm/llvm-project/pull/166967

>From 14182fb64adde6e86a96f7a6ea0c22749124b827 Mon Sep 17 00:00:00 2001
From: AnushaK6 <[email protected]>
Date: Fri, 7 Nov 2025 22:33:04 +0530
Subject: [PATCH 1/3] Add diagnostic reasoning for unsatisfied is_destructible
 trait

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  5 +-
 clang/lib/Sema/SemaTypeTraits.cpp             | 62 +++++++++++++++
 .../type-traits-unsatisfied-diags-std.cpp     | 76 +++++++++++++++++++
 .../SemaCXX/type-traits-unsatisfied-diags.cpp | 49 ++++++++++++
 4 files changed, 191 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4e369be0bbb92..ee357936e3a87 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1776,7 +1776,8 @@ def note_unsatisfied_trait
            "%StandardLayout{standard-layout}|"
            "%Aggregate{aggregate}|"
            "%Final{final}|"
-           "%Abstract{abstract}"
+           "%Abstract{abstract}|"
+           "%Destructible{destructible}"
            "}1">;
 
 def note_unsatisfied_trait_reason
@@ -1808,6 +1809,7 @@ def note_unsatisfied_trait_reason
            "%NonStandardLayoutMember{has a non-standard-layout member %1 of 
type %2}|"
            "%IndirectBaseWithFields{has an indirect base %1 with data 
members}|"
            "%DeletedDtr{has a %select{deleted|user-provided}1 destructor}|"
+           "%InaccessibleDtr{has a %select{private|protected}1 destructor}|"
            "%UserProvidedCtr{has a user provided %select{copy|move}1 "
            "constructor}|"
            "%UserDeclaredCtr{has a user-declared constructor}|"
@@ -1823,6 +1825,7 @@ def note_unsatisfied_trait_reason
            "%FunctionType{is a function type}|"
            "%CVVoidType{is a cv void type}|"
            "%IncompleteArrayType{is an incomplete array type}|"
+           "%IncompleteType{is an incomplete type}|"
            "%PrivateProtectedDirectDataMember{has a 
%select{private|protected}1 direct data member}|"
            "%PrivateProtectedDirectBase{has a %select{private|protected}1 
direct base}|"
            "%NotClassOrUnion{is not a class or union type}|"
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp 
b/clang/lib/Sema/SemaTypeTraits.cpp
index 38877967af05e..e9b8032733efc 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -2028,6 +2028,7 @@ static std::optional<TypeTrait> 
StdNameToTypeTrait(StringRef Name) {
       .Case("is_constructible", TypeTrait::TT_IsConstructible)
       .Case("is_final", TypeTrait::UTT_IsFinal)
       .Case("is_abstract", TypeTrait::UTT_IsAbstract)
+      .Case("is_destructible", TypeTrait::UTT_IsDestructible)
       .Default(std::nullopt);
 }
 
@@ -2399,6 +2400,64 @@ static void DiagnoseNonConstructibleReason(
   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
 }
 
+static void DiagnoseNonDestructibleReason(
+    Sema &SemaRef, SourceLocation Loc,
+    QualType T) {
+
+  QualType CoreT = T.getCanonicalType();
+  if (const ArrayType *AT = SemaRef.Context.getAsArrayType(CoreT))
+    CoreT = AT->getElementType();
+
+  SemaRef.Diag(Loc, diag::note_unsatisfied_trait) << CoreT << 
diag::TraitName::Destructible;
+
+
+  if (CoreT->isFunctionType()){
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) << 
diag::TraitNotSatisfiedReason::FunctionType;
+    return;
+  }
+    
+  if(CoreT->isVoidType()){
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) << 
diag::TraitNotSatisfiedReason::CVVoidType;
+    return;
+  }
+
+  if (CoreT->isIncompleteType()) {
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) << 
diag::TraitNotSatisfiedReason::IncompleteType;
+    return;
+  }
+
+  const CXXRecordDecl *RD = CoreT->getAsCXXRecordDecl();
+  if (!RD || RD->isInvalidDecl())
+    return;
+
+  const CXXRecordDecl *Def = RD->getDefinition();
+  if (!Def) {
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+      << diag::TraitNotSatisfiedReason::IncompleteType;
+    return;
+  }
+
+  CXXDestructorDecl *Dtor = Def->getDestructor();
+  if (!Dtor)
+    return;
+
+  if (Dtor->isDeleted()) {
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+        << diag::TraitNotSatisfiedReason::DeletedDtr << 0
+        << Dtor->getSourceRange();
+    return;
+  }
+
+  AccessSpecifier AS = Dtor->getAccess();
+  if (AS == AS_private || AS == AS_protected) {
+    unsigned Select = (AS == AS_private) ? 0 : 1;
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+        << diag::TraitNotSatisfiedReason::InaccessibleDtr << Select
+        << Dtor->getSourceRange();
+    return;
+  }
+}
+
 static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,
                                                SourceLocation Loc, QualType T) 
{
   SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
@@ -2889,6 +2948,9 @@ void Sema::DiagnoseTypeTraitDetails(const Expr *E) {
   case TT_IsConstructible:
     DiagnoseNonConstructibleReason(*this, E->getBeginLoc(), Args);
     break;
+  case UTT_IsDestructible:
+    DiagnoseNonDestructibleReason(*this, E->getBeginLoc(), Args[0]);
+    break;
   case UTT_IsAggregate:
     DiagnoseNonAggregateReason(*this, E->getBeginLoc(), Args[0]);
     break;
diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp 
b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp
index 3e03a79275232..3e02fe8f10f56 100644
--- a/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp
+++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp
@@ -73,6 +73,15 @@ struct is_abstract {
 template <typename T>
 constexpr bool is_abstract_v = __is_abstract(T);
 
+template <typename T>
+struct is_destructible {
+    static constexpr bool value = __is_destructible(T);
+};
+
+template <typename T>
+constexpr bool is_destructible_v = __is_destructible(T);
+
+
 #endif
 
 #ifdef STD2
@@ -167,6 +176,17 @@ using is_abstract = __details_is_abstract<T>;
 template <typename T>
 constexpr bool is_abstract_v = __is_abstract(T);
 
+template <typename T>
+struct __details_is_destructible {
+    static constexpr bool value = __is_destructible(T);
+};
+
+template <typename T>
+using is_destructible = __details_is_destructible<T>;
+
+template <typename T>
+constexpr bool is_destructible_v = __is_destructible(T);
+
 #endif
 
 
@@ -252,6 +272,15 @@ using is_abstract = __details_is_abstract<T>;
 template <typename T>
 constexpr bool is_abstract_v = is_abstract<T>::value;
 
+template <typename T>
+struct __details_is_destructible : bool_constant<__is_destructible(T)> {};
+
+template <typename T>
+using is_destructible = __details_is_destructible<T>;
+
+template <typename T>
+constexpr bool is_destructible_v = is_destructible<T>::value;
+
 #endif
 }
 
@@ -374,6 +403,18 @@ static_assert(std::is_abstract_v<int&>);
 // expected-note@-1 {{because it is a reference type}} \
 // expected-note@-1 {{because it is not a struct or class type}}
 
+static_assert(std::is_destructible<int>::value);
+
+static_assert(std::is_destructible<void>::value);
+// expected-error-re@-1 {{static assertion failed due to requirement 
'std::{{.*}}is_destructible<void>::value'}} \
+// expected-note@-1 {{'void' is not destructible}} \
+// expected-note@-1 {{because it is a cv void type}}
+
+static_assert(std::is_destructible_v<void>);
+// expected-error@-1 {{static assertion failed due to requirement 
'std::is_destructible_v<void>'}} \
+// expected-note@-1 {{'void' is not destructible}} \
+// expected-note@-1 {{because it is a cv void type}}
+
 
 namespace test_namespace {
     using namespace std;
@@ -473,6 +514,17 @@ namespace test_namespace {
     // expected-note@-1 {{'int &' is not abstract}} \
     // expected-note@-1 {{because it is a reference type}} \
     // expected-note@-1 {{because it is not a struct or class type}}
+
+    static_assert(is_destructible<void>::value);
+    // expected-error-re@-1 {{static assertion failed due to requirement 
'{{.*}}is_destructible<void>::value'}} \
+    // expected-note@-1 {{'void' is not destructible}} \
+    // expected-note@-1 {{because it is a cv void type}}
+
+    static_assert(is_destructible_v<void>);
+    // expected-error@-1 {{static assertion failed due to requirement 
'is_destructible_v<void>'}} \
+    // expected-note@-1 {{'void' is not destructible}} \
+    // expected-note@-1 {{because it is a cv void type}}
+
 }
 
 
@@ -518,6 +570,15 @@ concept C5 = std::is_aggregate_v<T>; // #concept10
 
 template <C5 T> void g5();  // #cand10
 
+template <typename T>
+requires std::is_destructible<T>::value void f6();  // #cand11
+
+template <typename T>
+concept C6 = std::is_destructible_v<T>; // #concept11
+
+template <C6 T> void g6();  // #cand12
+
+
 void test() {
     f<int&>();
     // expected-error@-1 {{no matching function for call to 'f'}} \
@@ -589,6 +650,21 @@ void test() {
     // expected-note@#concept10 {{because 'std::is_aggregate_v<void>' 
evaluated to false}} \
     // expected-note@#concept10 {{'void' is not aggregate}} \
     // expected-note@#concept10 {{because it is a cv void type}}
+
+    f6<void>();
+    // expected-error@-1 {{no matching function for call to 'f6'}} \
+    // expected-note@#cand11 {{candidate template ignored: constraints not 
satisfied [with T = void]}} \
+    // expected-note-re@#cand11 {{because '{{.*}}is_destructible<void>::value' 
evaluated to false}} \
+    // expected-note@#cand11 {{'void' is not destructible}} \
+    // expected-note@#cand11 {{because it is a cv void type}}
+
+    g6<void>();
+    // expected-error@-1 {{no matching function for call to 'g6'}} \
+    // expected-note@#cand12 {{candidate template ignored: constraints not 
satisfied [with T = void]}} \
+    // expected-note@#cand12 {{because 'void' does not satisfy 'C6'}} \
+    // expected-note@#concept11 {{because 'std::is_destructible_v<void>' 
evaluated to false}} \
+    // expected-note@#concept11 {{'void' is not destructible}} \
+    // expected-note@#concept11 {{because it is a cv void type}}
 }
 }
 
diff --git a/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp 
b/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp
index 22740418f09f5..858a5cc24868f 100644
--- a/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp
+++ b/clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp
@@ -1052,3 +1052,52 @@ static_assert(__is_abstract(U));
 // expected-note@-1 {{because it is not a struct or class type}}
 
 }
+namespace destructible {
+
+struct Incomplete; // expected-note {{forward declaration of 
'destructible::Incomplete'}}
+static_assert(__is_destructible(Incomplete));
+// expected-error@-1 {{incomplete type 'Incomplete' used in type trait 
expression}}
+
+static_assert(__is_destructible(void));
+// expected-error@-1 {{static assertion failed due to requirement 
'__is_destructible(void)'}} \
+// expected-note@-1 {{'void' is not destructible}} \
+// expected-note@-1 {{because it is a cv void type}}
+
+using F = void();
+static_assert(__is_destructible(F));
+// expected-error@-1 {{static assertion failed due to requirement 
'__is_destructible(void ())'}} \
+// expected-note@-1 {{'void ()' is not destructible}} \
+// expected-note@-1 {{because it is a function type}}
+
+using Ref = int&;
+static_assert(__is_destructible(Ref)); // no diagnostics (true)
+
+struct DeletedDtor { // #d-DeletedDtor
+  ~DeletedDtor() = delete;
+};
+static_assert(__is_destructible(DeletedDtor));
+// expected-error@-1 {{static assertion failed due to requirement 
'__is_destructible(destructible::DeletedDtor)'}} \
+// expected-note@-1 {{'destructible::DeletedDtor' is not destructible}} \
+// expected-note@-1 {{because it has a deleted destructor}}
+
+struct PrivateDtor { // #d-PrivateDtor
+private:
+  ~PrivateDtor(); // #d-PrivateDtor-dtor
+};
+static_assert(__is_destructible(PrivateDtor));
+// expected-error@-1 {{static assertion failed due to requirement 
'__is_destructible(destructible::PrivateDtor)'}} \
+// expected-note@-1 {{'destructible::PrivateDtor' is not destructible}} \
+// expected-note@-1 {{because it has a private destructor}}
+
+struct BaseInaccessible { // #d-BaseInacc
+private:
+  ~BaseInaccessible(); // #d-BaseInacc-dtor
+};
+
+struct DerivedFromInaccessible : BaseInaccessible {}; // #d-DerivedInacc
+static_assert(__is_destructible(DerivedFromInaccessible));
+// expected-error@-1 {{static assertion failed due to requirement 
'__is_destructible(destructible::DerivedFromInaccessible)'}} \
+// expected-note@-1 {{'destructible::DerivedFromInaccessible' is not 
destructible}} \
+// expected-note@-1 {{because it has a deleted destructor}}
+
+}

>From 5b5bdbfeafceedec79b173bf8e1d317818d7127d Mon Sep 17 00:00:00 2001
From: AnushaK6 <[email protected]>
Date: Fri, 7 Nov 2025 22:34:51 +0530
Subject: [PATCH 2/3] [NFC] Format code using clang-format

---
 clang/lib/Sema/SemaTypeTraits.cpp | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Sema/SemaTypeTraits.cpp 
b/clang/lib/Sema/SemaTypeTraits.cpp
index e9b8032733efc..fef47dfc2cc51 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -2400,29 +2400,31 @@ static void DiagnoseNonConstructibleReason(
   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
 }
 
-static void DiagnoseNonDestructibleReason(
-    Sema &SemaRef, SourceLocation Loc,
-    QualType T) {
+static void DiagnoseNonDestructibleReason(Sema &SemaRef, SourceLocation Loc,
+                                          QualType T) {
 
   QualType CoreT = T.getCanonicalType();
   if (const ArrayType *AT = SemaRef.Context.getAsArrayType(CoreT))
     CoreT = AT->getElementType();
 
-  SemaRef.Diag(Loc, diag::note_unsatisfied_trait) << CoreT << 
diag::TraitName::Destructible;
-
+  SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
+      << CoreT << diag::TraitName::Destructible;
 
-  if (CoreT->isFunctionType()){
-    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) << 
diag::TraitNotSatisfiedReason::FunctionType;
+  if (CoreT->isFunctionType()) {
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+        << diag::TraitNotSatisfiedReason::FunctionType;
     return;
   }
-    
-  if(CoreT->isVoidType()){
-    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) << 
diag::TraitNotSatisfiedReason::CVVoidType;
+
+  if (CoreT->isVoidType()) {
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+        << diag::TraitNotSatisfiedReason::CVVoidType;
     return;
   }
 
   if (CoreT->isIncompleteType()) {
-    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) << 
diag::TraitNotSatisfiedReason::IncompleteType;
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+        << diag::TraitNotSatisfiedReason::IncompleteType;
     return;
   }
 
@@ -2433,7 +2435,7 @@ static void DiagnoseNonDestructibleReason(
   const CXXRecordDecl *Def = RD->getDefinition();
   if (!Def) {
     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
-      << diag::TraitNotSatisfiedReason::IncompleteType;
+        << diag::TraitNotSatisfiedReason::IncompleteType;
     return;
   }
 

>From 8ba77ae65bbfd5b809c17de7c718c451c535ca54 Mon Sep 17 00:00:00 2001
From: AnushaK6 <[email protected]>
Date: Sun, 9 Nov 2025 22:58:51 +0530
Subject: [PATCH 3/3] [GlobalISel] Port computeNumSignBits for G_MUL

---
 .../CodeGen/GlobalISel/GISelValueTracking.cpp | 37 +++++++++
 .../AArch64/GlobalISel/knownbits-mul.mir      | 79 +++++++++++++++++++
 llvm/test/CodeGen/AArch64/combine-sdiv.ll     |  4 +-
 llvm/test/CodeGen/AArch64/rem-by-const.ll     |  3 +-
 4 files changed, 118 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-mul.mir

diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp 
b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index c1fb8b6d78ff8..3a4d8c27ac88b 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -37,6 +37,8 @@
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Support/KnownFPClass.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/IR/Constants.h"
 
 #define DEBUG_TYPE "gisel-known-bits"
 
@@ -2084,6 +2086,41 @@ unsigned GISelValueTracking::computeNumSignBits(Register 
R,
     FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
     break;
   }
+  case TargetOpcode::G_MUL: {
+    Register Src1 = MI.getOperand(1).getReg();
+    Register Src2 = MI.getOperand(2).getReg();
+
+    KnownBits Known1 = getKnownBits(Src1, DemandedElts, Depth + 1);
+    KnownBits Known2 = getKnownBits(Src2, DemandedElts, Depth + 1);
+
+    if (Known1.isZero() || Known2.isZero())
+      return TyBits;
+    
+    auto C1 = getIConstantVRegValWithLookThrough(Src1, MRI);
+    auto C2 = getIConstantVRegValWithLookThrough(Src2, MRI);
+
+    if (C1 && C2) {
+      APInt Val1 = C1->Value;
+      APInt Val2 = C2->Value;
+      APInt Product = Val1 * Val2;
+      return Product.getNumSignBits();
+    }
+    unsigned Src1NumSignBits =
+        computeNumSignBits(Src1, DemandedElts, Depth + 1);
+    if(Src1NumSignBits==1){
+      return 1;
+    }
+    unsigned Src2NumSignBits =
+        computeNumSignBits(Src2, DemandedElts, Depth + 1);
+    if(Src2NumSignBits==1){
+      return 1;
+    }
+
+    unsigned OutValidBits =
+      (TyBits - Src1NumSignBits + 1) + (TyBits - Src2NumSignBits + 1);
+    FirstAnswer = OutValidBits > TyBits ? 1 : TyBits - OutValidBits + 1;
+    break;
+  }
   case TargetOpcode::G_FCMP:
   case TargetOpcode::G_ICMP: {
     bool IsFP = Opcode == TargetOpcode::G_FCMP;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-mul.mir 
b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-mul.mir
new file mode 100644
index 0000000000000..ea5281948a211
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-mul.mir
@@ -0,0 +1,79 @@
+# NOTE: Assertions have been autogenerated by 
utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=aarch64 -passes="print<gisel-value-tracking>" 
-filetype=null %s 2>&1 | FileCheck %s
+
+---
+name:            ConstPositives
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @ConstPositives
+  ; CHECK-NEXT: %0:_ KnownBits:00000011 SignBits:6
+  ; CHECK-NEXT: %1:_ KnownBits:00000101 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:00001111 SignBits:4
+    %0:_(s8) = G_CONSTANT i8 3
+    %1:_(s8) = G_CONSTANT i8 5
+    %2:_(s8) = G_MUL %0, %1
+...
+---
+name:            ConstZero
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @ConstZero
+  ; CHECK-NEXT: %0:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %1:_ KnownBits:00000001 SignBits:7
+  ; CHECK-NEXT: %2:_ KnownBits:00000000 SignBits:8
+    %0:_(s8) = G_CONSTANT i8 0
+    %1:_(s8) = G_CONSTANT i8 1
+    %2:_(s8) = G_MUL %0, %1
+...
+---
+name:            ConstNegatives
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @ConstNegatives
+  ; CHECK-NEXT: %0:_ KnownBits:11111110 SignBits:7
+  ; CHECK-NEXT: %1:_ KnownBits:11111100 SignBits:6
+  ; CHECK-NEXT: %2:_ KnownBits:00001000 SignBits:4
+    %0:_(s8) = G_CONSTANT i8 -2
+    %1:_(s8) = G_CONSTANT i8 -4
+    %2:_(s8) = G_MUL %0, %1
+...
+---
+name:            MixedSigns
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @MixedSigns
+  ; CHECK-NEXT: %0:_ KnownBits:11111100 SignBits:6
+  ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6
+  ; CHECK-NEXT: %2:_ KnownBits:11110100 SignBits:4
+    %0:_(s8) = G_CONSTANT i8 -4
+    %1:_(s8) = G_CONSTANT i8 3
+    %2:_(s8) = G_MUL %0, %1
+...
+---
+name:            UnknownVar
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @UnknownVar
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000010 SignBits:6
+  ; CHECK-NEXT: %2:_ KnownBits:???????0 SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = G_CONSTANT i8 2
+    %2:_(s8) = G_MUL %0, %1
+...
+---
+name:            VectorMul
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @VectorMul
+  ; CHECK-NEXT: %0:_ KnownBits:0000000000000001 SignBits:15
+  ; CHECK-NEXT: %1:_ KnownBits:0000000000000010 SignBits:14
+  ; CHECK-NEXT: %2:_ KnownBits:00000000000000?? SignBits:14
+  ; CHECK-NEXT: %3:_ KnownBits:00000000000000?? SignBits:14
+  ; CHECK-NEXT: %4:_ KnownBits:000000000000???? SignBits:12
+    %0:_(s16) = G_CONSTANT i16 1
+    %1:_(s16) = G_CONSTANT i16 2
+    %2:_(<4 x s16>) = G_BUILD_VECTOR %0, %1, %1, %0
+    %3:_(<4 x s16>) = G_BUILD_VECTOR %1, %0, %0, %1
+    %4:_(<4 x s16>) = G_MUL %2, %3
+...
diff --git a/llvm/test/CodeGen/AArch64/combine-sdiv.ll 
b/llvm/test/CodeGen/AArch64/combine-sdiv.ll
index cca190f08df2b..37ea64f700fd8 100644
--- a/llvm/test/CodeGen/AArch64/combine-sdiv.ll
+++ b/llvm/test/CodeGen/AArch64/combine-sdiv.ll
@@ -1510,7 +1510,6 @@ define i5 @combine_i5_sdiv_const7(i5 %x) {
 ; CHECK-GI-NEXT:    sbfx w9, w0, #0, #5
 ; CHECK-GI-NEXT:    sbfx w8, w8, #0, #5
 ; CHECK-GI-NEXT:    mul w8, w9, w8
-; CHECK-GI-NEXT:    sbfx w8, w8, #0, #10
 ; CHECK-GI-NEXT:    add w8, w0, w8, asr #5
 ; CHECK-GI-NEXT:    sbfx w8, w8, #0, #5
 ; CHECK-GI-NEXT:    asr w8, w8, #2
@@ -1560,7 +1559,6 @@ define i8 @combine_i8_sdiv_const7(i8 %x) {
 ; CHECK-GI-NEXT:    sxtb w8, w0
 ; CHECK-GI-NEXT:    mov w9, #-109 // =0xffffff93
 ; CHECK-GI-NEXT:    mul w8, w8, w9
-; CHECK-GI-NEXT:    sxth w8, w8
 ; CHECK-GI-NEXT:    add w8, w0, w8, asr #8
 ; CHECK-GI-NEXT:    sbfx w8, w8, #2, #6
 ; CHECK-GI-NEXT:    ubfx w9, w8, #7, #1
@@ -1585,7 +1583,7 @@ define i8 @combine_i8_sdiv_const100(i8 %x) {
 ; CHECK-GI-NEXT:    sxtb w8, w0
 ; CHECK-GI-NEXT:    mov w9, #41 // =0x29
 ; CHECK-GI-NEXT:    mul w8, w8, w9
-; CHECK-GI-NEXT:    sbfx w8, w8, #8, #8
+; CHECK-GI-NEXT:    asr w8, w8, #8
 ; CHECK-GI-NEXT:    asr w8, w8, #4
 ; CHECK-GI-NEXT:    ubfx w9, w8, #7, #1
 ; CHECK-GI-NEXT:    add w0, w8, w9
diff --git a/llvm/test/CodeGen/AArch64/rem-by-const.ll 
b/llvm/test/CodeGen/AArch64/rem-by-const.ll
index 87b11086e28d5..9cc00fae412a0 100644
--- a/llvm/test/CodeGen/AArch64/rem-by-const.ll
+++ b/llvm/test/CodeGen/AArch64/rem-by-const.ll
@@ -21,7 +21,6 @@ define i8 @si8_7(i8 %a, i8 %b) {
 ; CHECK-GI-NEXT:    sxtb w8, w0
 ; CHECK-GI-NEXT:    mov w9, #-109 // =0xffffff93
 ; CHECK-GI-NEXT:    mul w8, w8, w9
-; CHECK-GI-NEXT:    sxth w8, w8
 ; CHECK-GI-NEXT:    add w8, w0, w8, asr #8
 ; CHECK-GI-NEXT:    sbfx w8, w8, #2, #6
 ; CHECK-GI-NEXT:    ubfx w9, w8, #7, #1
@@ -52,7 +51,7 @@ define i8 @si8_100(i8 %a, i8 %b) {
 ; CHECK-GI-NEXT:    sxtb w8, w0
 ; CHECK-GI-NEXT:    mov w9, #41 // =0x29
 ; CHECK-GI-NEXT:    mul w8, w8, w9
-; CHECK-GI-NEXT:    sbfx w8, w8, #8, #8
+; CHECK-GI-NEXT:    asr w8, w8, #8
 ; CHECK-GI-NEXT:    asr w8, w8, #4
 ; CHECK-GI-NEXT:    ubfx w9, w8, #7, #1
 ; CHECK-GI-NEXT:    add w8, w8, w9

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to