Skip to content

Commit 5c3ec6b

Browse files
Merge pull request #73424 from nate-chandler/cherrypick/release/6.0/rdar127452206
6.0: [SILCombine] Handle indirect error in apply(convert_function).
2 parents aa6fcbc + 521b325 commit 5c3ec6b

File tree

6 files changed

+96
-2
lines changed

6 files changed

+96
-2
lines changed

include/swift/SIL/SILFunctionConventions.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,24 @@ class SILFunctionConventions {
242242
return 0;
243243
}
244244

245+
std::optional<SILResultInfo> getIndirectErrorResult() const {
246+
if (!silConv.loweredAddresses)
247+
return std::nullopt;
248+
auto info = funcTy->getOptionalErrorResult();
249+
if (!info)
250+
return std::nullopt;
251+
if (info->getConvention() != ResultConvention::Indirect)
252+
return std::nullopt;
253+
return info;
254+
}
255+
256+
SILType getIndirectErrorResultType(TypeExpansionContext context) const {
257+
auto result = getIndirectErrorResult();
258+
if (!result)
259+
return SILType();
260+
return getSILType(*result, context);
261+
}
262+
245263
bool isArgumentIndexOfIndirectErrorResult(unsigned idx) {
246264
unsigned indirectResults = getNumIndirectSILResults();
247265
return idx >= indirectResults &&

include/swift/SIL/Test.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ class FunctionTest final {
173173
template <typename Analysis, typename Transform = SILFunctionTransform>
174174
Analysis *getAnalysis();
175175

176+
SILFunctionTransform *getPass();
177+
176178
SwiftPassInvocation *getSwiftPassInvocation();
177179

178180
//===----------------------------------------------------------------------===//
@@ -302,6 +304,8 @@ template <typename Analysis, typename Transform>
302304
Analysis *FunctionTest::getAnalysis() {
303305
return impl::getAnalysisFromTransform<Analysis, Transform>(pass);
304306
}
307+
308+
inline SILFunctionTransform *FunctionTest::getPass() { return pass; }
305309
} // namespace test
306310
} // namespace swift
307311

lib/SILOptimizer/SILCombiner/SILCombine.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/SIL/DebugUtils.h"
2626
#include "swift/SIL/SILBuilder.h"
2727
#include "swift/SIL/SILVisitor.h"
28+
#include "swift/SIL/Test.h"
2829
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
2930
#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
3031
#include "swift/SILOptimizer/Analysis/NonLocalAccessBlockAnalysis.h"
@@ -498,6 +499,29 @@ bool SILCombiner::doOneIteration(SILFunction &F, unsigned Iteration) {
498499
return MadeChange;
499500
}
500501

502+
namespace swift::test {
503+
// Arguments:
504+
// - instruction: the instruction to be canonicalized
505+
// Dumps:
506+
// - the function after the canonicalization is attempted
507+
static FunctionTest SILCombineCanonicalizeInstruction(
508+
"sil_combine_instruction", [](auto &function, auto &arguments, auto &test) {
509+
SILCombiner combiner(test.getPass(), false, false);
510+
auto inst = arguments.takeInstruction();
511+
combiner.Builder.setInsertionPoint(inst);
512+
auto *result = combiner.visit(inst);
513+
if (result) {
514+
combiner.Worklist.replaceInstructionWithInstruction(inst, result
515+
#ifndef NDEBUG
516+
,
517+
""
518+
#endif
519+
);
520+
}
521+
function.dump();
522+
});
523+
} // end namespace swift::test
524+
501525
bool SILCombiner::runOnFunction(SILFunction &F) {
502526
clear();
503527

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,11 @@ class SILCombiner :
7272
/// lifetimes in OSSA.
7373
NonLocalAccessBlockAnalysis *NLABA;
7474

75+
public:
7576
/// Worklist containing all of the instructions primed for simplification.
7677
SmallSILInstructionWorklist<256> Worklist;
7778

79+
private:
7880
/// Utility for dead code removal.
7981
InstructionDeleter deleter;
8082

@@ -102,10 +104,12 @@ class SILCombiner :
102104
// The tracking list is used by `Builder` for newly added
103105
// instructions, which we will periodically move to our worklist.
104106
llvm::SmallVector<SILInstruction *, 64> TrackingList;
105-
107+
108+
public:
106109
/// Builder used to insert instructions.
107110
SILBuilder Builder;
108111

112+
private:
109113
SILOptFunctionBuilder FuncBuilder;
110114

111115
/// Cast optimizer

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI,
157157
auto context = AI.getFunction()->getTypeExpansionContext();
158158
auto oldOpRetTypes = substConventions.getIndirectSILResultTypes(context);
159159
auto newOpRetTypes = convertConventions.getIndirectSILResultTypes(context);
160+
auto oldIndirectErrorResultType =
161+
substConventions.getIndirectErrorResultType(context);
162+
auto newIndirectErrorResultType =
163+
convertConventions.getIndirectErrorResultType(context);
160164
auto oldOpParamTypes = substConventions.getParameterSILTypes(context);
161165
auto newOpParamTypes = convertConventions.getParameterSILTypes(context);
162166

@@ -186,7 +190,13 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI,
186190
++OpI, ++newRetI, ++oldRetI) {
187191
convertOp(Ops[OpI], *oldRetI, *newRetI);
188192
}
189-
193+
194+
if (oldIndirectErrorResultType) {
195+
assert(newIndirectErrorResultType);
196+
convertOp(Ops[OpI], oldIndirectErrorResultType, newIndirectErrorResultType);
197+
++OpI;
198+
}
199+
190200
auto newParamI = newOpParamTypes.begin();
191201
auto oldParamI = oldOpParamTypes.begin();
192202
for (auto e = newOpParamTypes.end(); newParamI != e;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -test-runner | %FileCheck %s
2+
3+
import Builtin
4+
5+
struct Input {}
6+
struct Output {}
7+
enum Nunca {}
8+
9+
sil @rdar127452206_callee : $@convention(thin) @Sendable @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> (@out τ_0_2, @error_indirect τ_0_1) for <Input, Nunca, Output>
10+
11+
// CHECK-LABEL: sil @rdar127452206 : {{.*}} {
12+
// CHECK: bb0([[INPUT:%[^,]+]] :
13+
// CHECK: [[OUTPUT:%[^,]+]] = alloc_stack $Output
14+
// CHECK: [[NUNCA:%[^,]+]] = alloc_stack $Nunca
15+
// CHECK: [[OUTPUT_AS_OUTPUT:%[^,]+]] = unchecked_addr_cast [[OUTPUT]]
16+
// CHECK: [[NUNCA_AS_NUNCA:%[^,]+]] = unchecked_addr_cast [[NUNCA]]
17+
// CHECK: [[INPUT_AS_INPUT:%[^,]+]] = unchecked_addr_cast [[INPUT]]
18+
// CHECK: apply [nothrow] {{%[^,]+}}([[OUTPUT_AS_OUTPUT]], [[NUNCA_AS_NUNCA]], [[INPUT_AS_INPUT]])
19+
// CHECK-LABEL: } // end sil function 'rdar127452206'
20+
sil @rdar127452206 : $@convention(thin) (@in Input) -> () {
21+
entry(%input : $*Input):
22+
%output = alloc_stack $Output
23+
%nunca = alloc_stack $Nunca
24+
%callee = function_ref @rdar127452206_callee : $@convention(thin) @Sendable @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> (@out τ_0_2, @error_indirect τ_0_1) for <Input, Nunca, Output>
25+
%convert = convert_function %callee : $@convention(thin) @Sendable @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> (@out τ_0_2, @error_indirect τ_0_1) for <Input, Nunca, Output> to $@convention(thin) @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> (@out τ_0_2, @error_indirect τ_0_1) for <Input, Nunca, Output> // user: %216
26+
specify_test "sil_combine_instruction @instruction[4]"
27+
apply [nothrow] %convert(%output, %nunca, %input) : $@convention(thin) @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> (@out τ_0_2, @error_indirect τ_0_1) for <Input, Nunca, Output>
28+
dealloc_stack %nunca : $*Nunca
29+
dealloc_stack %output : $*Output
30+
%retval = tuple ()
31+
return %retval : $()
32+
}
33+
34+

0 commit comments

Comments
 (0)