Skip to content

Commit 8b34d8b

Browse files
Allow Builtin.bitcast to do VecNxInt1 -> IntN (swiftlang#36252)
This is necessary to support the idiom for movmsk operations on x86.
1 parent a8beb7b commit 8b34d8b

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

lib/AST/Builtins.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,15 @@ static ValueDecl *getCastOperation(ASTContext &Context, Identifier Id,
577577
if (auto *BIT = CheckOutput->getAs<BuiltinIntegerType>())
578578
if (BIT->isFixedWidth() && BIT->getFixedWidth() == BFT->getBitWidth())
579579
break;
580+
581+
// Support VecNxInt1 -> IntN bitcast for SIMD comparison results.
582+
if (auto *Vec = CheckInput->getAs<BuiltinVectorType>())
583+
if (auto *BIT = CheckOutput->getAs<BuiltinIntegerType>())
584+
if (auto *Element = Vec->getElementType()->getAs<BuiltinIntegerType>())
585+
if (Element->getFixedWidth() == 1 &&
586+
BIT->isFixedWidth() &&
587+
BIT->getFixedWidth() == Vec->getNumElements())
588+
break;
580589

581590
// FIXME: Implement bitcast typechecking.
582591
llvm_unreachable("Bitcast not supported yet!");

test/IRGen/builtins.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ func cast_test(_ ptr: inout Builtin.RawPointer, i8: inout Builtin.Int8,
158158
d = Builtin.bitcast_Int64_FPIEEE64(i64) // CHECK: bitcast
159159
}
160160

161+
func vector_bitcast_test(_ src: Builtin.Vec16xInt8) -> Builtin.Int16 {
162+
// CHECK: vector_bitcast_test
163+
// This is the idiom for pmovmskb on x86 targets:
164+
let zero: Builtin.Vec16xInt8 = Builtin.zeroInitializer()
165+
let mask = Builtin.cmp_slt_Vec16xInt8(src, zero)
166+
return Builtin.bitcast_Vec16xInt1_Int16(mask) // CHECK: bitcast
167+
}
168+
161169
func intrinsic_test(_ i32: inout Builtin.Int32, i16: inout Builtin.Int16,
162170
_ v8i16: Builtin.Vec8xInt16) {
163171
// CHECK: intrinsic_test

0 commit comments

Comments
 (0)