Merge pull request #84008 from drexin/wip-159143492-6.2.1

[6.2.1][IRGen] Fix computation of spare bits for fixed arrays
This commit is contained in:
Dario Rexin
2025-09-04 13:25:55 -07:00
committed by GitHub
3 changed files with 87 additions and 2 deletions

View File

@@ -240,9 +240,15 @@ protected:
// Take spare bits from the first element only.
SpareBitVector result = elementTI.getSpareBits();
// We can use the padding to the next element as spare bits too.
result.appendSetBits(getArraySize(arraySize, elementTI).getValueInBits()
- result.size());
auto padding = elementTI.getFixedStride() - elementTI.getFixedSize();
result.appendSetBits(padding.getValueInBits());
// spare bits of any other elements should not be considered
result.appendClearBits(
getArraySize(arraySize - 1, elementTI).getValueInBits());
return result;
}

View File

@@ -0,0 +1,44 @@
// RUN: %target-swift-frontend -disable-availability-checking -O -emit-ir %s | %FileCheck %s
// UNSUPPORTED: PTRSIZE=32
public struct Foo {
let x: UInt64
let y: InlineArray<2, UInt64>
}
public struct Bar {
let x: UInt64
let y: [UInt64]
}
// CHECK: define {{.*}} i32 @"$s22inline_array_enum_tags3BazOwug"(ptr noalias nocapture readonly %value, ptr nocapture readnone %Baz)
// CHECK: [[TAG_ADDR:%.*]] = getelementptr inbounds i8, ptr %value, i64 24
// CHECK: [[TAG_VAL:%.*]] = load i1, ptr [[TAG_ADDR]], align 8
// CHECK: [[TAG_EXT:%.*]] = zext i1 [[TAG_VAL]] to i32
// CHECK: ret i32 [[TAG_EXT]]
// CHECK: }
public enum Baz {
case foo(Foo)
case bar(Bar)
}
public struct Padded {
let x: UInt64
let y: InlineArray<2, (UInt16, UInt8)>
}
// CHECK: define {{.*}} i32 @"$s22inline_array_enum_tags17WithPaddedPayloadOwug"(ptr noalias nocapture readonly %value, ptr nocapture readnone %WithPaddedPayload)
// CHECK: entry:
// CHECK: [[ADDR:%.*]] = getelementptr inbounds i8, ptr %value, i64 8
// CHECK: [[VAL:%.*]] = load i64, ptr [[ADDR]], align 8
// CHECK: [[MASKED:%.*]] = and i64 [[VAL]], 2147483648
// CHECK: [[TAG:%.*]] = icmp ne i64 [[MASKED]], 0
// CHECK: [[EXTENDED:%.*]] = zext i1 [[TAG]] to i32
// CHECK: ret i32 [[EXTENDED]]
// CHECK: }
public enum WithPaddedPayload {
case a(Padded)
case b(Padded)
}

View File

@@ -0,0 +1,35 @@
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking) | %FileCheck %s
// RUN: %target-run-simple-swift(-O -Xfrontend -disable-availability-checking) | %FileCheck %s
// REQUIRES: executable_test
// UNSUPPORTED: back_deployment_runtime || use_os_stdlib
struct Foo {
let x: UInt64
let y: InlineArray<2, UInt64>
}
struct Bar {
let x: UInt64
let y: [UInt64]
}
enum Baz {
case foo(Foo)
case bar(Bar)
}
@inline(never)
func createEnum() -> Baz {
return .foo(Foo(x: 0, y: [0, 0xff00000000000000]))
}
let x = createEnum()
// CHECK: 0 - 18374686479671623680
switch x {
case .bar: fatalError("Expected .foo")
case .foo(let x): print("\(x.y[0]) - \(x.y[1])")
}