[GlobalISel] Translate shufflevector

Reviewers: qcolombet, aditya_nandakumar, t.p.northover, javed.absar, ab, dsanders

Reviewed By: javed.absar

Subscribers: dberris, rovka, llvm-commits, kristof.beyls

Differential Revision: https://reviews.llvm.org/D30962

llvm-svn: 298347
This commit is contained in:
Volkan Keles 2017-03-21 08:44:13 +00:00
parent 9353e2dbfb
commit 75bdc7690e
6 changed files with 211 additions and 4 deletions

View File

@ -299,6 +299,8 @@ private:
bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder);
// Stubs to keep the compiler happy while we implement the rest of the
// translation.
bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) {
@ -337,9 +339,6 @@ private:
bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
return false;
}
bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder) {
return false;
}
/// @}

View File

@ -537,4 +537,11 @@ def G_EXTRACT_VECTOR_ELT : Instruction {
let hasSideEffects = 0;
}
// Generic shufflevector.
def G_SHUFFLE_VECTOR: Instruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
let hasSideEffects = 0;
}
// TODO: Add the other generic opcodes.

View File

@ -401,12 +401,15 @@ HANDLE_TARGET_OPCODE(G_INSERT_VECTOR_ELT)
/// Generic extractelement.
HANDLE_TARGET_OPCODE(G_EXTRACT_VECTOR_ELT)
/// Generic shufflevector.
HANDLE_TARGET_OPCODE(G_SHUFFLE_VECTOR)
// TODO: Add more generic opcodes as we move along.
/// Marker for the end of the generic opcode.
/// This is used to check if an opcode is in the range of the
/// generic opcodes.
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_EXTRACT_VECTOR_ELT)
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_SHUFFLE_VECTOR)
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific post-isel opcode values start here.

View File

@ -1005,6 +1005,16 @@ bool IRTranslator::translateExtractElement(const User &U,
return true;
}
bool IRTranslator::translateShuffleVector(const User &U,
MachineIRBuilder &MIRBuilder) {
MIRBuilder.buildInstr(TargetOpcode::G_SHUFFLE_VECTOR)
.addDef(getOrCreateVReg(U))
.addUse(getOrCreateVReg(*U.getOperand(0)))
.addUse(getOrCreateVReg(*U.getOperand(1)))
.addUse(getOrCreateVReg(*U.getOperand(2)));
return true;
}
bool IRTranslator::translatePHI(const User &U, MachineIRBuilder &MIRBuilder) {
const PHINode &PI = cast<PHINode>(U);
auto MIB = MIRBuilder.buildInstr(TargetOpcode::PHI);

View File

@ -1411,3 +1411,111 @@ define float @test_different_call_conv_target(float %x) {
%res = call ghccc float @different_call_conv_target(float %x)
ret float %res
}
define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_v2s32
; CHECK: [[ARG:%[0-9]+]](s32) = COPY %w0
; CHECK: [[UNDEF:%[0-9]+]](s32) = IMPLICIT_DEF
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[MASK:%[0-9]+]](<2 x s32>) = G_MERGE_VALUES [[C0]](s32), [[C0]](s32)
; CHECK: [[VEC:%[0-9]+]](<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: %d0 = COPY [[VEC]](<2 x s32>)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
ret <2 x i32> %res
}
define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_s32
; CHECK: [[ARG:%[0-9]+]](<2 x s32>) = COPY %d0
; CHECK: [[UNDEF:%[0-9]+]](<2 x s32>) = IMPLICIT_DEF
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[RES:%[0-9]+]](s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[C1]](s32)
; CHECK: %w0 = COPY [[RES]](s32)
%vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1>
%res = extractelement <1 x i32> %vec, i32 0
ret i32 %res
}
define <2 x i32> @test_shufflevector_v2s32_v2s32(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32
; CHECK: [[ARG:%[0-9]+]](<2 x s32>) = COPY %d0
; CHECK: [[UNDEF:%[0-9]+]](<2 x s32>) = IMPLICIT_DEF
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[MASK:%[0-9]+]](<2 x s32>) = G_MERGE_VALUES [[C1]](s32), [[C0]](s32)
; CHECK: [[VEC:%[0-9]+]](<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: %d0 = COPY [[VEC]](<2 x s32>)
%res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 1, i32 0>
ret <2 x i32> %res
}
define i32 @test_shufflevector_v2s32_v3s32(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
; CHECK: [[ARG:%[0-9]+]](<2 x s32>) = COPY %d0
; CHECK: [[UNDEF:%[0-9]+]](<2 x s32>) = IMPLICIT_DEF
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[MASK:%[0-9]+]](<3 x s32>) = G_MERGE_VALUES [[C1]](s32), [[C0]](s32), [[C1]](s32)
; CHECK: [[VEC:%[0-9]+]](<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<3 x s32>)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
%vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
%res = extractelement <3 x i32> %vec, i32 0
ret i32 %res
}
define <4 x i32> @test_shufflevector_v2s32_v4s32(<2 x i32> %arg1, <2 x i32> %arg2) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
; CHECK: [[ARG1:%[0-9]+]](<2 x s32>) = COPY %d0
; CHECK: [[ARG2:%[0-9]+]](<2 x s32>) = COPY %d1
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[C2:%[0-9]+]](s32) = G_CONSTANT i32 2
; CHECK: [[C3:%[0-9]+]](s32) = G_CONSTANT i32 3
; CHECK: [[MASK:%[0-9]+]](<4 x s32>) = G_MERGE_VALUES [[C0]](s32), [[C1]](s32), [[C2]](s32), [[C3]](s32)
; CHECK: [[VEC:%[0-9]+]](<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], [[MASK]](<4 x s32>)
; CHECK: %q0 = COPY [[VEC]](<4 x s32>)
%res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
ret <4 x i32> %res
}
define <2 x i32> @test_shufflevector_v4s32_v2s32(<4 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
; CHECK: [[ARG:%[0-9]+]](<4 x s32>) = COPY %q0
; CHECK: [[UNDEF:%[0-9]+]](<4 x s32>) = IMPLICIT_DEF
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[C3:%[0-9]+]](s32) = G_CONSTANT i32 3
; CHECK: [[MASK:%[0-9]+]](<2 x s32>) = G_MERGE_VALUES [[C1]](s32), [[C3]](s32)
; CHECK: [[VEC:%[0-9]+]](<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: %d0 = COPY [[VEC]](<2 x s32>)
%res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
ret <2 x i32> %res
}
define <16 x i8> @test_shufflevector_v8s8_v16s8(<8 x i8> %arg1, <8 x i8> %arg2) {
; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8
; CHECK: [[ARG1:%[0-9]+]](<8 x s8>) = COPY %d0
; CHECK: [[ARG2:%[0-9]+]](<8 x s8>) = COPY %d1
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[C8:%[0-9]+]](s32) = G_CONSTANT i32 8
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[C9:%[0-9]+]](s32) = G_CONSTANT i32 9
; CHECK: [[C2:%[0-9]+]](s32) = G_CONSTANT i32 2
; CHECK: [[C10:%[0-9]+]](s32) = G_CONSTANT i32 10
; CHECK: [[C3:%[0-9]+]](s32) = G_CONSTANT i32 3
; CHECK: [[C11:%[0-9]+]](s32) = G_CONSTANT i32 11
; CHECK: [[C4:%[0-9]+]](s32) = G_CONSTANT i32 4
; CHECK: [[C12:%[0-9]+]](s32) = G_CONSTANT i32 12
; CHECK: [[C5:%[0-9]+]](s32) = G_CONSTANT i32 5
; CHECK: [[C13:%[0-9]+]](s32) = G_CONSTANT i32 13
; CHECK: [[C6:%[0-9]+]](s32) = G_CONSTANT i32 6
; CHECK: [[C14:%[0-9]+]](s32) = G_CONSTANT i32 14
; CHECK: [[C7:%[0-9]+]](s32) = G_CONSTANT i32 7
; CHECK: [[C15:%[0-9]+]](s32) = G_CONSTANT i32 15
; CHECK: [[MASK:%[0-9]+]](<16 x s32>) = G_MERGE_VALUES [[C0]](s32), [[C8]](s32), [[C1]](s32), [[C9]](s32), [[C2]](s32), [[C10]](s32), [[C3]](s32), [[C11]](s32), [[C4]](s32), [[C12]](s32), [[C5]](s32), [[C13]](s32), [[C6]](s32), [[C14]](s32), [[C7]](s32), [[C15]](s32)
; CHECK: [[VEC:%[0-9]+]](<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], [[MASK]](<16 x s32>)
; CHECK: %q0 = COPY [[VEC]](<16 x s8>)
%res = shufflevector <8 x i8> %arg1, <8 x i8> %arg2, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
ret <16 x i8> %res
}

View File

@ -543,3 +543,83 @@ entry:
%r = notail call arm_aapcscc float @different_call_conv_target(float %x)
ret float %r
}
define i32 @test_shufflevector_s32_v2s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_v2s32
; CHECK: [[ARG:%[0-9]+]](s32) = COPY %r0
; CHECK: [[UNDEF:%[0-9]+]](s32) = IMPLICIT_DEF
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[MASK:%[0-9]+]](<2 x s32>) = G_MERGE_VALUES [[C0]](s32), [[C0]](s32)
; CHECK: [[VEC:%[0-9]+]](<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
%res = extractelement <2 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
; CHECK: [[ARG2:%[0-9]+]](s32) = COPY %r1
; CHECK: [[UNDEF:%[0-9]+]](<2 x s32>) = IMPLICIT_DEF
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[MASK:%[0-9]+]](<3 x s32>) = G_MERGE_VALUES [[C1]](s32), [[C0]](s32), [[C1]](s32)
; CHECK: [[V1:%[0-9]+]](<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK: [[V2:%[0-9]+]](<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK: [[VEC:%[0-9]+]](<3 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], [[MASK]](<3 x s32>)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
%v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1
%shuffle = shufflevector <2 x i32> %v2, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
%res = extractelement <3 x i32> %shuffle, i32 0
ret i32 %res
}
define i32 @test_shufflevector_v2s32_v4s32(i32 %arg1, i32 %arg2) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
; CHECK: [[ARG1:%[0-9]+]](s32) = COPY %r0
; CHECK: [[ARG2:%[0-9]+]](s32) = COPY %r1
; CHECK: [[UNDEF:%[0-9]+]](<2 x s32>) = IMPLICIT_DEF
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[MASK:%[0-9]+]](<4 x s32>) = G_MERGE_VALUES [[C0]](s32), [[C0]](s32), [[C0]](s32), [[C0]](s32)
; CHECK: [[V1:%[0-9]+]](<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK: [[V2:%[0-9]+]](<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK: [[VEC:%[0-9]+]](<4 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], [[MASK]](<4 x s32>)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<4 x s32>)
%v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1
%shuffle = shufflevector <2 x i32> %v2, <2 x i32> undef, <4 x i32> zeroinitializer
%res = extractelement <4 x i32> %shuffle, i32 0
ret i32 %res
}
define i32 @test_shufflevector_v4s32_v2s32(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) {
; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
; CHECK: [[ARG1:%[0-9]+]](s32) = COPY %r0
; CHECK: [[ARG2:%[0-9]+]](s32) = COPY %r1
; CHECK: [[ARG3:%[0-9]+]](s32) = COPY %r2
; CHECK: [[ARG4:%[0-9]+]](s32) = COPY %r3
; CHECK: [[UNDEF:%[0-9]+]](<4 x s32>) = IMPLICIT_DEF
; CHECK: [[C0:%[0-9]+]](s32) = G_CONSTANT i32 0
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
; CHECK: [[C2:%[0-9]+]](s32) = G_CONSTANT i32 2
; CHECK: [[C3:%[0-9]+]](s32) = G_CONSTANT i32 3
; CHECK: [[MASK:%[0-9]+]](<2 x s32>) = G_MERGE_VALUES [[C1]](s32), [[C3]](s32)
; CHECK: [[V1:%[0-9]+]](<4 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK: [[V2:%[0-9]+]](<4 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK: [[V3:%[0-9]+]](<4 x s32>) = G_INSERT_VECTOR_ELT [[V2]], [[ARG3]](s32), [[C2]](s32)
; CHECK: [[V4:%[0-9]+]](<4 x s32>) = G_INSERT_VECTOR_ELT [[V3]], [[ARG4]](s32), [[C3]](s32)
; CHECK: [[VEC:%[0-9]+]](<2 x s32>) = G_SHUFFLE_VECTOR [[V4]](<4 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
%v1 = insertelement <4 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <4 x i32> %v1, i32 %arg2, i32 1
%v3 = insertelement <4 x i32> %v2, i32 %arg3, i32 2
%v4 = insertelement <4 x i32> %v3, i32 %arg4, i32 3
%shuffle = shufflevector <4 x i32> %v4, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
%res = extractelement <2 x i32> %shuffle, i32 0
ret i32 %res
}