diff options
| author | Volkan Keles <vkeles@apple.com> | 2017-03-21 08:44:13 +0000 |
|---|---|---|
| committer | Volkan Keles <vkeles@apple.com> | 2017-03-21 08:44:13 +0000 |
| commit | 75bdc7690e619aea7748d99e1057ffc0ab904936 (patch) | |
| tree | 9bcf5830876085805e2ca6deb773d286834027f4 /llvm | |
| parent | 9353e2dbfb2b310a6f7874dfd03aa51a32a9be03 (diff) | |
| download | bcm5719-llvm-75bdc7690e619aea7748d99e1057ffc0ab904936.tar.gz bcm5719-llvm-75bdc7690e619aea7748d99e1057ffc0ab904936.zip | |
[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
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h | 5 | ||||
| -rw-r--r-- | llvm/include/llvm/Target/GenericOpcodes.td | 7 | ||||
| -rw-r--r-- | llvm/include/llvm/Target/TargetOpcodes.def | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 10 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll | 108 | ||||
| -rw-r--r-- | llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll | 80 |
6 files changed, 211 insertions, 4 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 83141f68431..31ffdc0e2e7 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -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; - } /// @} diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index 64f4ec8dd44..de3796cd4ee 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -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. diff --git a/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def index e3ae2fae83e..96db6e0a976 100644 --- a/llvm/include/llvm/Target/TargetOpcodes.def +++ b/llvm/include/llvm/Target/TargetOpcodes.def @@ -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. diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 0f97469d453..b6e6fbd03d0 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -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); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index db85d41c37f..a4352efc64a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -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 +} diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll index d285bf3a3bb..c73e386e6bf 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll @@ -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 +} |

