Skip to content

Commit dfe4393

Browse files
Merge pull request #19333 from adrian-prantl/43566087
Zero-initialize -Onone debug shadow copies for exploded values
2 parents 1281f3d + 9cb0b8e commit dfe4393

12 files changed

+54
-53
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -720,31 +720,25 @@ class IRGenSILFunction :
720720
}
721721

722722
/// To make it unambiguous whether a `var` binding has been initialized,
723-
/// zero-initialize the first pointer-sized field. LLDB uses this to
724-
/// recognize to detect uninitizialized variables. This can be removed once
725-
/// swiftc switches to @llvm.dbg.addr() intrinsics.
723+
/// zero-initialize the shadow copy alloca. LLDB uses the first pointer-sized
724+
/// field to recognize to detect uninitizialized variables. This can be
725+
/// removed once swiftc switches to @llvm.dbg.addr() intrinsics.
726726
void zeroInit(llvm::AllocaInst *AI) {
727727
if (!AI)
728728
return;
729729

730730
// Only do this at -Onone.
731-
if (IGM.IRGen.Opts.shouldOptimize())
732-
return;
733-
734-
auto &DL = IGM.DataLayout;
735-
if (DL.getTypeSizeInBits(AI->getAllocatedType()) <
736-
DL.getPointerSizeInBits())
731+
uint64_t Size = *AI->getAllocationSizeInBits(IGM.DataLayout) / 8;
732+
if (IGM.IRGen.Opts.shouldOptimize() || !Size)
737733
return;
738734

739735
llvm::IRBuilder<> ZeroInitBuilder(AI->getNextNode());
740736

741737
// No debug location is how LLVM marks prologue instructions.
742738
ZeroInitBuilder.SetCurrentDebugLocation(nullptr);
743-
auto *BC =
744-
ZeroInitBuilder.CreateBitCast(AI, IGM.OpaquePtrTy->getPointerTo());
745-
ZeroInitBuilder.CreateAlignedStore(
746-
llvm::ConstantPointerNull::get(IGM.OpaquePtrTy), BC,
747-
IGM.getPointerAlignment().getValue());
739+
ZeroInitBuilder.CreateMemSet(
740+
AI, llvm::ConstantInt::get(IGM.Int8Ty, 0),
741+
Size, AI->getAlignment());
748742
}
749743

750744
/// Account for bugs in LLVM.
@@ -769,8 +763,8 @@ class IRGenSILFunction :
769763

770764
auto &Alloca = ShadowStackSlots[{ArgNo, {Scope, Name}}];
771765
if (!Alloca.isValid())
772-
Alloca = createAlloca(Storage->getType(), Align, Name+".addr");
773-
zeroInit(dyn_cast<llvm::AllocaInst>(Alloca.getAddress()));
766+
Alloca = createAlloca(Storage->getType(), Align, Name+".debug");
767+
zeroInit(cast<llvm::AllocaInst>(Alloca.getAddress()));
774768

775769
ArtificialLocation AutoRestore(Scope, IGM.DebugInfo, Builder);
776770
Builder.CreateStore(Storage, Alloca.getAddress(), Align);
@@ -848,7 +842,8 @@ class IRGenSILFunction :
848842

849843
SILType Type = SILVal->getType();
850844
auto &LTI = cast<LoadableTypeInfo>(IGM.getTypeInfo(Type));
851-
auto Alloca = LTI.allocateStack(*this, Type, "debug.copy");
845+
auto Alloca = LTI.allocateStack(*this, Type, Name+".debug");
846+
zeroInit(cast<llvm::AllocaInst>(Alloca.getAddress().getAddress()));
852847
ArtificialLocation AutoRestore(Scope, IGM.DebugInfo, Builder);
853848
LTI.initialize(*this, e, Alloca.getAddress(), false /* isOutlined */);
854849
copy.push_back(Alloca.getAddressPointer());

test/DebugInfo/dbgvalue-insertpt.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// FIXME: This test should be testing a non-shadow-copied value instead.
33
for i in 0 ..< 3 {
44
// CHECK: %[[ALLOCA:[0-9]+]] = alloca %TSiSg
5-
// CHECK: %i.addr = alloca i{{32|64}}
6-
// CHECK-NEXT: call void @llvm.dbg.declare(metadata i{{32|64}}* %i.addr,
5+
// CHECK: %i.debug = alloca i{{32|64}}
6+
// CHECK-NEXT: call void @llvm.dbg.declare(metadata i{{32|64}}* %i.debug,
77
// CHECK-SAME: metadata ![[I:[0-9]+]],
88
// CHECK: call swiftcc{{.*}} @{{.*}}next{{.*}}
99
// CHECK: %[[LD:[0-9]+]] = load i{{32|64}}, i{{32|64}}*
@@ -14,6 +14,6 @@ for i in 0 ..< 3 {
1414
//
1515
// CHECK: ; <label>:[[NEXT_BB]]:
1616
// CHECK: %[[PHI_VAL:.*]] = phi i{{32|64}} [ %[[LD]], %[[SUCCESS]] ]
17-
// CHECK: store i{{32|64}} %[[PHI_VAL]], i{{32|64}}* %i.addr
17+
// CHECK: store i{{32|64}} %[[PHI_VAL]], i{{32|64}}* %i.debug
1818
// CHECK: ![[I]] = !DILocalVariable(name: "i",
1919
}

test/DebugInfo/generic_arg2.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
22

33
// CHECK: define hidden swiftcc void @"$S12generic_arg25ClassC3foo{{.*}}, %swift.type* %U
4-
// CHECK: call void @llvm.dbg.declare(metadata %swift.opaque** %y.addr, metadata ![[U:.*]], metadata !DIExpression())
4+
// CHECK: call void @llvm.dbg.declare(metadata %swift.opaque** %y.debug, metadata ![[U:.*]], metadata !DIExpression())
55
// Make sure there is no conflicting dbg.value for this variable.x
66
// CHECK-NOT: dbg.value{{.*}}metadata ![[U]]
77
class Class <T> {

test/DebugInfo/guard-let.swift

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
1-
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
2-
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s --check-prefix=CHECK2
1+
// RUN: %target-swift-frontend %s -c -emit-ir -g -o - | \
2+
// RUN: %FileCheck %s --check-prefix=CHECK1
3+
// RUN: %target-swift-frontend %s -c -emit-ir -g -o - | \
4+
// RUN: %FileCheck %s --check-prefix=CHECK2
35

46
// UNSUPPORTED: OS=watchos
57

68
func use<T>(_ t: T) {}
79

810
public func f(_ i : Int?)
911
{
10-
// CHECK: define {{.*}}@"$S4main1fyySiSgF"
11-
// CHECK1: %debug.copy = alloca %TSiSg
12-
// CHECK1: @llvm.dbg.declare(metadata %TSiSg* %debug.copy
13-
// CHECK1: @llvm.dbg.declare(metadata {{(i32|i64)}}* %val.addr, {{.*}}, !dbg ![[DBG0:.*]]
14-
// CHECK1: %5 = bitcast %TSiSg* %debug.copy to i64*, !dbg
15-
// CHECK1: store i64 %0, i64* %5, align 8, !dbg
12+
// CHECK1-LABEL: define {{.*}}@"$S4main1fyySiSgF"
13+
// CHECK1: %i.debug = alloca %TSiSg
14+
// CHECK1: @llvm.dbg.declare(metadata %TSiSg* %i.debug
15+
// CHECK1: %[[BITCAST:.*]] = bitcast %TSiSg* %i.debug to i8*
16+
// CHECK1: call void @llvm.memset{{.*}}(i8* align {{(4|8)}} %[[BITCAST]],
17+
// CHECK1-SAME: i8 0, i64 {{(5|9)}}, i1 false){{$}}
18+
// CHECK1: @llvm.dbg.declare(metadata {{(i32|i64)}}* %val.debug,
19+
// CHECK1-SAME: !dbg ![[DBG0:.*]]
20+
// CHECK1-LABEL: define {{.*}}@"$S4main1gyySSSgF"
1621
// CHECK1: ![[F:.*]] = distinct !DISubprogram(name: "f",
1722
// CHECK1: ![[BLK:.*]] = distinct !DILexicalBlock(scope: ![[F]],
18-
// CHECK1: ![[DBG0]] = !DILocation(line: [[@LINE+2]],
19-
// CHECK1: ![[DBG1]] = !DILocation(line: 0, scope: ![[BLK]])
23+
// CHECK1: ![[DBG0]] = !DILocation(line: [[@LINE+1]],
2024
guard let val = i else { return }
2125
use(val)
2226
}
@@ -32,13 +36,12 @@ public func f(_ i : Int?)
3236
public func g(_ s : String?)
3337
{
3438
// CHECK2: define {{.*}}@"$S4main1gyySSSgF"
35-
// CHECK2: %debug.copy = alloca %TSSSg
39+
// CHECK2: %s.debug = alloca %TSSSg
3640
// CHECK2: @llvm.dbg.declare(metadata %TSSSg*
37-
// CHECK2: %debug.copy1 = alloca %TSS
41+
// CHECK2: %val.debug = alloca %TSS
3842
// CHECK2: @llvm.dbg.declare(metadata %TSS*
39-
// CHECK2: %4 = bitcast %TSSSg* %debug.copy to {{.*}}*, !dbg
40-
// CHECK2: %5 = getelementptr inbounds {{.*}}, {{.*}}* %4, i32 0, i32 0, !dbg
41-
// CHECK2: store {{.*}} %0, {{.*}}* %5, align 8, !dbg
43+
// CHECK2: %[[BITCAST:.*]] = bitcast %TSS* %val.debug to i8*{{$}}
44+
// CHECK2: call void @llvm.memset.{{.*}}(i8* align {{(4|8)}} %[[BITCAST]], i8 0
4245
// CHECK2: ![[G:.*]] = distinct !DISubprogram(name: "g"
4346
guard let val = s else { return }
4447
use(val)

test/DebugInfo/linetable-codeview.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ func foo() {
4747
// NOTE: The point of this test is to trigger IRGenSIL::emitShadowCopy()
4848
// and IRGenSIL::emitShadowCopyIfNeeded(). It may be worthwhile to
4949
// simplify this testcase.
50-
// CHECK: store float %0, float* %myArg.addr, {{.*}}, !dbg ![[PROLOGUE:[0-9]+]]
51-
// CHECK: store float {{.*}}, float* %debug.copy.myVal1._value, {{.*}}, !dbg ![[PROLOGUE]]
50+
// CHECK: store float %0, float* %myArg.debug, {{.*}}, !dbg ![[PROLOGUE:[0-9]+]]
51+
// CHECK: store float {{.*}}, float* %self.debug.myVal1._value, {{.*}}, !dbg ![[PROLOGUE]]
5252

5353
// func myLoop() {
5454
// CHECK: define {{.*}} @"$S4main6myLoopyyF"
55-
// CHECK: call void @llvm.dbg.declare(metadata i64* %index.addr, {{.*}}), !dbg ![[FORLOOP:[0-9]+]]
55+
// CHECK: call void @llvm.dbg.declare(metadata i64* %index.debug, {{.*}}), !dbg ![[FORLOOP:[0-9]+]]
5656
// CHECK: phi i64 [ %{{.[0-9]+}}, %{{.[0-9]+}} ], !dbg ![[FORLOOP]]
5757
// CHECK: call {{.*}} @"$S4main8markUsedyyxlF"{{.*}}, !dbg ![[FORBODY:[0-9]+]]
5858
// CHECK: ret void

test/DebugInfo/shadowcopy-linetable.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ func foo(_ x: inout Int64) {
88
// not.
99
// CHECK: %[[X:.*]] = alloca %Ts5Int64V*, align {{(4|8)}}
1010
// CHECK-NEXT: call void @llvm.dbg.declare
11-
// CHECK-NEXT: [[ZEROED:%[0-9]+]] = bitcast %Ts5Int64V** %[[X]] to %swift.opaque**
12-
// CHECK-NEXT: store %swift.opaque* null, %swift.opaque** [[ZEROED]], align {{(4|8)}}
11+
// CHECK-NEXT: %[[ZEROED:[0-9]+]] = bitcast %Ts5Int64V** %[[X]] to i8*{{$}}
12+
// CHECK-NEXT: call void @llvm.memset.{{.*}}(i8* align {{(4|8)}} %[[ZEROED]], i8 0
1313
// CHECK: store %Ts5Int64V* %0, %Ts5Int64V** %[[X]], align {{(4|8)}}
1414
// CHECK-SAME: !dbg ![[LOC0:.*]]
1515
// CHECK-NEXT: getelementptr inbounds %Ts5Int64V, %Ts5Int64V* %0, i32 0, i32 0,

test/DebugInfo/uninitialized.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
2-
// RUN: %target-swift-frontend %s -O -emit-ir -g -o - | %FileCheck %s --check-prefix=OPT
1+
// RUN: %target-swift-frontend %s -c -emit-ir -g -o - | %FileCheck %s
2+
// RUN: %target-swift-frontend %s -O -c -emit-ir -g -o - | %FileCheck %s --check-prefix=OPT
33
class MyClass {}
44

55
// CHECK-LABEL: define {{.*}} @"$S13uninitialized1fyyF"
@@ -8,9 +8,10 @@ public func f() {
88
var object: MyClass
99
// CHECK: %[[OBJ:.*]] = alloca %[[T1:.*]]*, align
1010
// CHECK: call void @llvm.dbg.declare(metadata %[[T1]]** %[[OBJ]],
11-
// CHECK: %[[BC1:.*]] = bitcast %[[T1]]** %[[OBJ]] to %swift.opaque**
12-
// CHECK: store %swift.opaque* null, %swift.opaque** %[[BC1]], align {{.*}}
13-
// OPT-NOT: store
11+
// CHECK: %[[BC1:.*]] = bitcast %[[T1]]** %[[OBJ]] to i8*{{$}}
12+
// CHECK: void @llvm.memset.{{.*}}(i8* align {{(4|8)}} %[[BC1]], i8 0,
13+
// CHECK-SAME: ){{$}}
14+
// OPT-NOT: @llvm.memset
1415
// OPT: ret
1516
}
1617

@@ -20,8 +21,9 @@ public func g() {
2021
var dict: Dictionary<Int64, Int64>
2122
// CHECK: %[[DICT:.*]] = alloca %[[T2:.*]], align
2223
// CHECK: call void @llvm.dbg.declare(metadata %[[T2]]* %[[DICT]],
23-
// CHECK: %[[BC2:.*]] = bitcast %[[T2]]* %[[DICT]] to %swift.opaque**
24-
// CHECK: store %swift.opaque* null, %swift.opaque** %[[BC2]], align {{.*}}
25-
// OPT-NOT: store
24+
// CHECK: %[[BC2:.*]] = bitcast %[[T2]]* %[[DICT]] to i8*
25+
// CHECK: void @llvm.memset.{{.*}}(i8* align {{(4|8)}} %[[BC2]], i8 0,
26+
// CHECK-SAME: ){{$}}
27+
// OPT-NOT: @llvm.memset
2628
// OPT: ret
2729
}

test/IRGen/alloc_box.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ func f() -> Bool? { return nil }
99
})()
1010

1111
// CHECK-LABEL: @"$S9alloc_boxyyXEfU_"
12-
// CHECK: <label>:8:
12+
// CHECK: <label>:9:
1313
// CHECK-NOT: call void @swift_setDeallocating
1414
// CHECK: call void @swift_deallocUninitializedObject
1515

test/IRGen/builtins.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,7 @@ func unsafeGuaranteed_test(_ x: Builtin.NativeObject) -> Builtin.NativeObject {
748748
// CHECK-LABEL: define {{.*}} @{{.*}}unsafeGuaranteedEnd_test
749749
// CHECK-NEXT: {{.*}}:
750750
// CHECK-NEXT: alloca
751+
// CHECK-NEXT: memset
751752
// CHECK-NEXT: store
752753
// CHECK-NEXT: ret void
753754
func unsafeGuaranteedEnd_test(_ x: Builtin.Int8) {

test/IRGen/class_bounded_generics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ func archetype_with_generic_class_constraint<T, U>(t: T) where T : A<U> {
298298

299299
// CHECK-LABEL: define hidden swiftcc void @"$S22class_bounded_generics029calls_archetype_with_generic_A11_constraint1ayAA1ACyxG_tlF"(%T22class_bounded_generics1AC*) #0 {
300300
// CHECK: alloca
301-
// CHECK: store
301+
// CHECK: memset
302302
// CHECK: [[ISA_ADDR:%.*]] = getelementptr inbounds %T22class_bounded_generics1AC, %T22class_bounded_generics1AC* %0, i32 0, i32 0, i32 0
303303
// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
304304
// CHECK: [[ISA_PTR:%.*]] = bitcast %swift.type* [[ISA]] to %swift.type**

test/IRGen/objc.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func test1(_ cell: Blammo) {}
9191
// CHECK-NEXT: entry
9292
// CHECK-NEXT: alloca
9393
// CHECK-NEXT: bitcast
94-
// CHECK-NEXT: store
94+
// CHECK-NEXT: memset
9595
// CHECK-NEXT: store
9696
// CHECK-NEXT: ret void
9797

test/IRGen/struct_resilience.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public func functionWithMyResilientTypesSize(_ s: __owned MySize, f: (__owned My
9797
// CHECK: bitcast
9898
// CHECK: llvm.lifetime.start
9999
// CHECK: bitcast
100-
// CHECK: [[COPY:%.*]] = bitcast %T17struct_resilience6MySizeV* %4 to i8*
100+
// CHECK: [[COPY:%.*]] = bitcast %T17struct_resilience6MySizeV* %5 to i8*
101101
// CHECK: [[ARG:%.*]] = bitcast %T17struct_resilience6MySizeV* %1 to i8*
102102
// CHECK: call void @llvm.memcpy{{.*}}(i8* align {{4|8}} [[COPY]], i8* align {{4|8}} [[ARG]], {{i32 8|i64 16}}, i1 false)
103103
// CHECK: [[FN:%.*]] = bitcast i8* %2

0 commit comments

Comments
 (0)