}
const Constant *Mask = MaskOp.getShuffleMask();
+ auto *MaskVT = dyn_cast<VectorType>(Mask->getType());
+ if (!MaskVT || !MaskVT->getElementType()->isIntegerTy(32)) {
+ report("Invalid shufflemask constant type", MI);
+ break;
+ }
+
if (!Mask->getAggregateElement(0u)) {
report("Invalid shufflemask constant type", MI);
break;
}
- // TODO: Verify element numbers consistent
+ LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+ LLT Src0Ty = MRI->getType(MI->getOperand(1).getReg());
+ LLT Src1Ty = MRI->getType(MI->getOperand(2).getReg());
+
+ if (Src0Ty != Src1Ty)
+ report("Source operands must be the same type", MI);
+
+ if (Src0Ty.getScalarType() != DstTy.getScalarType())
+ report("G_SHUFFLE_VECTOR cannot change element type", MI);
+
+ // Don't check that all operands are vector because scalars are used in
+ // place of 1 element vectors.
+ int SrcNumElts = Src0Ty.isVector() ? Src0Ty.getNumElements() : 1;
+ int DstNumElts = DstTy.isVector() ? DstTy.getNumElements() : 1;
+
+ SmallVector<int, 32> MaskIdxes;
+ ShuffleVectorInst::getShuffleMask(Mask, MaskIdxes);
+
+ if (static_cast<int>(MaskIdxes.size()) != DstNumElts)
+ report("Wrong result type for shufflemask", MI);
+
+ for (int Idx : MaskIdxes) {
+ if (Idx < 0)
+ continue;
+
+ if (Idx >= 2 * SrcNumElts)
+ report("Out of bounds shuffle index", MI);
+ }
+
break;
}
default:
ret i32 %res
}
+define i32 @test_shufflevector_s32_s32_s32(i32 %arg) {
+; CHECK-LABEL: name: test_shufflevector_s32_s32_s32
+; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0
+; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+; CHECK: [[VEC:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0)
+ %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
+ %shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <1 x i32> zeroinitializer
+ %res = extractelement <1 x i32> %shuffle, i32 0
+ ret i32 %res
+}
+
define i32 @test_shufflevector_v2s32_v3s32(i32 %arg1, i32 %arg2) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $r0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
- %1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(0)
- $d0 = COPY %1(<2 x s32>)
- RET_ReallyLR implicit $d0
+ %1:_(s32) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(0)
+ $w0 = COPY %1
+ RET_ReallyLR implicit $w0
...
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
- %1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1)
- $d0 = COPY %1(<2 x s32>)
- RET_ReallyLR implicit $d0
+ %1:_(s32) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1)
+ $w0 = COPY %1
+ RET_ReallyLR implicit $w0
...
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
- %1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(undef)
- $d0 = COPY %1(<2 x s32>)
- RET_ReallyLR implicit $d0
+ %1:_(s32) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(undef)
+ $w0 = COPY %1
+ RET_ReallyLR implicit $w0
...
-# RUN: not llc -o - -march=arm64 -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
+# RUN: not llc -o - -march=arm64 -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
# REQUIRES: aarch64-registered-target
---
name: g_shuffle_vector
; CHECK: Bad machine code: Incorrect mask operand type for G_SHUFFLE_VECTOR
%9:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, i32 0
+ ; CHECK: Bad machine code: Wrong result type for shufflemask
+ %10:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0, 2)
+
+ ; CHECK: Bad machine code: Wrong result type for shufflemask
+ %11:_(<2 x s32>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0, 2, 1, 1)
+
+ ; CHECK: Bad machine code: G_SHUFFLE_VECTOR cannot change element type
+ %12:_(<4 x s16>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0, 2, 1, 1)
+
+ ; CHECK: Bad machine code: Source operands must be the same type
+ %13:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %2, shufflemask(0, 2, 1, 1)
+
+ ; CHECK: Bad machine code: Out of bounds shuffle index
+ %14:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0, 2, 1, 4)
+
+ ; CHECK: Bad machine code: Out of bounds shuffle index
+ %15:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0, 2, 1, 5)
+
+ %19:_(s16) = G_CONSTANT i16 0
+
+ ; CHECK: Bad machine code: Source operands must be the same type
+ %20:_(<2 x s32>) = G_SHUFFLE_VECTOR %3, %19, shufflemask(1, 0)
+
+ ; CHECK: Bad machine code: G_SHUFFLE_VECTOR cannot change element type
+ %21:_(s16) = G_SHUFFLE_VECTOR %3, %4, shufflemask(0)
+
...