Skip to content

Commit aa3672e

Browse files
author
z1_cciauto
authored
merge main into amd-staging (llvm#3713)
2 parents 56517ed + 158cbc9 commit aa3672e

35 files changed

+975
-580
lines changed

clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ class RenamerClangTidyCheckPPCallbacks : public PPCallbacks {
194194
return;
195195
if (SM.isWrittenInCommandLineFile(MacroNameTok.getLocation()))
196196
return;
197+
if (SM.isInSystemHeader(MacroNameTok.getLocation()))
198+
return;
197199
Check->checkMacro(MacroNameTok, Info, SM);
198200
}
199201

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ Changes in existing checks
163163

164164
- Improved :doc:`bugprone-reserved-identifier
165165
<clang-tidy/checks/bugprone/reserved-identifier>` check by ignoring
166-
declarations in system headers.
166+
declarations and macros in system headers.
167167

168168
- Improved :doc:`bugprone-signed-char-misuse
169169
<clang-tidy/checks/bugprone/signed-char-misuse>` check by fixing
@@ -229,8 +229,8 @@ Changes in existing checks
229229

230230
- Improved :doc:`readability-identifier-naming
231231
<clang-tidy/checks/readability/identifier-naming>` check by ignoring
232-
declarations in system headers. The documentation is also improved to
233-
differentiate the general options from the specific ones.
232+
declarations and macros in system headers. The documentation is also improved
233+
to differentiate the general options from the specific ones.
234234

235235
- Improved :doc:`readability-qualified-auto
236236
<clang-tidy/checks/readability/qualified-auto>` check by adding the option

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "interception/interception.h"
1717
#include "sanitizer_common/sanitizer_allocator_dlsym.h"
18+
#include "sanitizer_common/sanitizer_glibc_version.h"
1819
#include "sanitizer_common/sanitizer_platform_interceptors.h"
1920

2021
#include "interception/interception.h"
@@ -46,12 +47,41 @@
4647

4748
using namespace __sanitizer;
4849

50+
DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, usize size)
51+
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)
52+
4953
namespace {
5054
struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
5155
static bool UseImpl() { return !__rtsan_is_initialized(); }
5256
};
5357
} // namespace
5458

59+
// See note in tsan as to why this is necessary
60+
static pthread_cond_t *init_cond(pthread_cond_t *c, bool force = false) {
61+
if (!common_flags()->legacy_pthread_cond)
62+
return c;
63+
64+
atomic_uintptr_t *p = (atomic_uintptr_t *)c;
65+
uptr cond = atomic_load(p, memory_order_acquire);
66+
if (!force && cond != 0)
67+
return (pthread_cond_t *)cond;
68+
void *newcond = WRAP(malloc)(sizeof(pthread_cond_t));
69+
internal_memset(newcond, 0, sizeof(pthread_cond_t));
70+
if (atomic_compare_exchange_strong(p, &cond, (uptr)newcond,
71+
memory_order_acq_rel))
72+
return (pthread_cond_t *)newcond;
73+
WRAP(free)(newcond);
74+
return (pthread_cond_t *)cond;
75+
}
76+
77+
static void destroy_cond(pthread_cond_t *cond) {
78+
if (common_flags()->legacy_pthread_cond) {
79+
// Free our aux cond and zero the pointer to not leave dangling pointers.
80+
WRAP(free)(cond);
81+
atomic_store((atomic_uintptr_t *)cond, 0, memory_order_relaxed);
82+
}
83+
}
84+
5585
// Filesystem
5686

5787
INTERCEPTOR(int, open, const char *path, int oflag, ...) {
@@ -766,26 +796,45 @@ INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) {
766796
return REAL(pthread_join)(thread, value_ptr);
767797
}
768798

799+
INTERCEPTOR(int, pthread_cond_init, pthread_cond_t *cond,
800+
const pthread_condattr_t *a) {
801+
__rtsan_notify_intercepted_call("pthread_cond_init");
802+
pthread_cond_t *c = init_cond(cond, true);
803+
return REAL(pthread_cond_init)(c, a);
804+
}
805+
769806
INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) {
770807
__rtsan_notify_intercepted_call("pthread_cond_signal");
771-
return REAL(pthread_cond_signal)(cond);
808+
pthread_cond_t *c = init_cond(cond);
809+
return REAL(pthread_cond_signal)(c);
772810
}
773811

774812
INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) {
775813
__rtsan_notify_intercepted_call("pthread_cond_broadcast");
776-
return REAL(pthread_cond_broadcast)(cond);
814+
pthread_cond_t *c = init_cond(cond);
815+
return REAL(pthread_cond_broadcast)(c);
777816
}
778817

779818
INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond,
780819
pthread_mutex_t *mutex) {
781820
__rtsan_notify_intercepted_call("pthread_cond_wait");
782-
return REAL(pthread_cond_wait)(cond, mutex);
821+
pthread_cond_t *c = init_cond(cond);
822+
return REAL(pthread_cond_wait)(c, mutex);
783823
}
784824

785825
INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond,
786826
pthread_mutex_t *mutex, const timespec *ts) {
787827
__rtsan_notify_intercepted_call("pthread_cond_timedwait");
788-
return REAL(pthread_cond_timedwait)(cond, mutex, ts);
828+
pthread_cond_t *c = init_cond(cond);
829+
return REAL(pthread_cond_timedwait)(c, mutex, ts);
830+
}
831+
832+
INTERCEPTOR(int, pthread_cond_destroy, pthread_cond_t *cond) {
833+
__rtsan_notify_intercepted_call("pthread_cond_destroy");
834+
pthread_cond_t *c = init_cond(cond);
835+
int res = REAL(pthread_cond_destroy)(c);
836+
destroy_cond(c);
837+
return res;
789838
}
790839

791840
INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) {
@@ -1641,10 +1690,26 @@ void __rtsan::InitializeInterceptors() {
16411690
INTERCEPT_FUNCTION(pthread_mutex_lock);
16421691
INTERCEPT_FUNCTION(pthread_mutex_unlock);
16431692
INTERCEPT_FUNCTION(pthread_join);
1693+
1694+
// See the comment in tsan_interceptors_posix.cpp.
1695+
#if SANITIZER_GLIBC && !__GLIBC_PREREQ(2, 36) && \
1696+
(defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \
1697+
defined(__s390x__))
1698+
INTERCEPT_FUNCTION_VER(pthread_cond_init, "GLIBC_2.3.2");
1699+
INTERCEPT_FUNCTION_VER(pthread_cond_signal, "GLIBC_2.3.2");
1700+
INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, "GLIBC_2.3.2");
1701+
INTERCEPT_FUNCTION_VER(pthread_cond_wait, "GLIBC_2.3.2");
1702+
INTERCEPT_FUNCTION_VER(pthread_cond_timedwait, "GLIBC_2.3.2");
1703+
INTERCEPT_FUNCTION_VER(pthread_cond_destroy, "GLIBC_2.3.2");
1704+
#else
1705+
INTERCEPT_FUNCTION(pthread_cond_init);
16441706
INTERCEPT_FUNCTION(pthread_cond_signal);
16451707
INTERCEPT_FUNCTION(pthread_cond_broadcast);
16461708
INTERCEPT_FUNCTION(pthread_cond_wait);
16471709
INTERCEPT_FUNCTION(pthread_cond_timedwait);
1710+
INTERCEPT_FUNCTION(pthread_cond_destroy);
1711+
#endif
1712+
16481713
INTERCEPT_FUNCTION(pthread_rwlock_rdlock);
16491714
INTERCEPT_FUNCTION(pthread_rwlock_unlock);
16501715
INTERCEPT_FUNCTION(pthread_rwlock_wrlock);

compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,24 @@ TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {
12411241
}
12421242
#endif
12431243

1244+
TEST(TestRtsanInterceptors, PthreadCondInitDiesWhenRealtime) {
1245+
pthread_cond_t cond{};
1246+
auto Func = [&cond]() { pthread_cond_init(&cond, nullptr); };
1247+
ExpectRealtimeDeath(Func, "pthread_cond_init");
1248+
ExpectNonRealtimeSurvival(Func);
1249+
}
1250+
1251+
TEST(TestRtsanInterceptors, PthreadCondDestroyDiesWhenRealtime) {
1252+
pthread_cond_t cond{};
1253+
ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
1254+
1255+
auto Func = [&cond]() { pthread_cond_destroy(&cond); };
1256+
ExpectRealtimeDeath(Func, "pthread_cond_destroy");
1257+
ExpectNonRealtimeSurvival(Func);
1258+
1259+
pthread_cond_destroy(&cond);
1260+
}
1261+
12441262
TEST(TestRtsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
12451263
pthread_cond_t cond{};
12461264
ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));

llvm/include/llvm/ADT/SmallSet.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ class SmallSet {
272272
/// We use this middleman class DeprecatedSmallSet so that the deprecation
273273
/// warning works. Placing LLVM_DEPRECATED just before SmallSet below won't
274274
/// work.
275-
template <typename PointeeType, unsigned N>
275+
template <typename PointerType, unsigned N>
276276
class LLVM_DEPRECATED("Use SmallPtrSet instead", "SmallPtrSet")
277-
DeprecatedSmallSet : public SmallPtrSet<PointeeType *, N> {};
277+
DeprecatedSmallSet : public SmallPtrSet<PointerType, N> {};
278278

279279
template <typename PointeeType, unsigned N>
280280
class SmallSet<PointeeType *, N> : public DeprecatedSmallSet<PointeeType *, N> {

llvm/lib/Target/AMDGPU/MIMGInstructions.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,9 +2044,9 @@ class VIMAGE_TENSOR_Pseudo<string opName, bit _UpTo2D = 0> :
20442044
let hasSideEffects = 0;
20452045

20462046
bit UpTo2D = _UpTo2D;
2047-
let InOperandList = !if(UpTo2D, (ins SReg_128:$vaddr0, SReg_256:$vaddr1, R128A16:$r128, CPol:$cpol),
2048-
(ins SReg_128:$vaddr0, SReg_256:$vaddr1, SReg_128:$vaddr2,
2049-
SReg_128:$vaddr3, R128A16:$r128, CPol:$cpol));
2047+
let InOperandList = !if(UpTo2D, (ins SReg_128_XNULL:$vaddr0, SReg_256_XNULL:$vaddr1, R128A16:$r128, CPol:$cpol),
2048+
(ins SReg_128_XNULL:$vaddr0, SReg_256_XNULL:$vaddr1, SReg_128_XNULL:$vaddr2,
2049+
SReg_128_XNULL:$vaddr3, R128A16:$r128, CPol:$cpol));
20502050
string AsmOperands = " $vaddr0, $vaddr1"#!if(UpTo2D, "", ", $vaddr2, $vaddr3")#"$r128$cpol";
20512051
}
20522052

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8599,8 +8599,7 @@ static void addExitUsersForFirstOrderRecurrences(VPlan &Plan, VFRange &Range) {
85998599
// the VPIRInstruction modeling the phi.
86008600
for (VPUser *U : FOR->users()) {
86018601
using namespace llvm::VPlanPatternMatch;
8602-
if (!match(U, m_VPInstruction<VPInstruction::ExtractLastElement>(
8603-
m_Specific(FOR))))
8602+
if (!match(U, m_ExtractLastElement(m_Specific(FOR))))
86048603
continue;
86058604
// For VF vscale x 1, if vscale = 1, we are unable to extract the
86068605
// penultimate value of the recurrence. Instead we rely on the existing
@@ -8909,7 +8908,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(
89098908
VPlanTransforms::addActiveLaneMask(*Plan, ForControlFlow,
89108909
WithoutRuntimeCheck);
89118910
}
8912-
VPlanTransforms::optimizeInductionExitUsers(*Plan, IVEndValues);
8911+
VPlanTransforms::optimizeInductionExitUsers(*Plan, IVEndValues, *PSE.getSE());
89138912

89148913
assert(verifyVPlanIsValid(*Plan) && "VPlan is invalid");
89158914
return Plan;
@@ -9242,8 +9241,7 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
92429241
if (FinalReductionResult == U || Parent->getParent())
92439242
continue;
92449243
U->replaceUsesOfWith(OrigExitingVPV, FinalReductionResult);
9245-
if (match(U, m_VPInstruction<VPInstruction::ExtractLastElement>(
9246-
m_VPValue())))
9244+
if (match(U, m_ExtractLastElement(m_VPValue())))
92479245
cast<VPInstruction>(U)->replaceAllUsesWith(FinalReductionResult);
92489246
}
92499247

llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,9 @@ SmallVector<VPRegisterUsage, 8> llvm::calculateRegisterUsageForPlan(
442442
// assume that each recipe that has in-loop users starts an interval. We
443443
// record every time that an in-loop value is used, so we have a list of the
444444
// first and last occurrences of each recipe.
445+
VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
445446
ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>> RPOT(
446-
Plan.getVectorLoopRegion());
447+
LoopRegion);
447448
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
448449
if (!VPBB->getParent())
449450
break;
@@ -473,10 +474,10 @@ SmallVector<VPRegisterUsage, 8> llvm::calculateRegisterUsageForPlan(
473474
Ends.insert(DefR);
474475
}
475476
}
476-
if (VPBB == Plan.getVectorLoopRegion()->getExiting()) {
477+
if (VPBB == LoopRegion->getExiting()) {
477478
// VPWidenIntOrFpInductionRecipes are used implicitly at the end of the
478479
// exiting block, where their increment will get materialized eventually.
479-
for (auto &R : Plan.getVectorLoopRegion()->getEntryBasicBlock()->phis()) {
480+
for (auto &R : LoopRegion->getEntryBasicBlock()->phis()) {
480481
if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
481482
EndPoint[&R] = Idx2Recipe.size();
482483
Ends.insert(&R);

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ m_Broadcast(const Op0_t &Op0) {
301301
return m_VPInstruction<VPInstruction::Broadcast>(Op0);
302302
}
303303

304+
template <typename Op0_t>
305+
inline VPInstruction_match<VPInstruction::ExtractLastElement, Op0_t>
306+
m_ExtractLastElement(const Op0_t &Op0) {
307+
return m_VPInstruction<VPInstruction::ExtractLastElement>(Op0);
308+
}
304309
template <typename Op0_t, typename Op1_t>
305310
inline VPInstruction_match<VPInstruction::ActiveLaneMask, Op0_t, Op1_t>
306311
m_ActiveLaneMask(const Op0_t &Op0, const Op1_t &Op1) {

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,8 @@ static void legalizeAndOptimizeInductions(VPlan &Plan) {
716716
/// Check if \p VPV is an untruncated wide induction, either before or after the
717717
/// increment. If so return the header IV (before the increment), otherwise
718718
/// return null.
719-
static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV) {
719+
static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV,
720+
ScalarEvolution &SE) {
720721
auto *WideIV = dyn_cast<VPWidenInductionRecipe>(VPV);
721722
if (WideIV) {
722723
// VPV itself is a wide induction, separately compute the end value for exit
@@ -753,13 +754,13 @@ static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV) {
753754
// IVStep will be the negated step of the subtraction. Check if Step == -1
754755
// * IVStep.
755756
VPValue *Step;
756-
if (!match(VPV, m_Sub(m_VPValue(), m_VPValue(Step))) ||
757-
!Step->isLiveIn() || !IVStep->isLiveIn())
757+
if (!match(VPV, m_Sub(m_VPValue(), m_VPValue(Step))))
758758
return false;
759-
auto *StepCI = dyn_cast<ConstantInt>(Step->getLiveInIRValue());
760-
auto *IVStepCI = dyn_cast<ConstantInt>(IVStep->getLiveInIRValue());
761-
return StepCI && IVStepCI &&
762-
StepCI->getValue() == (-1 * IVStepCI->getValue());
759+
const SCEV *IVStepSCEV = vputils::getSCEVExprForVPValue(IVStep, SE);
760+
const SCEV *StepSCEV = vputils::getSCEVExprForVPValue(Step, SE);
761+
return !isa<SCEVCouldNotCompute>(IVStepSCEV) &&
762+
!isa<SCEVCouldNotCompute>(StepSCEV) &&
763+
IVStepSCEV == SE.getNegativeSCEV(StepSCEV);
763764
}
764765
default:
765766
return ID.getKind() == InductionDescriptor::IK_PtrInduction &&
@@ -776,15 +777,16 @@ static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV) {
776777
static VPValue *optimizeEarlyExitInductionUser(VPlan &Plan,
777778
VPTypeAnalysis &TypeInfo,
778779
VPBlockBase *PredVPBB,
779-
VPValue *Op) {
780+
VPValue *Op,
781+
ScalarEvolution &SE) {
780782
VPValue *Incoming, *Mask;
781783
if (!match(Op, m_VPInstruction<VPInstruction::ExtractLane>(
782784
m_VPInstruction<VPInstruction::FirstActiveLane>(
783785
m_VPValue(Mask)),
784786
m_VPValue(Incoming))))
785787
return nullptr;
786788

787-
auto *WideIV = getOptimizableIVOf(Incoming);
789+
auto *WideIV = getOptimizableIVOf(Incoming, SE);
788790
if (!WideIV)
789791
return nullptr;
790792

@@ -827,16 +829,14 @@ static VPValue *optimizeEarlyExitInductionUser(VPlan &Plan,
827829

828830
/// Attempts to optimize the induction variable exit values for users in the
829831
/// exit block coming from the latch in the original scalar loop.
830-
static VPValue *
831-
optimizeLatchExitInductionUser(VPlan &Plan, VPTypeAnalysis &TypeInfo,
832-
VPBlockBase *PredVPBB, VPValue *Op,
833-
DenseMap<VPValue *, VPValue *> &EndValues) {
832+
static VPValue *optimizeLatchExitInductionUser(
833+
VPlan &Plan, VPTypeAnalysis &TypeInfo, VPBlockBase *PredVPBB, VPValue *Op,
834+
DenseMap<VPValue *, VPValue *> &EndValues, ScalarEvolution &SE) {
834835
VPValue *Incoming;
835-
if (!match(Op, m_VPInstruction<VPInstruction::ExtractLastElement>(
836-
m_VPValue(Incoming))))
836+
if (!match(Op, m_ExtractLastElement(m_VPValue(Incoming))))
837837
return nullptr;
838838

839-
auto *WideIV = getOptimizableIVOf(Incoming);
839+
auto *WideIV = getOptimizableIVOf(Incoming, SE);
840840
if (!WideIV)
841841
return nullptr;
842842

@@ -875,7 +875,8 @@ optimizeLatchExitInductionUser(VPlan &Plan, VPTypeAnalysis &TypeInfo,
875875
}
876876

877877
void VPlanTransforms::optimizeInductionExitUsers(
878-
VPlan &Plan, DenseMap<VPValue *, VPValue *> &EndValues) {
878+
VPlan &Plan, DenseMap<VPValue *, VPValue *> &EndValues,
879+
ScalarEvolution &SE) {
879880
VPBlockBase *MiddleVPBB = Plan.getMiddleBlock();
880881
VPTypeAnalysis TypeInfo(Plan);
881882
for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks()) {
@@ -885,11 +886,12 @@ void VPlanTransforms::optimizeInductionExitUsers(
885886
for (auto [Idx, PredVPBB] : enumerate(ExitVPBB->getPredecessors())) {
886887
VPValue *Escape = nullptr;
887888
if (PredVPBB == MiddleVPBB)
888-
Escape = optimizeLatchExitInductionUser(
889-
Plan, TypeInfo, PredVPBB, ExitIRI->getOperand(Idx), EndValues);
889+
Escape = optimizeLatchExitInductionUser(Plan, TypeInfo, PredVPBB,
890+
ExitIRI->getOperand(Idx),
891+
EndValues, SE);
890892
else
891893
Escape = optimizeEarlyExitInductionUser(Plan, TypeInfo, PredVPBB,
892-
ExitIRI->getOperand(Idx));
894+
ExitIRI->getOperand(Idx), SE);
893895
if (Escape)
894896
ExitIRI->setOperand(Idx, Escape);
895897
}
@@ -1173,8 +1175,7 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
11731175
}
11741176

11751177
// Look through ExtractLastElement (BuildVector ....).
1176-
if (match(&R, m_VPInstruction<VPInstruction::ExtractLastElement>(
1177-
m_BuildVector()))) {
1178+
if (match(&R, m_ExtractLastElement(m_BuildVector()))) {
11781179
auto *BuildVector = cast<VPInstruction>(R.getOperand(0));
11791180
Def->replaceAllUsesWith(
11801181
BuildVector->getOperand(BuildVector->getNumOperands() - 1));
@@ -1228,15 +1229,13 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
12281229
return;
12291230
}
12301231

1231-
if (match(Def, m_VPInstruction<VPInstruction::ExtractLastElement>(
1232-
m_Broadcast(m_VPValue(A))))) {
1232+
if (match(Def, m_ExtractLastElement(m_Broadcast(m_VPValue(A))))) {
12331233
Def->replaceAllUsesWith(A);
12341234
return;
12351235
}
12361236

12371237
VPInstruction *OpVPI;
1238-
if (match(Def, m_VPInstruction<VPInstruction::ExtractLastElement>(
1239-
m_VPInstruction(OpVPI))) &&
1238+
if (match(Def, m_ExtractLastElement(m_VPInstruction(OpVPI))) &&
12401239
OpVPI->isVectorToScalar()) {
12411240
Def->replaceAllUsesWith(OpVPI);
12421241
return;

0 commit comments

Comments
 (0)