Skip to content

Commit d003bf4

Browse files
gottesmmnvzqz
authored andcommitted
[irgenprepare] Teach IRGenPrepare how to transform polymorphic builtins into traps in IRGenPrepare.
1 parent 8c324df commit d003bf4

File tree

2 files changed

+54
-17
lines changed

2 files changed

+54
-17
lines changed

lib/SILOptimizer/Mandatory/IRGenPrepare.cpp

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
///
1919
/// 1. We remove calls to Builtin.poundAssert() and Builtin.staticReport(),
2020
/// which are not needed post SIL.
21+
/// 2. We transform polymorphic builtins in transparent functions into traps.
2122
///
2223
//===----------------------------------------------------------------------===//
2324

@@ -42,28 +43,47 @@ static bool cleanFunction(SILFunction &fn) {
4243
SILInstruction *inst = &*i;
4344
++i;
4445

45-
// Remove calls to Builtin.poundAssert() and Builtin.staticReport().
4646
auto *bi = dyn_cast<BuiltinInst>(inst);
4747
if (!bi) {
4848
continue;
4949
}
5050

51-
switch (bi->getBuiltinInfo().ID) {
52-
case BuiltinValueKind::CondFailMessage: {
53-
SILBuilderWithScope Builder(bi);
54-
Builder.createCondFail(bi->getLoc(), bi->getOperand(0),
55-
"unknown program error");
56-
LLVM_FALLTHROUGH;
57-
}
58-
case BuiltinValueKind::PoundAssert:
59-
case BuiltinValueKind::StaticReport:
60-
// The call to the builtin should get removed before we reach
61-
// IRGen.
62-
recursivelyDeleteTriviallyDeadInstructions(bi, /* Force */ true);
63-
madeChange = true;
64-
break;
65-
default:
66-
break;
51+
auto kind = bi->getBuiltinKind();
52+
if (!kind) {
53+
continue;
54+
}
55+
56+
// Transform polymorphic builtins into int_trap.
57+
if (isPolymorphicBuiltin(*kind)) {
58+
assert(bi->getFunction()->isTransparent() == IsTransparent &&
59+
"Should only see these in transparent functions. If these were "
60+
"mandatory inlined into a caller, we should either have emitted "
61+
"a call to the static overload or emitted a diagnostic");
62+
// Replace all uses with undef since we are going to trap. Any such uses
63+
// are now unreachable along a path.
64+
bi->replaceAllUsesWithUndef();
65+
SILBuilderWithScope(bi).createBuiltinTrap(bi->getLoc());
66+
bi->eraseFromParent();
67+
madeChange = true;
68+
continue;
69+
}
70+
71+
switch (*kind) {
72+
case BuiltinValueKind::CondFailMessage: {
73+
SILBuilderWithScope Builder(bi);
74+
Builder.createCondFail(bi->getLoc(), bi->getOperand(0),
75+
"unknown program error");
76+
LLVM_FALLTHROUGH;
77+
}
78+
case BuiltinValueKind::PoundAssert:
79+
case BuiltinValueKind::StaticReport:
80+
// The call to the builtin should get removed before we reach
81+
// IRGen.
82+
recursivelyDeleteTriviallyDeadInstructions(bi, /* Force */ true);
83+
madeChange = true;
84+
break;
85+
default:
86+
break;
6787
}
6888
}
6989
}

test/SILOptimizer/irgenprepare.sil

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-sil-opt -module-name Swift -irgen-prepare %s -enable-sil-verify-all | %FileCheck %s
2+
3+
sil_stage raw
4+
5+
import Builtin
6+
7+
// CHECK-LABEL: sil [transparent] [canonical] @polymorphic_builtin_to_trap : $@convention(thin) <T> (@in T, @in T) -> @out T {
8+
// CHECK-NOT: builtin "generic_add"
9+
// CHECK: builtin "int_trap"
10+
// CHECK-NOT: builtin "generic_add"
11+
// CHECK: } // end sil function 'polymorphic_builtin_to_trap'
12+
sil [transparent] [canonical] @polymorphic_builtin_to_trap : $@convention(thin) <T> (@in T, @in T) -> @out T {
13+
bb0(%0 : $*T, %1 : $*T, %2 : $*T):
14+
%3 = builtin "generic_add"<T>(%0 : $*T, %1 : $*T, %2 : $*T): $()
15+
%9999 = tuple()
16+
return %9999 : $()
17+
}

0 commit comments

Comments
 (0)