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
