Skip to content

Commit ac61901

Browse files
committed
SwiftCompilerSources/SIL: Fix APInt assertion failure on rebranch
The assertion is hit through `TypeValueInst.simplify` when constructing an integer literal instruction with a negative 64-bit `Swift.Int` and a bit width of 32 (the target pointer bit width for arm64_32 watchOS). This happens because we tell the `llvm::APInt` constructor to treat the input integer as unsigned by default in `getAPInt`, and a negative 64-bit signed integer does not fit into 32 bits when interpreted as unsigned. Fix this by flipping the default signedness assumption for the Swift API and introducing a convenience method for constructing a 1-bit integer literal instruction, where the correct signedness assumption depends on whether you want to use 1 or -1 for 'true'. In the context of using an integer to construct an `llvm::APInt`, there are 2 other cases where signedness matters that come to mind: 1. A non-decimal integer literal narrower than 64 bits, such as `0xABCD`, is used. 2. The desired bit width is >64, since `llvm::APInt` can either zero-extend or sign-extend the 64-bit integer it accepts. Neither of these appear to be exercised in SwiftCompilerSources, and if we ever do, the caller should be responsible for either (1) appropriately extending the literal manually, e.g. `Int(Int16(bitPattern: 0xABCD))`, or (2) passing along the appropriate signedness.
1 parent 963aad3 commit ac61901

File tree

7 files changed

+27
-14
lines changed

7 files changed

+27
-14
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBeginCOWMutation.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ private extension BeginCOWMutationInst {
6565
return
6666
}
6767
let builder = Builder(before: self, location: location, context)
68-
let zero = builder.createIntegerLiteral(0, type: uniquenessResult.type);
69-
uniquenessResult.uses.replaceAll(with: zero, context)
68+
let falseLiteral = builder.createBoolLiteral(false)
69+
uniquenessResult.uses.replaceAll(with: falseLiteral, context)
7070
}
7171

7272
func optimizeEmptyBeginEndPair(_ context: SimplifyContext) -> Bool {

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private extension BuiltinInst {
8181
return
8282
}
8383
let builder = Builder(before: self, context)
84-
let result = builder.createIntegerLiteral(hasArchetype ? 0 : 1, type: type)
84+
let result = builder.createBoolLiteral(!hasArchetype)
8585
uses.replaceAll(with: result, context)
8686
context.erase(instruction: self)
8787
}
@@ -94,7 +94,7 @@ private extension BuiltinInst {
9494
return
9595
}
9696
let builder = Builder(before: self, context)
97-
let result = builder.createIntegerLiteral(equal ? 1 : 0, type: type)
97+
let result = builder.createBoolLiteral(equal)
9898

9999
uses.replaceAll(with: result, context)
100100
}
@@ -250,7 +250,7 @@ private extension BuiltinInst {
250250
operands[0].value.lookThroughScalarCasts is StringLiteralInst
251251
{
252252
let builder = Builder(before: self, context)
253-
let result = builder.createIntegerLiteral(isEqual ? 0 : 1, type: type)
253+
let result = builder.createBoolLiteral(!isEqual)
254254
uses.replaceAll(with: result, context)
255255
context.erase(instruction: self)
256256
return true

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyClassifyBridgeObject.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ extension ClassifyBridgeObjectInst : OnoneSimplifiable, SILCombineSimplifiable {
2323
}
2424

2525
let builder = Builder(before: self, context)
26-
let falseLiteral = builder.createIntegerLiteral(0, type: context.getBuiltinIntegerType(bitWidth: 1))
26+
let falseLiteral = builder.createBoolLiteral(false)
2727
let tp = builder.createTuple(type: self.type, elements: [falseLiteral, falseLiteral])
2828
uses.replaceAll(with: tp, context)
2929
context.erase(instruction: self)

SwiftCompilerSources/Sources/Optimizer/Utilities/Devirtualization.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ private func devirtualize(builtinDestroyArray: BuiltinInst, _ context: some Muta
288288
let preheaderBuilder = Builder(atEndOf: preheaderBlock, location: builtinDestroyArray.location, context)
289289
let zero = preheaderBuilder.createIntegerLiteral(0, type: indexType)
290290
let one = preheaderBuilder.createIntegerLiteral(1, type: indexType)
291-
let falseValue = preheaderBuilder.createIntegerLiteral(0, type: boolType)
291+
let falseValue = preheaderBuilder.createBoolLiteral(false);
292292
let baseAddress = preheaderBuilder.createPointerToAddress(pointer: basePointer,
293293
addressType: elementType.addressType,
294294
isStrict: true, isInvariant: false)

SwiftCompilerSources/Sources/SIL/Builder.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,21 @@ public struct Builder {
190190
}
191191
}
192192

193-
public func createIntegerLiteral(_ value: Int, type: Type) -> IntegerLiteralInst {
194-
let literal = bridged.createIntegerLiteral(type.bridged, value)
193+
private func createIntegerLiteral(_ value: Int, type: Type, treatAsSigned: Bool) -> IntegerLiteralInst {
194+
let literal = bridged.createIntegerLiteral(type.bridged, value, treatAsSigned)
195195
return notifyNew(literal.getAs(IntegerLiteralInst.self))
196196
}
197-
197+
198+
public func createIntegerLiteral(_ value: Int, type: Type) -> IntegerLiteralInst {
199+
createIntegerLiteral(value, type: type, treatAsSigned: true)
200+
}
201+
202+
/// Creates a `Builtin.Int1` integer literal instruction with the given value.
203+
public func createBoolLiteral(_ value: Bool) -> IntegerLiteralInst {
204+
let boolType = notificationHandler.getBuiltinIntegerType(1).type
205+
return createIntegerLiteral(value ? 1 : 0, type: boolType, treatAsSigned: false)
206+
}
207+
198208
public func createAllocRef(_ type: Type, isObjC: Bool = false, canAllocOnStack: Bool = false, isBare: Bool = false,
199209
tailAllocatedTypes: TypeArray, tailAllocatedCounts: [Value]) -> AllocRefInst {
200210
return tailAllocatedCounts.withBridgedValues { countsRef in

include/swift/SIL/SILBridging.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,8 @@ struct BridgedBuilder{
11971197
BridgedValueArray arguments) const;
11981198
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createCondFail(BridgedValue condition,
11991199
BridgedStringRef message) const;
1200-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createIntegerLiteral(BridgedType type, SwiftInt value) const;
1200+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createIntegerLiteral(
1201+
BridgedType type, SwiftInt value, bool treatAsSigned) const;
12011202

12021203
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createAllocRef(BridgedType type,
12031204
bool objc, bool canAllocOnStack, bool isBare,

include/swift/SIL/SILBridgingImpl.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,9 +2219,11 @@ BridgedInstruction BridgedBuilder::createCondFail(BridgedValue condition, Bridge
22192219
message.unbridged())};
22202220
}
22212221

2222-
BridgedInstruction BridgedBuilder::createIntegerLiteral(BridgedType type, SwiftInt value) const {
2223-
return {
2224-
unbridged().createIntegerLiteral(regularLoc(), type.unbridged(), value)};
2222+
BridgedInstruction
2223+
BridgedBuilder::createIntegerLiteral(BridgedType type, SwiftInt value,
2224+
bool treatAsSigned) const {
2225+
return {unbridged().createIntegerLiteral(regularLoc(), type.unbridged(),
2226+
value, treatAsSigned)};
22252227
}
22262228

22272229
BridgedInstruction BridgedBuilder::createAllocRef(BridgedType type,

0 commit comments

Comments
 (0)