Skip to content

Commit 511b50e

Browse files
Implement shufflevector builtin. (swiftlang#36650)
This isn't _terribly_ useful as-is, because the only constant mask you can get at from Swift at present is the zeroinitializer, but even that is quite useful for optimizing the repeating: intializer on SIMD. At some future point we should wire up generating constant masks for the .even, .odd, .high and .low properties (and also eventually make shufflevector take non-constant masks in LLVM). But this is enough to be useful, so let's get it in.
1 parent aedd3f2 commit 511b50e

File tree

7 files changed

+52
-2
lines changed

7 files changed

+52
-2
lines changed

include/swift/AST/Builtins.def

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,9 @@ BUILTIN_MISC_OPERATION(ExtractElement, "extractelement", "n", Special)
626626
/// InsertElement has type (Vector<N, T>, T, Int32) -> Vector<N, T>.
627627
BUILTIN_MISC_OPERATION(InsertElement, "insertelement", "n", Special)
628628

629+
// Shufflevector has type (VecN<T>, VecN<T>, VecM<Int32>) -> VecM<T>
630+
BUILTIN_MISC_OPERATION(ShuffleVector, "shufflevector", "n", Special)
631+
629632
/// StaticReport has type (Builtin.Int1, Builtin.Int1, Builtin.RawPointer) -> ()
630633
BUILTIN_MISC_OPERATION(StaticReport, "staticReport", "", Special)
631634

@@ -655,8 +658,6 @@ BUILTIN_MISC_OPERATION(UToUCheckedTrunc, "u_to_u_checked_trunc", "n", Special)
655658
/// IntToFPWithOverflow has type (Integer) -> Float
656659
BUILTIN_MISC_OPERATION(IntToFPWithOverflow, "itofp_with_overflow", "n", Special)
657660

658-
// FIXME: shufflevector
659-
660661
/// zeroInitializer has type <T> () -> T
661662
BUILTIN_MISC_OPERATION(ZeroInitializer, "zeroInitializer", "n", Special)
662663

lib/AST/Builtins.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,27 @@ static ValueDecl *getInsertElementOperation(ASTContext &Context, Identifier Id,
16491649
return getBuiltinFunction(Id, ArgElts, VecTy);
16501650
}
16511651

1652+
static ValueDecl *getShuffleVectorOperation(ASTContext &Context, Identifier Id,
1653+
Type FirstTy, Type SecondTy) {
1654+
// (Vector<N, T>, Vector<N, T>, Vector<M, Int32) -> Vector<M, T>
1655+
auto VecTy = FirstTy->getAs<BuiltinVectorType>();
1656+
if (!VecTy)
1657+
return nullptr;
1658+
auto ElementTy = VecTy->getElementType();
1659+
1660+
auto IndexTy = SecondTy->getAs<BuiltinVectorType>();
1661+
if (!IndexTy)
1662+
return nullptr;
1663+
auto IdxElTy = IndexTy->getElementType()->getAs<BuiltinIntegerType>();
1664+
if (!IdxElTy || !IdxElTy->isFixedWidth() || IdxElTy->getFixedWidth() != 32)
1665+
return nullptr;
1666+
1667+
Type ArgElts[] = { VecTy, VecTy, IndexTy };
1668+
Type ResultTy = BuiltinVectorType::get(Context, ElementTy,
1669+
IndexTy->getNumElements());
1670+
return getBuiltinFunction(Id, ArgElts, ResultTy);
1671+
}
1672+
16521673
static ValueDecl *getStaticReportOperation(ASTContext &Context, Identifier Id) {
16531674
auto BoolTy = BuiltinIntegerType::get(1, Context);
16541675
auto MessageTy = Context.TheRawPointerType;
@@ -2594,6 +2615,10 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
25942615
case BuiltinValueKind::InsertElement:
25952616
if (Types.size() != 3) return nullptr;
25962617
return getInsertElementOperation(Context, Id, Types[0], Types[1], Types[2]);
2618+
2619+
case BuiltinValueKind::ShuffleVector:
2620+
if (Types.size() != 2) return nullptr;
2621+
return getShuffleVectorOperation(Context, Id, Types[0], Types[1]);
25972622

25982623
case BuiltinValueKind::StaticReport:
25992624
if (!Types.empty()) return nullptr;

lib/IRGen/GenBuiltin.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,16 @@ if (Builtin.ID == BuiltinValueKind::id) { \
835835
out.add(IGF.Builder.CreateInsertElement(vector, newValue, index));
836836
return;
837837
}
838+
839+
if (Builtin.ID == BuiltinValueKind::ShuffleVector) {
840+
using namespace llvm;
841+
842+
auto dict0 = args.claimNext();
843+
auto dict1 = args.claimNext();
844+
auto index = args.claimNext();
845+
out.add(IGF.Builder.CreateShuffleVector(dict0, dict1, index));
846+
return;
847+
}
838848

839849
if (Builtin.ID == BuiltinValueKind::SToSCheckedTrunc ||
840850
Builtin.ID == BuiltinValueKind::UToUCheckedTrunc ||

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,7 @@ BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, SToUCheckedTrunc)
709709
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, Expect)
710710
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, Shl)
711711
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, GenericShl)
712+
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, ShuffleVector)
712713
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, Sizeof)
713714
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, StaticReport)
714715
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, Strideof)

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ UNOWNED_OR_NONE_DEPENDING_ON_RESULT(CmpXChg)
569569
UNOWNED_OR_NONE_DEPENDING_ON_RESULT(AtomicLoad)
570570
UNOWNED_OR_NONE_DEPENDING_ON_RESULT(ExtractElement)
571571
UNOWNED_OR_NONE_DEPENDING_ON_RESULT(InsertElement)
572+
UNOWNED_OR_NONE_DEPENDING_ON_RESULT(ShuffleVector)
572573
UNOWNED_OR_NONE_DEPENDING_ON_RESULT(ZeroInitializer)
573574
#undef UNOWNED_OR_NONE_DEPENDING_ON_RESULT
574575

lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ static bool isBarrier(SILInstruction *inst) {
120120
case BuiltinValueKind::OnFastPath:
121121
case BuiltinValueKind::ExtractElement:
122122
case BuiltinValueKind::InsertElement:
123+
case BuiltinValueKind::ShuffleVector:
123124
case BuiltinValueKind::StaticReport:
124125
case BuiltinValueKind::AssertConf:
125126
case BuiltinValueKind::StringObjectOr:

test/IRGen/builtins.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,17 @@ func vector_bitcast_test_ii(_ src: Builtin.Int16) -> Builtin.Vec16xInt8 {
172172
return Builtin.sext_Vec16xInt1_Vec16xInt8(v16x1) // CHECK: sext
173173
}
174174

175+
func shufflevector_test(_ src: Builtin.FPIEEE32) -> Builtin.Vec4xFPIEEE32 {
176+
// CHECK: insertelement <4 x float> zeroinitializer
177+
// CHECK: shufflevector <4 x float>
178+
let vec = Builtin.insertelement_Vec4xFPIEEE32_FPIEEE32_Int32(
179+
Builtin.zeroInitializer(), src, Builtin.zeroInitializer()
180+
)
181+
return Builtin.shufflevector_Vec4xFPIEEE32_Vec4xInt32(
182+
vec, vec, Builtin.zeroInitializer()
183+
)
184+
}
185+
175186
func intrinsic_test(_ i32: inout Builtin.Int32, i16: inout Builtin.Int16,
176187
_ v8i16: Builtin.Vec8xInt16) {
177188
// CHECK: intrinsic_test

0 commit comments

Comments
 (0)