@@ -2996,10 +2996,11 @@ bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
2996
2996
2997
2997
std::queue<Value *> InstWorklist;
2998
2998
Value *InitEEV = nullptr ;
2999
- Intrinsic::ID CommonOp = 0 ;
3000
2999
3001
- bool IsFirstCallInst = true ;
3002
- bool ShouldBeCallInst = true ;
3000
+ unsigned int CommonCallOp = 0 , CommonBinOp = 0 ;
3001
+
3002
+ bool IsFirstCallOrBinInst = true ;
3003
+ bool ShouldBeCallOrBinInst = true ;
3003
3004
3004
3005
SmallVector<Value *, 3 > PrevVecV (3 , nullptr );
3005
3006
int64_t ShuffleMaskHalf = -1 , ExpectedShuffleMaskHalf = 1 ;
@@ -3032,24 +3033,24 @@ bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
3032
3033
return false ;
3033
3034
3034
3035
if (auto *CallI = dyn_cast<CallInst>(CI)) {
3035
- if (!ShouldBeCallInst || !PrevVecV[2 ])
3036
+ if (!ShouldBeCallOrBinInst || !PrevVecV[2 ])
3036
3037
return false ;
3037
3038
3038
- if (!IsFirstCallInst &&
3039
+ if (!IsFirstCallOrBinInst &&
3039
3040
any_of (PrevVecV, [](Value *VecV) { return VecV == nullptr ; }))
3040
3041
return false ;
3041
3042
3042
- if (CallI != (IsFirstCallInst ? PrevVecV[2 ] : PrevVecV[0 ]))
3043
+ if (CallI != (IsFirstCallOrBinInst ? PrevVecV[2 ] : PrevVecV[0 ]))
3043
3044
return false ;
3044
- IsFirstCallInst = false ;
3045
+ IsFirstCallOrBinInst = false ;
3045
3046
3046
3047
auto *II = dyn_cast<IntrinsicInst>(CallI);
3047
3048
if (!II)
3048
3049
return false ;
3049
3050
3050
- if (!CommonOp )
3051
- CommonOp = II->getIntrinsicID ();
3052
- if (II->getIntrinsicID () != CommonOp )
3051
+ if (!CommonCallOp )
3052
+ CommonCallOp = II->getIntrinsicID ();
3053
+ if (II->getIntrinsicID () != CommonCallOp )
3053
3054
return false ;
3054
3055
3055
3056
switch (II->getIntrinsicID ()) {
@@ -3066,14 +3067,52 @@ bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
3066
3067
default :
3067
3068
return false ;
3068
3069
}
3069
- ShouldBeCallInst ^= 1 ;
3070
+ ShouldBeCallOrBinInst ^= 1 ;
3071
+
3072
+ if (!isa<ShuffleVectorInst>(PrevVecV[1 ]))
3073
+ std::swap (PrevVecV[0 ], PrevVecV[1 ]);
3074
+ InstWorklist.push (PrevVecV[1 ]);
3075
+ InstWorklist.push (PrevVecV[0 ]);
3076
+ } else if (auto *BinOp = dyn_cast<BinaryOperator>(CI)) {
3077
+ if (!ShouldBeCallOrBinInst || !PrevVecV[2 ])
3078
+ return false ;
3079
+
3080
+ if (!IsFirstCallOrBinInst &&
3081
+ any_of (PrevVecV, [](Value *VecV) { return VecV == nullptr ; }))
3082
+ return false ;
3083
+
3084
+ if (BinOp != (IsFirstCallOrBinInst ? PrevVecV[2 ] : PrevVecV[0 ]))
3085
+ return false ;
3086
+ IsFirstCallOrBinInst = false ;
3087
+
3088
+ if (!CommonBinOp)
3089
+ CommonBinOp = CI->getOpcode ();
3090
+ if (CI->getOpcode () != CommonBinOp)
3091
+ return false ;
3092
+
3093
+ switch (CI->getOpcode ()) {
3094
+ case BinaryOperator::Add:
3095
+ case BinaryOperator::Mul:
3096
+ case BinaryOperator::Or:
3097
+ case BinaryOperator::And:
3098
+ case BinaryOperator::Xor: {
3099
+ auto *Op0 = BinOp->getOperand (0 );
3100
+ auto *Op1 = BinOp->getOperand (1 );
3101
+ PrevVecV[0 ] = Op0;
3102
+ PrevVecV[1 ] = Op1;
3103
+ break ;
3104
+ }
3105
+ default :
3106
+ return false ;
3107
+ }
3108
+ ShouldBeCallOrBinInst ^= 1 ;
3070
3109
3071
3110
if (!isa<ShuffleVectorInst>(PrevVecV[1 ]))
3072
3111
std::swap (PrevVecV[0 ], PrevVecV[1 ]);
3073
3112
InstWorklist.push (PrevVecV[1 ]);
3074
3113
InstWorklist.push (PrevVecV[0 ]);
3075
3114
} else if (auto *SVInst = dyn_cast<ShuffleVectorInst>(CI)) {
3076
- if (ShouldBeCallInst ||
3115
+ if (ShouldBeCallOrBinInst ||
3077
3116
any_of (PrevVecV, [](Value *VecV) { return VecV == nullptr ; }))
3078
3117
return false ;
3079
3118
@@ -3100,13 +3139,13 @@ bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
3100
3139
ShuffleMaskHalf *= 2 ;
3101
3140
if (ExpectedShuffleMaskHalf == VecSize)
3102
3141
break ;
3103
- ShouldBeCallInst ^= 1 ;
3142
+ ShouldBeCallOrBinInst ^= 1 ;
3104
3143
} else {
3105
3144
return false ;
3106
3145
}
3107
3146
}
3108
3147
3109
- if (ShouldBeCallInst )
3148
+ if (ShouldBeCallOrBinInst )
3110
3149
return false ;
3111
3150
3112
3151
assert (VecSize != -1 && ExpectedShuffleMaskHalf == VecSize &&
@@ -3121,21 +3160,43 @@ bool VectorCombine::foldShuffleChainsToReduce(Instruction &I) {
3121
3160
assert (FinalVecVTy && " Expected non-null value for Vector Type" );
3122
3161
3123
3162
Intrinsic::ID ReducedOp = 0 ;
3124
- switch (CommonOp) {
3125
- case Intrinsic::umin:
3126
- ReducedOp = Intrinsic::vector_reduce_umin;
3127
- break ;
3128
- case Intrinsic::umax:
3129
- ReducedOp = Intrinsic::vector_reduce_umax;
3130
- break ;
3131
- case Intrinsic::smin:
3132
- ReducedOp = Intrinsic::vector_reduce_smin;
3133
- break ;
3134
- case Intrinsic::smax:
3135
- ReducedOp = Intrinsic::vector_reduce_smax;
3136
- break ;
3137
- default :
3138
- return false ;
3163
+ if (CommonCallOp) {
3164
+ switch (CommonCallOp) {
3165
+ case Intrinsic::umin:
3166
+ ReducedOp = Intrinsic::vector_reduce_umin;
3167
+ break ;
3168
+ case Intrinsic::umax:
3169
+ ReducedOp = Intrinsic::vector_reduce_umax;
3170
+ break ;
3171
+ case Intrinsic::smin:
3172
+ ReducedOp = Intrinsic::vector_reduce_smin;
3173
+ break ;
3174
+ case Intrinsic::smax:
3175
+ ReducedOp = Intrinsic::vector_reduce_smax;
3176
+ break ;
3177
+ default :
3178
+ return false ;
3179
+ }
3180
+ } else if (CommonBinOp) {
3181
+ switch (CommonBinOp) {
3182
+ case BinaryOperator::Add:
3183
+ ReducedOp = Intrinsic::vector_reduce_add;
3184
+ break ;
3185
+ case BinaryOperator::Mul:
3186
+ ReducedOp = Intrinsic::vector_reduce_mul;
3187
+ break ;
3188
+ case BinaryOperator::Or:
3189
+ ReducedOp = Intrinsic::vector_reduce_or;
3190
+ break ;
3191
+ case BinaryOperator::And:
3192
+ ReducedOp = Intrinsic::vector_reduce_and;
3193
+ break ;
3194
+ case BinaryOperator::Xor:
3195
+ ReducedOp = Intrinsic::vector_reduce_xor;
3196
+ break ;
3197
+ default :
3198
+ return false ;
3199
+ }
3139
3200
}
3140
3201
3141
3202
InstructionCost OrigCost = 0 ;
0 commit comments