@@ -1435,6 +1435,33 @@ static Instruction *foldBitOrderCrossLogicOp(Value *V,
1435
1435
return nullptr ;
1436
1436
}
1437
1437
1438
+ static Value *simplifyReductionOperand (Value *Arg, bool CanReorderLanes) {
1439
+ if (!CanReorderLanes)
1440
+ return nullptr ;
1441
+
1442
+ Value *V;
1443
+ if (match (Arg, m_VecReverse (m_Value (V))))
1444
+ return V;
1445
+
1446
+ ArrayRef<int > Mask;
1447
+ if (!isa<FixedVectorType>(Arg->getType ()) ||
1448
+ !match (Arg, m_Shuffle (m_Value (V), m_Undef (), m_Mask (Mask))) ||
1449
+ !cast<ShuffleVectorInst>(Arg)->isSingleSource ())
1450
+ return nullptr ;
1451
+
1452
+ int Sz = Mask.size ();
1453
+ SmallBitVector UsedIndices (Sz);
1454
+ for (int Idx : Mask) {
1455
+ if (Idx == PoisonMaskElem || UsedIndices.test (Idx))
1456
+ return nullptr ;
1457
+ UsedIndices.set (Idx);
1458
+ }
1459
+
1460
+ // Can remove shuffle iff just shuffled elements, no repeats, undefs, or
1461
+ // other changes.
1462
+ return UsedIndices.all () ? V : nullptr ;
1463
+ }
1464
+
1438
1465
// / CallInst simplification. This mostly only handles folding of intrinsic
1439
1466
// / instructions. For normal calls, it allows visitCallBase to do the heavy
1440
1467
// / lifting.
@@ -3223,6 +3250,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
3223
3250
// %res = cmp eq iReduxWidth %val, 11111
3224
3251
Value *Arg = II->getArgOperand (0 );
3225
3252
Value *Vect;
3253
+
3254
+ if (Value *NewOp =
3255
+ simplifyReductionOperand (Arg, /* CanReorderLanes=*/ true )) {
3256
+ replaceUse (II->getOperandUse (0 ), NewOp);
3257
+ return II;
3258
+ }
3259
+
3226
3260
if (match (Arg, m_ZExtOrSExtOrSelf (m_Value (Vect)))) {
3227
3261
if (auto *FTy = dyn_cast<FixedVectorType>(Vect->getType ()))
3228
3262
if (FTy->getElementType () == Builder.getInt1Ty ()) {
@@ -3254,6 +3288,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
3254
3288
// Trunc(ctpop(bitcast <n x i1> to in)).
3255
3289
Value *Arg = II->getArgOperand (0 );
3256
3290
Value *Vect;
3291
+
3292
+ if (Value *NewOp =
3293
+ simplifyReductionOperand (Arg, /* CanReorderLanes=*/ true )) {
3294
+ replaceUse (II->getOperandUse (0 ), NewOp);
3295
+ return II;
3296
+ }
3297
+
3257
3298
if (match (Arg, m_ZExtOrSExtOrSelf (m_Value (Vect)))) {
3258
3299
if (auto *FTy = dyn_cast<FixedVectorType>(Vect->getType ()))
3259
3300
if (FTy->getElementType () == Builder.getInt1Ty ()) {
@@ -3282,6 +3323,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
3282
3323
// ?ext(vector_reduce_add(<n x i1>))
3283
3324
Value *Arg = II->getArgOperand (0 );
3284
3325
Value *Vect;
3326
+
3327
+ if (Value *NewOp =
3328
+ simplifyReductionOperand (Arg, /* CanReorderLanes=*/ true )) {
3329
+ replaceUse (II->getOperandUse (0 ), NewOp);
3330
+ return II;
3331
+ }
3332
+
3285
3333
if (match (Arg, m_ZExtOrSExtOrSelf (m_Value (Vect)))) {
3286
3334
if (auto *FTy = dyn_cast<FixedVectorType>(Vect->getType ()))
3287
3335
if (FTy->getElementType () == Builder.getInt1Ty ()) {
@@ -3305,6 +3353,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
3305
3353
// zext(vector_reduce_and(<n x i1>))
3306
3354
Value *Arg = II->getArgOperand (0 );
3307
3355
Value *Vect;
3356
+
3357
+ if (Value *NewOp =
3358
+ simplifyReductionOperand (Arg, /* CanReorderLanes=*/ true )) {
3359
+ replaceUse (II->getOperandUse (0 ), NewOp);
3360
+ return II;
3361
+ }
3362
+
3308
3363
if (match (Arg, m_ZExtOrSExtOrSelf (m_Value (Vect)))) {
3309
3364
if (auto *FTy = dyn_cast<FixedVectorType>(Vect->getType ()))
3310
3365
if (FTy->getElementType () == Builder.getInt1Ty ()) {
@@ -3329,6 +3384,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
3329
3384
// ?ext(vector_reduce_{and,or}(<n x i1>))
3330
3385
Value *Arg = II->getArgOperand (0 );
3331
3386
Value *Vect;
3387
+
3388
+ if (Value *NewOp =
3389
+ simplifyReductionOperand (Arg, /* CanReorderLanes=*/ true )) {
3390
+ replaceUse (II->getOperandUse (0 ), NewOp);
3391
+ return II;
3392
+ }
3393
+
3332
3394
if (match (Arg, m_ZExtOrSExtOrSelf (m_Value (Vect)))) {
3333
3395
if (auto *FTy = dyn_cast<FixedVectorType>(Vect->getType ()))
3334
3396
if (FTy->getElementType () == Builder.getInt1Ty ()) {
@@ -3364,6 +3426,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
3364
3426
// zext(vector_reduce_{and,or}(<n x i1>))
3365
3427
Value *Arg = II->getArgOperand (0 );
3366
3428
Value *Vect;
3429
+
3430
+ if (Value *NewOp =
3431
+ simplifyReductionOperand (Arg, /* CanReorderLanes=*/ true )) {
3432
+ replaceUse (II->getOperandUse (0 ), NewOp);
3433
+ return II;
3434
+ }
3435
+
3367
3436
if (match (Arg, m_ZExtOrSExtOrSelf (m_Value (Vect)))) {
3368
3437
if (auto *FTy = dyn_cast<FixedVectorType>(Vect->getType ()))
3369
3438
if (FTy->getElementType () == Builder.getInt1Ty ()) {
@@ -3386,31 +3455,16 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
3386
3455
case Intrinsic::vector_reduce_fmin:
3387
3456
case Intrinsic::vector_reduce_fadd:
3388
3457
case Intrinsic::vector_reduce_fmul: {
3389
- bool CanBeReassociated = (IID != Intrinsic::vector_reduce_fadd &&
3390
- IID != Intrinsic::vector_reduce_fmul) ||
3391
- II->hasAllowReassoc ();
3458
+ bool CanReorderLanes = (IID != Intrinsic::vector_reduce_fadd &&
3459
+ IID != Intrinsic::vector_reduce_fmul) ||
3460
+ II->hasAllowReassoc ();
3392
3461
const unsigned ArgIdx = (IID == Intrinsic::vector_reduce_fadd ||
3393
3462
IID == Intrinsic::vector_reduce_fmul)
3394
3463
? 1
3395
3464
: 0 ;
3396
3465
Value *Arg = II->getArgOperand (ArgIdx);
3397
- Value *V;
3398
- ArrayRef<int > Mask;
3399
- if (!isa<FixedVectorType>(Arg->getType ()) || !CanBeReassociated ||
3400
- !match (Arg, m_Shuffle (m_Value (V), m_Undef (), m_Mask (Mask))) ||
3401
- !cast<ShuffleVectorInst>(Arg)->isSingleSource ())
3402
- break ;
3403
- int Sz = Mask.size ();
3404
- SmallBitVector UsedIndices (Sz);
3405
- for (int Idx : Mask) {
3406
- if (Idx == PoisonMaskElem || UsedIndices.test (Idx))
3407
- break ;
3408
- UsedIndices.set (Idx);
3409
- }
3410
- // Can remove shuffle iff just shuffled elements, no repeats, undefs, or
3411
- // other changes.
3412
- if (UsedIndices.all ()) {
3413
- replaceUse (II->getOperandUse (ArgIdx), V);
3466
+ if (Value *NewOp = simplifyReductionOperand (Arg, CanReorderLanes)) {
3467
+ replaceUse (II->getOperandUse (ArgIdx), NewOp);
3414
3468
return nullptr ;
3415
3469
}
3416
3470
break ;
0 commit comments