Skip to content

Commit 0463ba3

Browse files
committed
Add the Swift equivalent of the llvm.assume intrinsic
rdar://44947459
1 parent dfed279 commit 0463ba3

File tree

8 files changed

+44
-2
lines changed

8 files changed

+44
-2
lines changed

include/swift/AST/Builtins.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ BUILTIN_UNARY_OPERATION(FNeg, "fneg", "n", FloatOrVector)
114114
// It has only an effect if the argument is a load or call.
115115
// TODO: consider printing a warning if it is not used on a load or call.
116116
BUILTIN_UNARY_OPERATION(AssumeNonNegative, "assumeNonNegative", "n", Integer)
117+
// It only works on i1.
118+
BUILTIN_UNARY_OPERATION(AssumeTrue, "assume", "", Integer)
117119

118120
#undef BUILTIN_UNARY_OPERATION
119121

lib/IRGen/GenBuiltin.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,13 @@ if (Builtin.ID == BuiltinValueKind::id) { \
393393
llvm::Value *v = IGF.Builder.CreateFSub(lhs, rhs);
394394
return out.add(v);
395395
}
396-
396+
if (Builtin.ID == BuiltinValueKind::AssumeTrue) {
397+
llvm::Value *v = args.claimNext();
398+
if (v->getType() == IGF.IGM.Int1Ty) {
399+
IGF.Builder.CreateIntrinsicCall(llvm::Intrinsic::ID::assume, v);
400+
}
401+
return;
402+
}
397403
if (Builtin.ID == BuiltinValueKind::AssumeNonNegative) {
398404
llvm::Value *v = args.claimNext();
399405
// Set a value range on the load instruction, which must be the argument of

lib/SIL/SILOwnershipVerifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,7 @@ CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, AssignCopyArrayFrontToBack)
11571157
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, AssignCopyArrayBackToFront)
11581158
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, AssignTakeArray)
11591159
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, AssumeNonNegative)
1160+
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, AssumeTrue)
11601161
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, AtomicLoad)
11611162
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, AtomicRMW)
11621163
CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, AtomicStore)

lib/SIL/ValueOwnershipKindClassifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ CONSTANT_OWNERSHIP_BUILTIN(Trivial, AShr)
401401
CONSTANT_OWNERSHIP_BUILTIN(Trivial, Add)
402402
CONSTANT_OWNERSHIP_BUILTIN(Trivial, And)
403403
CONSTANT_OWNERSHIP_BUILTIN(Trivial, AssumeNonNegative)
404+
CONSTANT_OWNERSHIP_BUILTIN(Trivial, AssumeTrue)
404405
CONSTANT_OWNERSHIP_BUILTIN(Trivial, BitCast)
405406
CONSTANT_OWNERSHIP_BUILTIN(Trivial, ExactSDiv)
406407
CONSTANT_OWNERSHIP_BUILTIN(Trivial, ExactUDiv)

stdlib/public/core/Builtin.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ public func _onFastPath() {
290290
Builtin.onFastPath()
291291
}
292292

293+
@_transparent
294+
public func _assume(_ condition: Bool) {
295+
_ = Builtin.assume_Int1(condition._value)
296+
}
297+
293298
//===--- Runtime shim wrappers --------------------------------------------===//
294299

295300
/// Returns `true` iff the class indicated by `theClass` uses native

test/IRGen/assume.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend -module-name=A -O -emit-ir %s | %FileCheck %s
2+
3+
// LLVM uses the assume intrinsic to strength reduce the division.
4+
5+
// CHECK-LABEL: define swiftcc i64 @"$s1A10testAssumeyS2iF"(i64)
6+
// CHECK: [[COND:%.*]] = icmp sgt i64 %0, -1
7+
// CHECK: tail call void @llvm.assume(i1 [[COND]])
8+
// CHECK: [[RES:%.*]] = lshr i64 %0, 6
9+
// CHECK: ret i64 [[RES]]
10+
11+
public func testAssume(_ i: Int) -> Int {
12+
let cond = i >= 0
13+
_assume(cond)
14+
return i / 64
15+
}

test/IRGen/builtins.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,12 @@ func isUnique(_ ref: inout Builtin.BridgeObject) -> Bool {
652652
return Builtin.isUnique(&ref)
653653
}
654654

655+
// CHECK-LABEL: define hidden{{.*}} @"$s8builtins10assumeTrueyyBi1_F"
656+
// CHECK: call void @llvm.assume(i1 %0)
657+
// CHECK: ret
658+
func assumeTrue(_ x: Builtin.Int1) {
659+
Builtin.assume_Int1(x)
660+
}
655661
// BridgeObject nonNull
656662
// CHECK-LABEL: define hidden {{.*}}i1 @"$s8builtins15isUnique_nativeyBi1_BbzF"(%swift.bridge** nocapture dereferenceable({{.*}})) {{.*}} {
657663
// CHECK-NEXT: entry:

test/SILGen/builtins.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,4 +812,10 @@ func once(control: Builtin.RawPointer) {
812812
func valueToBridgeObject(_ x: UInt) -> Builtin.BridgeObject {
813813
return Builtin.valueToBridgeObject(x)
814814
}
815-
815+
816+
// CHECK-LABEL: sil hidden @$s8builtins10assumeTrueyyBi1_F
817+
// CHECK: builtin "assume_Int1"({{.*}} : $Builtin.Int1)
818+
// CHECK: return
819+
func assumeTrue(_ x: Builtin.Int1) {
820+
Builtin.assume_Int1(x)
821+
}

0 commit comments

Comments
 (0)