[InstCombine] add type constraint to intrinsic+shuffle fold

This check is in the related fold for binops,
but it was missed when the code was adapted
for intrinsics in 432c199e84. The new test
would crash when trying to create a new
intrinsic with mismatched types.
This commit is contained in:
Sanjay Patel 2022-05-04 12:57:34 -04:00
parent 7e6d318c50
commit 14f257620c
2 changed files with 21 additions and 2 deletions

View File

@ -1114,9 +1114,11 @@ foldShuffledIntrinsicOperands(IntrinsicInst *II,
// See if all arguments are shuffled with the same mask.
SmallVector<Value *, 4> NewArgs(II->arg_size());
NewArgs[0] = X;
Type *SrcTy = X->getType();
for (unsigned i = 1, e = II->arg_size(); i != e; ++i) {
if (!match(II->getArgOperand(i),
m_Shuffle(m_Value(X), m_Undef(), m_SpecificMask(Mask))))
m_Shuffle(m_Value(X), m_Undef(), m_SpecificMask(Mask))) ||
X->getType() != SrcTy)
return nullptr;
NewArgs[i] = X;
}
@ -1124,7 +1126,7 @@ foldShuffledIntrinsicOperands(IntrinsicInst *II,
// intrinsic (shuf X, M), (shuf Y, M), ... --> shuf (intrinsic X, Y, ...), M
Instruction *FPI = isa<FPMathOperator>(II) ? II : nullptr;
Value *NewIntrinsic =
Builder.CreateIntrinsic(II->getIntrinsicID(), X->getType(), NewArgs, FPI);
Builder.CreateIntrinsic(II->getIntrinsicID(), SrcTy, NewArgs, FPI);
return new ShuffleVectorInst(NewIntrinsic, Mask);
}

View File

@ -837,3 +837,20 @@ define <2 x i31> @fsh_unary_shuffle_ops_uses(<2 x i31> %x, <2 x i31> %y, <2 x i3
%r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %a, <2 x i31> %b, <2 x i31> %c)
ret <2 x i31> %r
}
; negative test - all source ops must have the same type
define <2 x i32> @fsh_unary_shuffle_ops_partial_widening(<3 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
; CHECK-LABEL: @fsh_unary_shuffle_ops_partial_widening(
; CHECK-NEXT: [[A:%.*]] = shufflevector <3 x i32> [[X:%.*]], <3 x i32> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: [[B:%.*]] = shufflevector <2 x i32> [[Y:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: [[C:%.*]] = shufflevector <2 x i32> [[Z:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[A]], <2 x i32> [[B]], <2 x i32> [[C]])
; CHECK-NEXT: ret <2 x i32> [[R]]
;
%a = shufflevector <3 x i32> %x, <3 x i32> poison, <2 x i32> <i32 1, i32 0>
%b = shufflevector <2 x i32> %y, <2 x i32> poison, <2 x i32> <i32 1, i32 0>
%c = shufflevector <2 x i32> %z, <2 x i32> poison, <2 x i32> <i32 1, i32 0>
%r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c)
ret <2 x i32> %r
}