Skip to content

Commit

Permalink
[GlobalISel] Import extract/insert subvector
Browse files Browse the repository at this point in the history
Tests are limited to fixed-length vectors.

Test: AArch64/GlobalISel/irtranslator-subvector.ll

Reference:

https://llvm.org/docs/LangRef.html#llvm-vector-extract-intrinsic
https://llvm.org/docs/LangRef.html#llvm-vector-insert-intrinsic
  • Loading branch information
tschuett committed Sep 28, 2024
1 parent 2a005bf commit f2202d0
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
14 changes: 14 additions & 0 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2588,6 +2588,20 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
getOrCreateVReg(*CI.getOperand(0)),
getOrCreateVReg(*CI.getOperand(1)));
return true;
case Intrinsic::vector_extract: {
ConstantInt *Index = cast<ConstantInt>(CI.getOperand(1));
MIRBuilder.buildExtractSubvector(getOrCreateVReg(CI),
getOrCreateVReg(*CI.getOperand(0)),
Index->getZExtValue());
return true;
}
case Intrinsic::vector_insert: {
ConstantInt *Index = cast<ConstantInt>(CI.getOperand(2));
MIRBuilder.buildInsertSubvector(
getOrCreateVReg(CI), getOrCreateVReg(*CI.getOperand(0)),
getOrCreateVReg(*CI.getOperand(1)), Index->getZExtValue());
return true;
}
case Intrinsic::prefetch: {
Value *Addr = CI.getOperand(0);
unsigned RW = cast<ConstantInt>(CI.getOperand(1))->getZExtValue();
Expand Down
78 changes: 78 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-subvector.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -O0 -mtriple=aarch64-linux-gnu -global-isel -stop-after=irtranslator %s -o - | FileCheck %s

define i32 @extract_v4i32_vector_insert_const(<4 x i32> %a, <2 x i32> %b, i32 %c) {
; CHECK-LABEL: name: extract_v4i32_vector_insert_const
; CHECK: bb.1.entry:
; CHECK-NEXT: liveins: $d1, $q0, $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
; CHECK-NEXT: [[INSERT_SUBVECTOR:%[0-9]+]]:_(<4 x s32>) = G_INSERT_SUBVECTOR [[COPY]], [[COPY1]](<2 x s32>), 0
; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[INSERT_SUBVECTOR]](<4 x s32>), [[C]](s64)
; CHECK-NEXT: $w0 = COPY [[EVEC]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%vector = call <4 x i32> @llvm.vector.insert.v4i32.v2i32(<4 x i32> %a, <2 x i32> %b, i64 0)
%d = extractelement <4 x i32> %vector, i32 1
ret i32 %d
}

define i32 @extract_v4i32_vector_insert(<4 x i32> %a, <2 x i32> %b, i32 %c) {
; CHECK-LABEL: name: extract_v4i32_vector_insert
; CHECK: bb.1.entry:
; CHECK-NEXT: liveins: $d1, $q0, $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[INSERT_SUBVECTOR:%[0-9]+]]:_(<4 x s32>) = G_INSERT_SUBVECTOR [[COPY]], [[COPY1]](<2 x s32>), 0
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY2]](s32)
; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[INSERT_SUBVECTOR]](<4 x s32>), [[ZEXT]](s64)
; CHECK-NEXT: $w0 = COPY [[EVEC]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%vector = call <4 x i32> @llvm.vector.insert.v4i32.v2i32(<4 x i32> %a, <2 x i32> %b, i64 0)
%d = extractelement <4 x i32> %vector, i32 %c
ret i32 %d
}

define i32 @extract_v4i32_vector_extract(<4 x i32> %a, <2 x i32> %b, i32 %c) {
; CHECK-LABEL: name: extract_v4i32_vector_extract
; CHECK: bb.1.entry:
; CHECK-NEXT: liveins: $d1, $q0, $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[EXTRACT_SUBVECTOR:%[0-9]+]]:_(<4 x s32>) = G_EXTRACT_SUBVECTOR [[COPY]](<4 x s32>), 0
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY2]](s32)
; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[EXTRACT_SUBVECTOR]](<4 x s32>), [[ZEXT]](s64)
; CHECK-NEXT: $w0 = COPY [[EVEC]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%vector = call <4 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %a, i64 0)
%d = extractelement <4 x i32> %vector, i32 %c
ret i32 %d
}

define i32 @extract_v4i32_vector_extract_const(<4 x i32> %a, <2 x i32> %b, i32 %c) {
; CHECK-LABEL: name: extract_v4i32_vector_extract_const
; CHECK: bb.1.entry:
; CHECK-NEXT: liveins: $d1, $q0, $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
; CHECK-NEXT: [[EXTRACT_SUBVECTOR:%[0-9]+]]:_(<4 x s32>) = G_EXTRACT_SUBVECTOR [[COPY]](<4 x s32>), 0
; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[EXTRACT_SUBVECTOR]](<4 x s32>), [[C]](s64)
; CHECK-NEXT: $w0 = COPY [[EVEC]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%vector = call <4 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %a, i64 0)
%d = extractelement <4 x i32> %vector, i32 0
ret i32 %d
}

0 comments on commit f2202d0

Please sign in to comment.