Просмотр исходного кода

Fix name mangling of generic impls (#6533)

### Description
Mangling collisions occur when implementing interfaces with generic
parameters. The mangler does not use the specific id, causing the same
symbol `_C[FunctionName].[PackageName]:[InterfaceName].[PackageName]` to
be generated for all of the implementations below:
```carbon
// Generic interface parameters ignored
impl C as I(A)
impl C as I(B)

// Generic class parameters ignored
impl D(A) as I
impl D(B) as I

// Both ignored
impl D(A) as I(A)
impl D(B) as I(B)
```

### Changes
Updated the mangling logic for `SemIR::ClassDecl` and
`SemIR::InterfaceDecl` to include the specific id. Now the mangling
ensures unique symbols for generic implementations using the format:

`_C[FunctionName].[FunctionSpecificId].[PackageName]:[InterfaceName].[InterfaceSpecificId].[PackageName]`.

Closes #6498
Özgür 4 месяцев назад
Родитель
Сommit
29018f38a6
23 измененных файлов с 386 добавлено и 217 удалено
  1. 2 2
      toolchain/driver/testdata/compile/optimize/optimize_debug.carbon
  2. 2 2
      toolchain/driver/testdata/compile/optimize/optimize_default.carbon
  3. 9 9
      toolchain/driver/testdata/compile/optimize/optimize_none.carbon
  4. 9 9
      toolchain/driver/testdata/compile/optimize/optimize_size.carbon
  5. 2 2
      toolchain/driver/testdata/compile/optimize/optimize_speed.carbon
  6. 17 8
      toolchain/lower/mangler.cpp
  7. 9 9
      toolchain/lower/testdata/array/iterate.carbon
  8. 3 3
      toolchain/lower/testdata/class/convert.carbon
  9. 6 6
      toolchain/lower/testdata/for/bindings.carbon
  10. 15 15
      toolchain/lower/testdata/for/break_continue.carbon
  11. 15 15
      toolchain/lower/testdata/for/for.carbon
  12. 3 3
      toolchain/lower/testdata/function/generic/call_impl_function.carbon
  13. 4 4
      toolchain/lower/testdata/function/generic/type_representation.carbon
  14. 169 9
      toolchain/lower/testdata/impl/impl.carbon
  15. 3 3
      toolchain/lower/testdata/impl/import_facet.carbon
  16. 18 18
      toolchain/lower/testdata/impl/import_thunk.carbon
  17. 23 23
      toolchain/lower/testdata/impl/thunk.carbon
  18. 7 7
      toolchain/lower/testdata/interop/cpp/nullptr.carbon
  19. 8 8
      toolchain/lower/testdata/interop/cpp/pointer.carbon
  20. 6 6
      toolchain/lower/testdata/interop/cpp/void.carbon
  21. 9 9
      toolchain/lower/testdata/operators/increment.carbon
  22. 3 3
      toolchain/lower/testdata/operators/overloaded.carbon
  23. 44 44
      toolchain/lower/testdata/primitives/optional.carbon

+ 2 - 2
toolchain/driver/testdata/compile/optimize/optimize_debug.carbon

@@ -114,7 +114,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !22 = !DILocation(line: 18, column: 9, scope: !16)
 // CHECK:STDOUT: !22 = !DILocation(line: 18, column: 9, scope: !16)
 // CHECK:STDOUT: !23 = !DILocation(line: 19, column: 5, scope: !16)
 // CHECK:STDOUT: !23 = !DILocation(line: 19, column: 5, scope: !16)
 // CHECK:STDOUT: !24 = !DILocation(line: 275, column: 3, scope: !25, inlinedAt: !32)
 // CHECK:STDOUT: !24 = !DILocation(line: 275, column: 3, scope: !25, inlinedAt: !32)
-// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5", scope: null, file: !26, line: 275, type: !27, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !29)
+// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5", scope: null, file: !26, line: 275, type: !27, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !29)
 // CHECK:STDOUT: !26 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !26 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !27 = !DISubroutineType(types: !28)
 // CHECK:STDOUT: !27 = !DISubroutineType(types: !28)
 // CHECK:STDOUT: !28 = !{null, !7, !7}
 // CHECK:STDOUT: !28 = !{null, !7, !7}
@@ -122,7 +122,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !30 = !DILocalVariable(arg: 1, scope: !25, type: !7)
 // CHECK:STDOUT: !30 = !DILocalVariable(arg: 1, scope: !25, type: !7)
 // CHECK:STDOUT: !31 = !DILocalVariable(arg: 2, scope: !25, type: !7)
 // CHECK:STDOUT: !31 = !DILocalVariable(arg: 2, scope: !25, type: !7)
 // CHECK:STDOUT: !32 = distinct !DILocation(line: 341, column: 5, scope: !33, inlinedAt: !38)
 // CHECK:STDOUT: !32 = distinct !DILocation(line: 341, column: 5, scope: !33, inlinedAt: !38)
-// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !26, line: 339, type: !34, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !36)
+// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !26, line: 339, type: !34, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !36)
 // CHECK:STDOUT: !34 = !DISubroutineType(types: !35)
 // CHECK:STDOUT: !34 = !DISubroutineType(types: !35)
 // CHECK:STDOUT: !35 = !{null, !7}
 // CHECK:STDOUT: !35 = !{null, !7}
 // CHECK:STDOUT: !36 = !{!37}
 // CHECK:STDOUT: !36 = !{!37}

+ 2 - 2
toolchain/driver/testdata/compile/optimize/optimize_default.carbon

@@ -114,7 +114,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !22 = !DILocation(line: 18, column: 9, scope: !16)
 // CHECK:STDOUT: !22 = !DILocation(line: 18, column: 9, scope: !16)
 // CHECK:STDOUT: !23 = !DILocation(line: 19, column: 5, scope: !16)
 // CHECK:STDOUT: !23 = !DILocation(line: 19, column: 5, scope: !16)
 // CHECK:STDOUT: !24 = !DILocation(line: 275, column: 3, scope: !25, inlinedAt: !32)
 // CHECK:STDOUT: !24 = !DILocation(line: 275, column: 3, scope: !25, inlinedAt: !32)
-// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5", scope: null, file: !26, line: 275, type: !27, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !29)
+// CHECK:STDOUT: !25 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5", scope: null, file: !26, line: 275, type: !27, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !29)
 // CHECK:STDOUT: !26 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !26 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !27 = !DISubroutineType(types: !28)
 // CHECK:STDOUT: !27 = !DISubroutineType(types: !28)
 // CHECK:STDOUT: !28 = !{null, !7, !7}
 // CHECK:STDOUT: !28 = !{null, !7, !7}
@@ -122,7 +122,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !30 = !DILocalVariable(arg: 1, scope: !25, type: !7)
 // CHECK:STDOUT: !30 = !DILocalVariable(arg: 1, scope: !25, type: !7)
 // CHECK:STDOUT: !31 = !DILocalVariable(arg: 2, scope: !25, type: !7)
 // CHECK:STDOUT: !31 = !DILocalVariable(arg: 2, scope: !25, type: !7)
 // CHECK:STDOUT: !32 = distinct !DILocation(line: 341, column: 5, scope: !33, inlinedAt: !38)
 // CHECK:STDOUT: !32 = distinct !DILocation(line: 341, column: 5, scope: !33, inlinedAt: !38)
-// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !26, line: 339, type: !34, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !36)
+// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !26, line: 339, type: !34, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !36)
 // CHECK:STDOUT: !34 = !DISubroutineType(types: !35)
 // CHECK:STDOUT: !34 = !DISubroutineType(types: !35)
 // CHECK:STDOUT: !35 = !{null, !7}
 // CHECK:STDOUT: !35 = !{null, !7}
 // CHECK:STDOUT: !36 = !{!37}
 // CHECK:STDOUT: !36 = !{!37}

+ 9 - 9
toolchain/driver/testdata/compile/optimize/optimize_none.carbon

@@ -75,7 +75,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT:   %Int.as.MulAssignWith.impl.Op.call = load i32, ptr %.loc19_11.array.index, align 4, !dbg !24
 // CHECK:STDOUT:   %Int.as.MulAssignWith.impl.Op.call = load i32, ptr %.loc19_11.array.index, align 4, !dbg !24
 // CHECK:STDOUT:   %Int.as.MulAssignWith.impl.Op.call1 = mul i32 %Int.as.MulAssignWith.impl.Op.call, 2, !dbg !24
 // CHECK:STDOUT:   %Int.as.MulAssignWith.impl.Op.call1 = mul i32 %Int.as.MulAssignWith.impl.Op.call, 2, !dbg !24
 // CHECK:STDOUT:   store i32 %Int.as.MulAssignWith.impl.Op.call1, ptr %.loc19_11.array.index, align 4, !dbg !24
 // CHECK:STDOUT:   store i32 %Int.as.MulAssignWith.impl.Op.call1, ptr %.loc19_11.array.index, align 4, !dbg !24
-// CHECK:STDOUT:   call void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %n.var), !dbg !25
+// CHECK:STDOUT:   call void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %n.var), !dbg !25
 // CHECK:STDOUT:   br label %while.cond, !dbg !26
 // CHECK:STDOUT:   br label %while.cond, !dbg !26
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: while.done:                                       ; preds = %while.cond
 // CHECK:STDOUT: while.done:                                       ; preds = %while.cond
@@ -86,14 +86,14 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: noinline nounwind optnone
 // CHECK:STDOUT: ; Function Attrs: noinline nounwind optnone
-// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !28 {
-// CHECK:STDOUT:   call void @"_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5"(ptr %self, i32 1), !dbg !34
+// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !28 {
+// CHECK:STDOUT:   call void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5"(ptr %self, i32 1), !dbg !34
 // CHECK:STDOUT:   ret void, !dbg !35
 // CHECK:STDOUT:   ret void, !dbg !35
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: noinline nounwind optnone
 // CHECK:STDOUT: ; Function Attrs: noinline nounwind optnone
-// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5"(ptr %self, i32 %other) #0 !dbg !36 {
-// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e"(i32 %other), !dbg !42
+// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5"(ptr %self, i32 %other) #0 !dbg !36 {
+// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e"(i32 %other), !dbg !42
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !43
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !43
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !43
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !43
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !43
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !43
@@ -101,7 +101,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: noinline nounwind optnone
 // CHECK:STDOUT: ; Function Attrs: noinline nounwind optnone
-// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e"(i32 %self) #0 !dbg !44 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e"(i32 %self) #0 !dbg !44 {
 // CHECK:STDOUT:   ret i32 %self, !dbg !50
 // CHECK:STDOUT:   ret i32 %self, !dbg !50
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -139,7 +139,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !25 = !DILocation(line: 20, column: 5, scope: !14)
 // CHECK:STDOUT: !25 = !DILocation(line: 20, column: 5, scope: !14)
 // CHECK:STDOUT: !26 = !DILocation(line: 18, column: 3, scope: !14)
 // CHECK:STDOUT: !26 = !DILocation(line: 18, column: 3, scope: !14)
 // CHECK:STDOUT: !27 = !DILocation(line: 15, column: 1, scope: !14)
 // CHECK:STDOUT: !27 = !DILocation(line: 15, column: 1, scope: !14)
-// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !29, line: 339, type: !30, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !32)
+// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !29, line: 339, type: !30, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !32)
 // CHECK:STDOUT: !29 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !29 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !30 = !DISubroutineType(types: !31)
 // CHECK:STDOUT: !30 = !DISubroutineType(types: !31)
 // CHECK:STDOUT: !31 = !{null, !7}
 // CHECK:STDOUT: !31 = !{null, !7}
@@ -147,7 +147,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !33 = !DILocalVariable(arg: 1, scope: !28, type: !7)
 // CHECK:STDOUT: !33 = !DILocalVariable(arg: 1, scope: !28, type: !7)
 // CHECK:STDOUT: !34 = !DILocation(line: 341, column: 5, scope: !28)
 // CHECK:STDOUT: !34 = !DILocation(line: 341, column: 5, scope: !28)
 // CHECK:STDOUT: !35 = !DILocation(line: 339, column: 3, scope: !28)
 // CHECK:STDOUT: !35 = !DILocation(line: 339, column: 3, scope: !28)
-// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5", scope: null, file: !29, line: 275, type: !37, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !39)
+// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5", scope: null, file: !29, line: 275, type: !37, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !39)
 // CHECK:STDOUT: !37 = !DISubroutineType(types: !38)
 // CHECK:STDOUT: !37 = !DISubroutineType(types: !38)
 // CHECK:STDOUT: !38 = !{null, !7, !7}
 // CHECK:STDOUT: !38 = !{null, !7, !7}
 // CHECK:STDOUT: !39 = !{!40, !41}
 // CHECK:STDOUT: !39 = !{!40, !41}
@@ -155,7 +155,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !41 = !DILocalVariable(arg: 2, scope: !36, type: !7)
 // CHECK:STDOUT: !41 = !DILocalVariable(arg: 2, scope: !36, type: !7)
 // CHECK:STDOUT: !42 = !DILocation(line: 4294967295, scope: !36)
 // CHECK:STDOUT: !42 = !DILocation(line: 4294967295, scope: !36)
 // CHECK:STDOUT: !43 = !DILocation(line: 275, column: 3, scope: !36)
 // CHECK:STDOUT: !43 = !DILocation(line: 275, column: 3, scope: !36)
-// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e", scope: null, file: !45, line: 24, type: !46, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !48)
+// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e", scope: null, file: !45, line: 24, type: !46, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !48)
 // CHECK:STDOUT: !45 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !45 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !46 = !DISubroutineType(types: !47)
 // CHECK:STDOUT: !46 = !DISubroutineType(types: !47)
 // CHECK:STDOUT: !47 = !{!7, !7}
 // CHECK:STDOUT: !47 = !{!7, !7}

+ 9 - 9
toolchain/driver/testdata/compile/optimize/optimize_size.carbon

@@ -74,7 +74,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT:   %Int.as.MulAssignWith.impl.Op.call = load i32, ptr %.loc19_11.array.index, align 4, !dbg !24
 // CHECK:STDOUT:   %Int.as.MulAssignWith.impl.Op.call = load i32, ptr %.loc19_11.array.index, align 4, !dbg !24
 // CHECK:STDOUT:   %Int.as.MulAssignWith.impl.Op.call1 = mul i32 %Int.as.MulAssignWith.impl.Op.call, 2, !dbg !24
 // CHECK:STDOUT:   %Int.as.MulAssignWith.impl.Op.call1 = mul i32 %Int.as.MulAssignWith.impl.Op.call, 2, !dbg !24
 // CHECK:STDOUT:   store i32 %Int.as.MulAssignWith.impl.Op.call1, ptr %.loc19_11.array.index, align 4, !dbg !24
 // CHECK:STDOUT:   store i32 %Int.as.MulAssignWith.impl.Op.call1, ptr %.loc19_11.array.index, align 4, !dbg !24
-// CHECK:STDOUT:   call void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %n.var), !dbg !25
+// CHECK:STDOUT:   call void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %n.var), !dbg !25
 // CHECK:STDOUT:   br label %while.cond, !dbg !26
 // CHECK:STDOUT:   br label %while.cond, !dbg !26
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: while.done:                                       ; preds = %while.cond
 // CHECK:STDOUT: while.done:                                       ; preds = %while.cond
@@ -85,14 +85,14 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: minsize nounwind optsize
 // CHECK:STDOUT: ; Function Attrs: minsize nounwind optsize
-// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !28 {
-// CHECK:STDOUT:   call void @"_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5"(ptr %self, i32 1), !dbg !34
+// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !28 {
+// CHECK:STDOUT:   call void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5"(ptr %self, i32 1), !dbg !34
 // CHECK:STDOUT:   ret void, !dbg !35
 // CHECK:STDOUT:   ret void, !dbg !35
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline minsize nounwind optsize
 // CHECK:STDOUT: ; Function Attrs: alwaysinline minsize nounwind optsize
-// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5"(ptr %self, i32 %other) #2 !dbg !36 {
-// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e"(i32 %other), !dbg !42
+// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5"(ptr %self, i32 %other) #2 !dbg !36 {
+// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e"(i32 %other), !dbg !42
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !43
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !43
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !43
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !43
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !43
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !43
@@ -100,7 +100,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: minsize nounwind optsize
 // CHECK:STDOUT: ; Function Attrs: minsize nounwind optsize
-// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e"(i32 %self) #0 !dbg !44 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e"(i32 %self) #0 !dbg !44 {
 // CHECK:STDOUT:   ret i32 %self, !dbg !50
 // CHECK:STDOUT:   ret i32 %self, !dbg !50
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -139,7 +139,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !25 = !DILocation(line: 20, column: 5, scope: !14)
 // CHECK:STDOUT: !25 = !DILocation(line: 20, column: 5, scope: !14)
 // CHECK:STDOUT: !26 = !DILocation(line: 18, column: 3, scope: !14)
 // CHECK:STDOUT: !26 = !DILocation(line: 18, column: 3, scope: !14)
 // CHECK:STDOUT: !27 = !DILocation(line: 15, column: 1, scope: !14)
 // CHECK:STDOUT: !27 = !DILocation(line: 15, column: 1, scope: !14)
-// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !29, line: 339, type: !30, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !32)
+// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !29, line: 339, type: !30, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !32)
 // CHECK:STDOUT: !29 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !29 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !30 = !DISubroutineType(types: !31)
 // CHECK:STDOUT: !30 = !DISubroutineType(types: !31)
 // CHECK:STDOUT: !31 = !{null, !7}
 // CHECK:STDOUT: !31 = !{null, !7}
@@ -147,7 +147,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !33 = !DILocalVariable(arg: 1, scope: !28, type: !7)
 // CHECK:STDOUT: !33 = !DILocalVariable(arg: 1, scope: !28, type: !7)
 // CHECK:STDOUT: !34 = !DILocation(line: 341, column: 5, scope: !28)
 // CHECK:STDOUT: !34 = !DILocation(line: 341, column: 5, scope: !28)
 // CHECK:STDOUT: !35 = !DILocation(line: 339, column: 3, scope: !28)
 // CHECK:STDOUT: !35 = !DILocation(line: 339, column: 3, scope: !28)
-// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5", scope: null, file: !29, line: 275, type: !37, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !39)
+// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5", scope: null, file: !29, line: 275, type: !37, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !39)
 // CHECK:STDOUT: !37 = !DISubroutineType(types: !38)
 // CHECK:STDOUT: !37 = !DISubroutineType(types: !38)
 // CHECK:STDOUT: !38 = !{null, !7, !7}
 // CHECK:STDOUT: !38 = !{null, !7, !7}
 // CHECK:STDOUT: !39 = !{!40, !41}
 // CHECK:STDOUT: !39 = !{!40, !41}
@@ -155,7 +155,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !41 = !DILocalVariable(arg: 2, scope: !36, type: !7)
 // CHECK:STDOUT: !41 = !DILocalVariable(arg: 2, scope: !36, type: !7)
 // CHECK:STDOUT: !42 = !DILocation(line: 4294967295, scope: !36)
 // CHECK:STDOUT: !42 = !DILocation(line: 4294967295, scope: !36)
 // CHECK:STDOUT: !43 = !DILocation(line: 275, column: 3, scope: !36)
 // CHECK:STDOUT: !43 = !DILocation(line: 275, column: 3, scope: !36)
-// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e", scope: null, file: !45, line: 24, type: !46, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !48)
+// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e", scope: null, file: !45, line: 24, type: !46, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !48)
 // CHECK:STDOUT: !45 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !45 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !46 = !DISubroutineType(types: !47)
 // CHECK:STDOUT: !46 = !DISubroutineType(types: !47)
 // CHECK:STDOUT: !47 = !{!7, !7}
 // CHECK:STDOUT: !47 = !{!7, !7}

+ 2 - 2
toolchain/driver/testdata/compile/optimize/optimize_speed.carbon

@@ -129,7 +129,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !21 = !DILocalVariable(arg: 1, scope: !16, type: !19)
 // CHECK:STDOUT: !21 = !DILocalVariable(arg: 1, scope: !16, type: !19)
 // CHECK:STDOUT: !22 = !DILocation(line: 18, column: 9, scope: !16)
 // CHECK:STDOUT: !22 = !DILocation(line: 18, column: 9, scope: !16)
 // CHECK:STDOUT: !23 = !DILocation(line: 275, column: 3, scope: !24, inlinedAt: !31)
 // CHECK:STDOUT: !23 = !DILocation(line: 275, column: 3, scope: !24, inlinedAt: !31)
-// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5", scope: null, file: !25, line: 275, type: !26, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !28)
+// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5", scope: null, file: !25, line: 275, type: !26, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !28)
 // CHECK:STDOUT: !25 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !25 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !26 = !DISubroutineType(types: !27)
 // CHECK:STDOUT: !26 = !DISubroutineType(types: !27)
 // CHECK:STDOUT: !27 = !{null, !7, !7}
 // CHECK:STDOUT: !27 = !{null, !7, !7}
@@ -137,7 +137,7 @@ fn VectorizedWithOptSpeed(a: array(i32, 65536)*) {
 // CHECK:STDOUT: !29 = !DILocalVariable(arg: 1, scope: !24, type: !7)
 // CHECK:STDOUT: !29 = !DILocalVariable(arg: 1, scope: !24, type: !7)
 // CHECK:STDOUT: !30 = !DILocalVariable(arg: 2, scope: !24, type: !7)
 // CHECK:STDOUT: !30 = !DILocalVariable(arg: 2, scope: !24, type: !7)
 // CHECK:STDOUT: !31 = distinct !DILocation(line: 341, column: 5, scope: !32, inlinedAt: !37)
 // CHECK:STDOUT: !31 = distinct !DILocation(line: 341, column: 5, scope: !32, inlinedAt: !37)
-// CHECK:STDOUT: !32 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !25, line: 339, type: !33, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !35)
+// CHECK:STDOUT: !32 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !25, line: 339, type: !33, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !35)
 // CHECK:STDOUT: !33 = !DISubroutineType(types: !34)
 // CHECK:STDOUT: !33 = !DISubroutineType(types: !34)
 // CHECK:STDOUT: !34 = !{null, !7}
 // CHECK:STDOUT: !34 = !{null, !7}
 // CHECK:STDOUT: !35 = !{!36}
 // CHECK:STDOUT: !35 = !{!36}

+ 17 - 8
toolchain/lower/mangler.cpp

@@ -13,6 +13,7 @@
 #include "toolchain/sem_ir/entry_point.h"
 #include "toolchain/sem_ir/entry_point.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/pattern.h"
 #include "toolchain/sem_ir/pattern.h"
+#include "toolchain/sem_ir/typed_insts.h"
 
 
 namespace Carbon::Lower {
 namespace Carbon::Lower {
 
 
@@ -29,6 +30,7 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
   // Maintain a stack of names for delayed rendering of interface impls.
   // Maintain a stack of names for delayed rendering of interface impls.
   struct NameEntry {
   struct NameEntry {
     SemIR::NameScopeId name_scope_id;
     SemIR::NameScopeId name_scope_id;
+    SemIR::SpecificId specific_id;
 
 
     // The prefix emitted before this name component. If '\0', no prefix will be
     // The prefix emitted before this name component. If '\0', no prefix will be
     // emitted.
     // emitted.
@@ -37,9 +39,11 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
     char prefix;
     char prefix;
   };
   };
   llvm::SmallVector<NameEntry> names_to_render;
   llvm::SmallVector<NameEntry> names_to_render;
-  names_to_render.push_back({.name_scope_id = name_scope_id, .prefix = '.'});
+  names_to_render.push_back({.name_scope_id = name_scope_id,
+                             .specific_id = SemIR::SpecificId::None,
+                             .prefix = '.'});
   while (!names_to_render.empty()) {
   while (!names_to_render.empty()) {
-    auto [name_scope_id, prefix] = names_to_render.pop_back_val();
+    auto [name_scope_id, specific_id, prefix] = names_to_render.pop_back_val();
     if (prefix) {
     if (prefix) {
       os << prefix;
       os << prefix;
     }
     }
@@ -70,8 +74,9 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
         auto interface_type = facet_type_info.extend_constraints.front();
         auto interface_type = facet_type_info.extend_constraints.front();
         const auto& interface =
         const auto& interface =
             sem_ir().interfaces().Get(interface_type.interface_id);
             sem_ir().interfaces().Get(interface_type.interface_id);
-        names_to_render.push_back(
-            {.name_scope_id = interface.scope_id, .prefix = ':'});
+        names_to_render.push_back({.name_scope_id = interface.scope_id,
+                                   .specific_id = interface_type.specific_id,
+                                   .prefix = ':'});
 
 
         auto self_const_inst_id =
         auto self_const_inst_id =
             constant_values().GetConstantInstId(impl.self_id);
             constant_values().GetConstantInstId(impl.self_id);
@@ -80,8 +85,9 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
           case CARBON_KIND(SemIR::ClassType class_type): {
           case CARBON_KIND(SemIR::ClassType class_type): {
             auto next_name_scope_id =
             auto next_name_scope_id =
                 sem_ir().classes().Get(class_type.class_id).scope_id;
                 sem_ir().classes().Get(class_type.class_id).scope_id;
-            names_to_render.push_back(
-                {.name_scope_id = next_name_scope_id, .prefix = '\0'});
+            names_to_render.push_back({.name_scope_id = next_name_scope_id,
+                                       .specific_id = class_type.specific_id,
+                                       .prefix = '\0'});
             break;
             break;
           }
           }
           case SemIR::AutoType::Kind:
           case SemIR::AutoType::Kind:
@@ -123,11 +129,13 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
       }
       }
       case CARBON_KIND(SemIR::ClassDecl class_decl): {
       case CARBON_KIND(SemIR::ClassDecl class_decl): {
         MangleNameId(os, sem_ir().classes().Get(class_decl.class_id).name_id);
         MangleNameId(os, sem_ir().classes().Get(class_decl.class_id).name_id);
+        MangleSpecificId(os, specific_id);
         break;
         break;
       }
       }
       case CARBON_KIND(SemIR::InterfaceDecl interface_decl): {
       case CARBON_KIND(SemIR::InterfaceDecl interface_decl): {
         MangleNameId(
         MangleNameId(
             os, sem_ir().interfaces().Get(interface_decl.interface_id).name_id);
             os, sem_ir().interfaces().Get(interface_decl.interface_id).name_id);
+        MangleSpecificId(os, specific_id);
         break;
         break;
       }
       }
       case SemIR::Namespace::Kind: {
       case SemIR::Namespace::Kind: {
@@ -139,8 +147,9 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os,
         break;
         break;
     }
     }
     if (!name_scope.is_imported_package()) {
     if (!name_scope.is_imported_package()) {
-      names_to_render.push_back(
-          {.name_scope_id = name_scope.parent_scope_id(), .prefix = '.'});
+      names_to_render.push_back({.name_scope_id = name_scope.parent_scope_id(),
+                                 .specific_id = SemIR::SpecificId::None,
+                                 .prefix = '.'});
     }
     }
   }
   }
 }
 }

+ 9 - 9
toolchain/lower/testdata/array/iterate.carbon

@@ -78,7 +78,7 @@ fn F() {
 // CHECK:STDOUT:   br i1 %2, label %3, label %7, !dbg !28
 // CHECK:STDOUT:   br i1 %2, label %3, label %7, !dbg !28
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: 3:                                                ; preds = %0
 // CHECK:STDOUT: 3:                                                ; preds = %0
-// CHECK:STDOUT:   call void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %cursor), !dbg !29
+// CHECK:STDOUT:   call void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %cursor), !dbg !29
 // CHECK:STDOUT:   %4 = load i32, ptr %cursor, align 4, !dbg !30
 // CHECK:STDOUT:   %4 = load i32, ptr %cursor, align 4, !dbg !30
 // CHECK:STDOUT:   %5 = sub i32 %4, 1, !dbg !30
 // CHECK:STDOUT:   %5 = sub i32 %4, 1, !dbg !30
 // CHECK:STDOUT:   %array.index = getelementptr inbounds [6 x i32], ptr %self, i32 0, i32 %5, !dbg !31
 // CHECK:STDOUT:   %array.index = getelementptr inbounds [6 x i32], ptr %self, i32 0, i32 %5, !dbg !31
@@ -104,8 +104,8 @@ fn F() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !49 {
-// CHECK:STDOUT:   call void @"_COp:thunk.Int.Core:AddAssignWith.Core.dcdd24268af36579"(ptr %self, i32 1), !dbg !55
+// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !49 {
+// CHECK:STDOUT:   call void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.e2da7149b7fcf782.Core.dcdd24268af36579"(ptr %self, i32 1), !dbg !55
 // CHECK:STDOUT:   ret void, !dbg !56
 // CHECK:STDOUT:   ret void, !dbg !56
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -137,8 +137,8 @@ fn F() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.Core:AddAssignWith.Core.dcdd24268af36579"(ptr %self, i32 %other) #3 !dbg !79 {
-// CHECK:STDOUT:   %1 = call i32 @"_CConvert.1e58d10da180d7d9:ImplicitAs.Core.255ef555a3d2f793"(i32 %other), !dbg !85
+// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.e2da7149b7fcf782.Core.dcdd24268af36579"(ptr %self, i32 %other) #3 !dbg !79 {
+// CHECK:STDOUT:   %1 = call i32 @"_CConvert.1e58d10da180d7d9:ImplicitAs.39e2e54f50ee65cc.Core.255ef555a3d2f793"(i32 %other), !dbg !85
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !86
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !86
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !86
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !86
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !86
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !86
@@ -162,7 +162,7 @@ fn F() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.1e58d10da180d7d9:ImplicitAs.Core.255ef555a3d2f793"(i32 %self) #0 !dbg !96 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.1e58d10da180d7d9:ImplicitAs.39e2e54f50ee65cc.Core.255ef555a3d2f793"(i32 %self) #0 !dbg !96 {
 // CHECK:STDOUT:   ret i32 %self, !dbg !102
 // CHECK:STDOUT:   ret i32 %self, !dbg !102
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -226,7 +226,7 @@ fn F() {
 // CHECK:STDOUT: !46 = !DILocalVariable(arg: 1, scope: !44, type: !17)
 // CHECK:STDOUT: !46 = !DILocalVariable(arg: 1, scope: !44, type: !17)
 // CHECK:STDOUT: !47 = !DILocation(line: 36, column: 12, scope: !44)
 // CHECK:STDOUT: !47 = !DILocation(line: 36, column: 12, scope: !44)
 // CHECK:STDOUT: !48 = !DILocation(line: 36, column: 5, scope: !44)
 // CHECK:STDOUT: !48 = !DILocation(line: 36, column: 5, scope: !44)
-// CHECK:STDOUT: !49 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !50, line: 339, type: !51, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !53)
+// CHECK:STDOUT: !49 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !50, line: 339, type: !51, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !53)
 // CHECK:STDOUT: !50 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !50 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !51 = !DISubroutineType(types: !52)
 // CHECK:STDOUT: !51 = !DISubroutineType(types: !52)
 // CHECK:STDOUT: !52 = !{null, !16}
 // CHECK:STDOUT: !52 = !{null, !16}
@@ -256,7 +256,7 @@ fn F() {
 // CHECK:STDOUT: !76 = !DILocalVariable(arg: 1, scope: !74, type: !17)
 // CHECK:STDOUT: !76 = !DILocalVariable(arg: 1, scope: !74, type: !17)
 // CHECK:STDOUT: !77 = !DILocation(line: 116, column: 12, scope: !74)
 // CHECK:STDOUT: !77 = !DILocation(line: 116, column: 12, scope: !74)
 // CHECK:STDOUT: !78 = !DILocation(line: 116, column: 5, scope: !74)
 // CHECK:STDOUT: !78 = !DILocation(line: 116, column: 5, scope: !74)
-// CHECK:STDOUT: !79 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.dcdd24268af36579", scope: null, file: !50, line: 275, type: !80, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !82)
+// CHECK:STDOUT: !79 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.e2da7149b7fcf782.Core.dcdd24268af36579", scope: null, file: !50, line: 275, type: !80, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !82)
 // CHECK:STDOUT: !80 = !DISubroutineType(types: !81)
 // CHECK:STDOUT: !80 = !DISubroutineType(types: !81)
 // CHECK:STDOUT: !81 = !{null, !16, !16}
 // CHECK:STDOUT: !81 = !{null, !16, !16}
 // CHECK:STDOUT: !82 = !{!83, !84}
 // CHECK:STDOUT: !82 = !{!83, !84}
@@ -273,7 +273,7 @@ fn F() {
 // CHECK:STDOUT: !93 = distinct !DISubprogram(name: "None", linkageName: "_CNone.3e8267224c5dc9c2:OptionalStorage.Core.329e9a7481f16207", scope: null, file: !37, line: 99, type: !65, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !93 = distinct !DISubprogram(name: "None", linkageName: "_CNone.3e8267224c5dc9c2:OptionalStorage.Core.329e9a7481f16207", scope: null, file: !37, line: 99, type: !65, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !94 = !DILocation(line: 101, column: 5, scope: !93)
 // CHECK:STDOUT: !94 = !DILocation(line: 101, column: 5, scope: !93)
 // CHECK:STDOUT: !95 = !DILocation(line: 102, column: 5, scope: !93)
 // CHECK:STDOUT: !95 = !DILocation(line: 102, column: 5, scope: !93)
-// CHECK:STDOUT: !96 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.1e58d10da180d7d9:ImplicitAs.Core.255ef555a3d2f793", scope: null, file: !97, line: 24, type: !98, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !100)
+// CHECK:STDOUT: !96 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.1e58d10da180d7d9:ImplicitAs.39e2e54f50ee65cc.Core.255ef555a3d2f793", scope: null, file: !97, line: 24, type: !98, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !100)
 // CHECK:STDOUT: !97 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !97 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !98 = !DISubroutineType(types: !99)
 // CHECK:STDOUT: !98 = !DISubroutineType(types: !99)
 // CHECK:STDOUT: !99 = !{!16, !16}
 // CHECK:STDOUT: !99 = !{!16, !16}

+ 3 - 3
toolchain/lower/testdata/class/convert.carbon

@@ -31,7 +31,7 @@ fn DoIt() {
 // CHECK:STDOUT: @IntWrapper.val.loc24_3 = internal constant { i32 } { i32 42 }
 // CHECK:STDOUT: @IntWrapper.val.loc24_3 = internal constant { i32 } { i32 42 }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @"_CConvert.IntWrapper.Main:ImplicitAs.Core"(ptr %self) #0 !dbg !4 {
+// CHECK:STDOUT: define i32 @"_CConvert.IntWrapper.Main:ImplicitAs.b88d1103f417c6d4.Core"(ptr %self) #0 !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc18_48.1.n = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !11
 // CHECK:STDOUT:   %.loc18_48.1.n = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !11
 // CHECK:STDOUT:   %.loc18_48.2 = load i32, ptr %.loc18_48.1.n, align 4, !dbg !11
 // CHECK:STDOUT:   %.loc18_48.2 = load i32, ptr %.loc18_48.1.n, align 4, !dbg !11
@@ -51,7 +51,7 @@ fn DoIt() {
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %w.var), !dbg !22
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %w.var), !dbg !22
 // CHECK:STDOUT:   %.loc24_31.3.n = getelementptr inbounds nuw { i32 }, ptr %w.var, i32 0, i32 0, !dbg !23
 // CHECK:STDOUT:   %.loc24_31.3.n = getelementptr inbounds nuw { i32 }, ptr %w.var, i32 0, i32 0, !dbg !23
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %w.var, ptr align 4 @IntWrapper.val.loc24_3, i64 4, i1 false), !dbg !22
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %w.var, ptr align 4 @IntWrapper.val.loc24_3, i64 4, i1 false), !dbg !22
-// CHECK:STDOUT:   %IntWrapper.as.ImplicitAs.impl.Convert.call = call i32 @"_CConvert.IntWrapper.Main:ImplicitAs.Core"(ptr %w.var), !dbg !24
+// CHECK:STDOUT:   %IntWrapper.as.ImplicitAs.impl.Convert.call = call i32 @"_CConvert.IntWrapper.Main:ImplicitAs.b88d1103f417c6d4.Core"(ptr %w.var), !dbg !24
 // CHECK:STDOUT:   call void @_CConsume.Main(i32 %IntWrapper.as.ImplicitAs.impl.Convert.call), !dbg !25
 // CHECK:STDOUT:   call void @_CConsume.Main(i32 %IntWrapper.as.ImplicitAs.impl.Convert.call), !dbg !25
 // CHECK:STDOUT:   ret void, !dbg !26
 // CHECK:STDOUT:   ret void, !dbg !26
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
@@ -73,7 +73,7 @@ fn DoIt() {
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "convert.carbon", directory: "")
 // CHECK:STDOUT: !3 = !DIFile(filename: "convert.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.IntWrapper.Main:ImplicitAs.Core", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !9)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.IntWrapper.Main:ImplicitAs.b88d1103f417c6d4.Core", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !9)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{!7, !8}
 // CHECK:STDOUT: !6 = !{!7, !8}
 // CHECK:STDOUT: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 // CHECK:STDOUT: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)

+ 6 - 6
toolchain/lower/testdata/for/bindings.carbon

@@ -48,13 +48,13 @@ fn For() {
 // CHECK:STDOUT:   %.loc29_33.8.temp = alloca { i32, i32 }, align 8, !dbg !8
 // CHECK:STDOUT:   %.loc29_33.8.temp = alloca { i32, i32 }, align 8, !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %r.var), !dbg !7
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %r.var), !dbg !7
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %r.var, ptr align 1 @EmptyRange.val.loc27_3, i64 0, i1 false), !dbg !7
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %r.var, ptr align 1 @EmptyRange.val.loc27_3, i64 0, i1 false), !dbg !7
-// CHECK:STDOUT:   call void @"_CNewCursor.EmptyRange.Main:Iterate.Core.c6c37881d2ed7d9d"(ptr %r.var), !dbg !8
+// CHECK:STDOUT:   call void @"_CNewCursor.EmptyRange.1ccc388edee5a786.Main:Iterate.Core.c6c37881d2ed7d9d"(ptr %r.var), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %var), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %var), !dbg !8
 // CHECK:STDOUT:   br label %for.next, !dbg !8
 // CHECK:STDOUT:   br label %for.next, !dbg !8
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: for.next:                                         ; preds = %for.body, %entry
 // CHECK:STDOUT: for.next:                                         ; preds = %for.body, %entry
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc29_33.1.temp), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc29_33.1.temp), !dbg !8
-// CHECK:STDOUT:   call void @"_CNext.EmptyRange.Main:Iterate.Core.c6c37881d2ed7d9d"(ptr %.loc29_33.1.temp, ptr %r.var, ptr %var), !dbg !8
+// CHECK:STDOUT:   call void @"_CNext.EmptyRange.1ccc388edee5a786.Main:Iterate.Core.c6c37881d2ed7d9d"(ptr %.loc29_33.1.temp, ptr %r.var, ptr %var), !dbg !8
 // CHECK:STDOUT:   %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.eeebe1ada0072aea(ptr %.loc29_33.1.temp), !dbg !8
 // CHECK:STDOUT:   %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.eeebe1ada0072aea(ptr %.loc29_33.1.temp), !dbg !8
 // CHECK:STDOUT:   br i1 %Optional.HasValue.call, label %for.body, label %for.done, !dbg !8
 // CHECK:STDOUT:   br i1 %Optional.HasValue.call, label %for.body, label %for.done, !dbg !8
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -81,13 +81,13 @@ fn For() {
 // CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #2
 // CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #2
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CNewCursor.EmptyRange.Main:Iterate.Core.c6c37881d2ed7d9d"(ptr %self) #0 !dbg !13 {
+// CHECK:STDOUT: define linkonce_odr void @"_CNewCursor.EmptyRange.1ccc388edee5a786.Main:Iterate.Core.c6c37881d2ed7d9d"(ptr %self) #0 !dbg !13 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   ret void, !dbg !19
 // CHECK:STDOUT:   ret void, !dbg !19
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CNext.EmptyRange.Main:Iterate.Core.c6c37881d2ed7d9d"(ptr sret({ { i32, i32 }, i1 }) %return, ptr %self, ptr %_) #0 !dbg !20 {
+// CHECK:STDOUT: define linkonce_odr void @"_CNext.EmptyRange.1ccc388edee5a786.Main:Iterate.Core.c6c37881d2ed7d9d"(ptr sret({ { i32, i32 }, i1 }) %return, ptr %self, ptr %_) #0 !dbg !20 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   call void @_CNone.Optional.Core.eeebe1ada0072aea(ptr %return), !dbg !26
 // CHECK:STDOUT:   call void @_CNone.Optional.Core.eeebe1ada0072aea(ptr %return), !dbg !26
 // CHECK:STDOUT:   ret void, !dbg !27
 // CHECK:STDOUT:   ret void, !dbg !27
@@ -169,14 +169,14 @@ fn For() {
 // CHECK:STDOUT: !10 = !DILocation(line: 30, column: 5, scope: !4)
 // CHECK:STDOUT: !10 = !DILocation(line: 30, column: 5, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 29, column: 3, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 29, column: 3, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 26, column: 1, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 26, column: 1, scope: !4)
-// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "NewCursor", linkageName: "_CNewCursor.EmptyRange.Main:Iterate.Core.c6c37881d2ed7d9d", scope: null, file: !3, line: 15, type: !14, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17)
+// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "NewCursor", linkageName: "_CNewCursor.EmptyRange.1ccc388edee5a786.Main:Iterate.Core.c6c37881d2ed7d9d", scope: null, file: !3, line: 15, type: !14, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17)
 // CHECK:STDOUT: !14 = !DISubroutineType(types: !15)
 // CHECK:STDOUT: !14 = !DISubroutineType(types: !15)
 // CHECK:STDOUT: !15 = !{!16, !16}
 // CHECK:STDOUT: !15 = !{!16, !16}
 // CHECK:STDOUT: !16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
 // CHECK:STDOUT: !16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
 // CHECK:STDOUT: !17 = !{!18}
 // CHECK:STDOUT: !17 = !{!18}
 // CHECK:STDOUT: !18 = !DILocalVariable(arg: 1, scope: !13, type: !16)
 // CHECK:STDOUT: !18 = !DILocalVariable(arg: 1, scope: !13, type: !16)
 // CHECK:STDOUT: !19 = !DILocation(line: 16, column: 7, scope: !13)
 // CHECK:STDOUT: !19 = !DILocation(line: 16, column: 7, scope: !13)
-// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "Next", linkageName: "_CNext.EmptyRange.Main:Iterate.Core.c6c37881d2ed7d9d", scope: null, file: !3, line: 18, type: !21, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !23)
+// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "Next", linkageName: "_CNext.EmptyRange.1ccc388edee5a786.Main:Iterate.Core.c6c37881d2ed7d9d", scope: null, file: !3, line: 18, type: !21, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !23)
 // CHECK:STDOUT: !21 = !DISubroutineType(types: !22)
 // CHECK:STDOUT: !21 = !DISubroutineType(types: !22)
 // CHECK:STDOUT: !22 = !{!16, !16, !16}
 // CHECK:STDOUT: !22 = !{!16, !16, !16}
 // CHECK:STDOUT: !23 = !{!24, !25}
 // CHECK:STDOUT: !23 = !{!24, !25}

+ 15 - 15
toolchain/lower/testdata/for/break_continue.carbon

@@ -41,14 +41,14 @@ fn For() {
 // CHECK:STDOUT:   %.loc20_33.1.temp = alloca { i32, i1 }, align 8, !dbg !8
 // CHECK:STDOUT:   %.loc20_33.1.temp = alloca { i32, i1 }, align 8, !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_32.1.temp), !dbg !7
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_32.1.temp), !dbg !7
 // CHECK:STDOUT:   call void @_CRange.Core(ptr %.loc20_32.1.temp, i32 100), !dbg !7
 // CHECK:STDOUT:   call void @_CRange.Core(ptr %.loc20_32.1.temp, i32 100), !dbg !7
-// CHECK:STDOUT:   %IntRange.as.Iterate.impl.NewCursor.call = call i32 @"_CNewCursor.IntRange.Core:Iterate.Core.be1e879c1ad406d8"(ptr %.loc20_32.1.temp), !dbg !8
+// CHECK:STDOUT:   %IntRange.as.Iterate.impl.NewCursor.call = call i32 @"_CNewCursor.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8"(ptr %.loc20_32.1.temp), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %var), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %var), !dbg !8
 // CHECK:STDOUT:   store i32 %IntRange.as.Iterate.impl.NewCursor.call, ptr %var, align 4, !dbg !8
 // CHECK:STDOUT:   store i32 %IntRange.as.Iterate.impl.NewCursor.call, ptr %var, align 4, !dbg !8
 // CHECK:STDOUT:   br label %for.next, !dbg !8
 // CHECK:STDOUT:   br label %for.next, !dbg !8
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: for.next:                                         ; preds = %if.else.loc22, %if.then.loc22, %entry
 // CHECK:STDOUT: for.next:                                         ; preds = %if.else.loc22, %if.then.loc22, %entry
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_33.1.temp), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_33.1.temp), !dbg !8
-// CHECK:STDOUT:   call void @"_CNext.IntRange.Core:Iterate.Core.be1e879c1ad406d8"(ptr %.loc20_33.1.temp, ptr %.loc20_32.1.temp, ptr %var), !dbg !8
+// CHECK:STDOUT:   call void @"_CNext.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8"(ptr %.loc20_33.1.temp, ptr %.loc20_32.1.temp, ptr %var), !dbg !8
 // CHECK:STDOUT:   %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.a88acd4c94838316(ptr %.loc20_33.1.temp), !dbg !8
 // CHECK:STDOUT:   %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.a88acd4c94838316(ptr %.loc20_33.1.temp), !dbg !8
 // CHECK:STDOUT:   br i1 %Optional.HasValue.call, label %for.body, label %for.done, !dbg !8
 // CHECK:STDOUT:   br i1 %Optional.HasValue.call, label %for.body, label %for.done, !dbg !8
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -81,14 +81,14 @@ fn For() {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr i32 @"_CNewCursor.IntRange.Core:Iterate.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !18 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CNewCursor.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !18 {
 // CHECK:STDOUT:   %start = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 0, !dbg !26
 // CHECK:STDOUT:   %start = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 0, !dbg !26
 // CHECK:STDOUT:   %1 = load i32, ptr %start, align 4, !dbg !26
 // CHECK:STDOUT:   %1 = load i32, ptr %start, align 4, !dbg !26
 // CHECK:STDOUT:   ret i32 %1, !dbg !27
 // CHECK:STDOUT:   ret i32 %1, !dbg !27
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CNext.IntRange.Core:Iterate.Core.be1e879c1ad406d8"(ptr sret({ i32, i1 }) %return, ptr %self, ptr %cursor) #0 !dbg !28 {
+// CHECK:STDOUT: define linkonce_odr void @"_CNext.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8"(ptr sret({ i32, i1 }) %return, ptr %self, ptr %cursor) #0 !dbg !28 {
 // CHECK:STDOUT:   %1 = alloca i32, align 4, !dbg !34
 // CHECK:STDOUT:   %1 = alloca i32, align 4, !dbg !34
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %1), !dbg !34
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %1), !dbg !34
 // CHECK:STDOUT:   %2 = load i32, ptr %cursor, align 4, !dbg !35
 // CHECK:STDOUT:   %2 = load i32, ptr %cursor, align 4, !dbg !35
@@ -100,7 +100,7 @@ fn For() {
 // CHECK:STDOUT:   br i1 %5, label %6, label %8, !dbg !38
 // CHECK:STDOUT:   br i1 %5, label %6, label %8, !dbg !38
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: 6:                                                ; preds = %0
 // CHECK:STDOUT: 6:                                                ; preds = %0
-// CHECK:STDOUT:   call void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %cursor), !dbg !39
+// CHECK:STDOUT:   call void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %cursor), !dbg !39
 // CHECK:STDOUT:   %7 = load i32, ptr %1, align 4, !dbg !40
 // CHECK:STDOUT:   %7 = load i32, ptr %1, align 4, !dbg !40
 // CHECK:STDOUT:   call void @_CSome.Optional.Core.a88acd4c94838316(ptr %return, i32 %7), !dbg !41
 // CHECK:STDOUT:   call void @_CSome.Optional.Core.a88acd4c94838316(ptr %return, i32 %7), !dbg !41
 // CHECK:STDOUT:   ret void, !dbg !42
 // CHECK:STDOUT:   ret void, !dbg !42
@@ -125,8 +125,8 @@ fn For() {
 // CHECK:STDOUT: declare void @_CInclusiveRange.Core(ptr sret({ i32, i32 }), i32, i32)
 // CHECK:STDOUT: declare void @_CInclusiveRange.Core(ptr sret({ i32, i32 }), i32, i32)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !58 {
-// CHECK:STDOUT:   call void @"_COp:thunk.Int.Core:AddAssignWith.Core.cfd8ddddc59ca787"(ptr %self, i32 1), !dbg !64
+// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !58 {
+// CHECK:STDOUT:   call void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.cfd8ddddc59ca787"(ptr %self, i32 1), !dbg !64
 // CHECK:STDOUT:   ret void, !dbg !65
 // CHECK:STDOUT:   ret void, !dbg !65
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -158,8 +158,8 @@ fn For() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.Core:AddAssignWith.Core.cfd8ddddc59ca787"(ptr %self, i32 %other) #2 !dbg !88 {
-// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.beca8a3ca33a86fb"(i32 %other), !dbg !94
+// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.cfd8ddddc59ca787"(ptr %self, i32 %other) #2 !dbg !88 {
+// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.beca8a3ca33a86fb"(i32 %other), !dbg !94
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !95
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !95
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !95
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !95
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !95
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !95
@@ -183,7 +183,7 @@ fn For() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.beca8a3ca33a86fb"(i32 %self) #0 !dbg !105 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.beca8a3ca33a86fb"(i32 %self) #0 !dbg !105 {
 // CHECK:STDOUT:   ret i32 %self, !dbg !111
 // CHECK:STDOUT:   ret i32 %self, !dbg !111
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -215,7 +215,7 @@ fn For() {
 // CHECK:STDOUT: !15 = !DILocation(line: 23, column: 5, scope: !4)
 // CHECK:STDOUT: !15 = !DILocation(line: 23, column: 5, scope: !4)
 // CHECK:STDOUT: !16 = !DILocation(line: 20, column: 3, scope: !4)
 // CHECK:STDOUT: !16 = !DILocation(line: 20, column: 3, scope: !4)
 // CHECK:STDOUT: !17 = !DILocation(line: 19, column: 1, scope: !4)
 // CHECK:STDOUT: !17 = !DILocation(line: 19, column: 1, scope: !4)
-// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "NewCursor", linkageName: "_CNewCursor.IntRange.Core:Iterate.Core.be1e879c1ad406d8", scope: null, file: !19, line: 25, type: !20, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !24)
+// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "NewCursor", linkageName: "_CNewCursor.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8", scope: null, file: !19, line: 25, type: !20, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !24)
 // CHECK:STDOUT: !19 = !DIFile(filename: "{{.*}}/range.carbon", directory: "")
 // CHECK:STDOUT: !19 = !DIFile(filename: "{{.*}}/range.carbon", directory: "")
 // CHECK:STDOUT: !20 = !DISubroutineType(types: !21)
 // CHECK:STDOUT: !20 = !DISubroutineType(types: !21)
 // CHECK:STDOUT: !21 = !{!22, !23}
 // CHECK:STDOUT: !21 = !{!22, !23}
@@ -225,7 +225,7 @@ fn For() {
 // CHECK:STDOUT: !25 = !DILocalVariable(arg: 1, scope: !18, type: !23)
 // CHECK:STDOUT: !25 = !DILocalVariable(arg: 1, scope: !18, type: !23)
 // CHECK:STDOUT: !26 = !DILocation(line: 25, column: 51, scope: !18)
 // CHECK:STDOUT: !26 = !DILocation(line: 25, column: 51, scope: !18)
 // CHECK:STDOUT: !27 = !DILocation(line: 25, column: 44, scope: !18)
 // CHECK:STDOUT: !27 = !DILocation(line: 25, column: 44, scope: !18)
-// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "Next", linkageName: "_CNext.IntRange.Core:Iterate.Core.be1e879c1ad406d8", scope: null, file: !19, line: 26, type: !29, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !31)
+// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "Next", linkageName: "_CNext.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8", scope: null, file: !19, line: 26, type: !29, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !31)
 // CHECK:STDOUT: !29 = !DISubroutineType(types: !30)
 // CHECK:STDOUT: !29 = !DISubroutineType(types: !30)
 // CHECK:STDOUT: !30 = !{!23, !23, !23}
 // CHECK:STDOUT: !30 = !{!23, !23, !23}
 // CHECK:STDOUT: !31 = !{!32, !33}
 // CHECK:STDOUT: !31 = !{!32, !33}
@@ -255,7 +255,7 @@ fn For() {
 // CHECK:STDOUT: !55 = !DILocalVariable(arg: 1, scope: !53, type: !23)
 // CHECK:STDOUT: !55 = !DILocalVariable(arg: 1, scope: !53, type: !23)
 // CHECK:STDOUT: !56 = !DILocation(line: 36, column: 12, scope: !53)
 // CHECK:STDOUT: !56 = !DILocation(line: 36, column: 12, scope: !53)
 // CHECK:STDOUT: !57 = !DILocation(line: 36, column: 5, scope: !53)
 // CHECK:STDOUT: !57 = !DILocation(line: 36, column: 5, scope: !53)
-// CHECK:STDOUT: !58 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !59, line: 339, type: !60, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !62)
+// CHECK:STDOUT: !58 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !59, line: 339, type: !60, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !62)
 // CHECK:STDOUT: !59 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !59 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !60 = !DISubroutineType(types: !61)
 // CHECK:STDOUT: !60 = !DISubroutineType(types: !61)
 // CHECK:STDOUT: !61 = !{null, !22}
 // CHECK:STDOUT: !61 = !{null, !22}
@@ -285,7 +285,7 @@ fn For() {
 // CHECK:STDOUT: !85 = !DILocalVariable(arg: 1, scope: !83, type: !23)
 // CHECK:STDOUT: !85 = !DILocalVariable(arg: 1, scope: !83, type: !23)
 // CHECK:STDOUT: !86 = !DILocation(line: 116, column: 12, scope: !83)
 // CHECK:STDOUT: !86 = !DILocation(line: 116, column: 12, scope: !83)
 // CHECK:STDOUT: !87 = !DILocation(line: 116, column: 5, scope: !83)
 // CHECK:STDOUT: !87 = !DILocation(line: 116, column: 5, scope: !83)
-// CHECK:STDOUT: !88 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.cfd8ddddc59ca787", scope: null, file: !59, line: 275, type: !89, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !91)
+// CHECK:STDOUT: !88 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.cfd8ddddc59ca787", scope: null, file: !59, line: 275, type: !89, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !91)
 // CHECK:STDOUT: !89 = !DISubroutineType(types: !90)
 // CHECK:STDOUT: !89 = !DISubroutineType(types: !90)
 // CHECK:STDOUT: !90 = !{null, !22, !22}
 // CHECK:STDOUT: !90 = !{null, !22, !22}
 // CHECK:STDOUT: !91 = !{!92, !93}
 // CHECK:STDOUT: !91 = !{!92, !93}
@@ -302,7 +302,7 @@ fn For() {
 // CHECK:STDOUT: !102 = distinct !DISubprogram(name: "None", linkageName: "_CNone.3e8267224c5dc9c2:OptionalStorage.Core.32fa7206ac42c9b7", scope: null, file: !46, line: 99, type: !74, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !102 = distinct !DISubprogram(name: "None", linkageName: "_CNone.3e8267224c5dc9c2:OptionalStorage.Core.32fa7206ac42c9b7", scope: null, file: !46, line: 99, type: !74, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !103 = !DILocation(line: 101, column: 5, scope: !102)
 // CHECK:STDOUT: !103 = !DILocation(line: 101, column: 5, scope: !102)
 // CHECK:STDOUT: !104 = !DILocation(line: 102, column: 5, scope: !102)
 // CHECK:STDOUT: !104 = !DILocation(line: 102, column: 5, scope: !102)
-// CHECK:STDOUT: !105 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.Core.beca8a3ca33a86fb", scope: null, file: !106, line: 24, type: !107, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !109)
+// CHECK:STDOUT: !105 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.beca8a3ca33a86fb", scope: null, file: !106, line: 24, type: !107, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !109)
 // CHECK:STDOUT: !106 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !106 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !107 = !DISubroutineType(types: !108)
 // CHECK:STDOUT: !107 = !DISubroutineType(types: !108)
 // CHECK:STDOUT: !108 = !{!22, !22}
 // CHECK:STDOUT: !108 = !{!22, !22}

+ 15 - 15
toolchain/lower/testdata/for/for.carbon

@@ -42,14 +42,14 @@ fn For() {
 // CHECK:STDOUT:   call void @_CF.Main(), !dbg !9
 // CHECK:STDOUT:   call void @_CF.Main(), !dbg !9
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc21_32.1.temp), !dbg !7
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc21_32.1.temp), !dbg !7
 // CHECK:STDOUT:   call void @_CRange.Core(ptr %.loc21_32.1.temp, i32 100), !dbg !7
 // CHECK:STDOUT:   call void @_CRange.Core(ptr %.loc21_32.1.temp, i32 100), !dbg !7
-// CHECK:STDOUT:   %IntRange.as.Iterate.impl.NewCursor.call = call i32 @"_CNewCursor.IntRange.Core:Iterate.Core.be1e879c1ad406d8"(ptr %.loc21_32.1.temp), !dbg !8
+// CHECK:STDOUT:   %IntRange.as.Iterate.impl.NewCursor.call = call i32 @"_CNewCursor.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8"(ptr %.loc21_32.1.temp), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %var), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %var), !dbg !8
 // CHECK:STDOUT:   store i32 %IntRange.as.Iterate.impl.NewCursor.call, ptr %var, align 4, !dbg !8
 // CHECK:STDOUT:   store i32 %IntRange.as.Iterate.impl.NewCursor.call, ptr %var, align 4, !dbg !8
 // CHECK:STDOUT:   br label %for.next, !dbg !8
 // CHECK:STDOUT:   br label %for.next, !dbg !8
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: for.next:                                         ; preds = %for.body, %entry
 // CHECK:STDOUT: for.next:                                         ; preds = %for.body, %entry
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc21_33.1.temp), !dbg !8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc21_33.1.temp), !dbg !8
-// CHECK:STDOUT:   call void @"_CNext.IntRange.Core:Iterate.Core.be1e879c1ad406d8"(ptr %.loc21_33.1.temp, ptr %.loc21_32.1.temp, ptr %var), !dbg !8
+// CHECK:STDOUT:   call void @"_CNext.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8"(ptr %.loc21_33.1.temp, ptr %.loc21_32.1.temp, ptr %var), !dbg !8
 // CHECK:STDOUT:   %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.a88acd4c94838316(ptr %.loc21_33.1.temp), !dbg !8
 // CHECK:STDOUT:   %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.a88acd4c94838316(ptr %.loc21_33.1.temp), !dbg !8
 // CHECK:STDOUT:   br i1 %Optional.HasValue.call, label %for.body, label %for.done, !dbg !8
 // CHECK:STDOUT:   br i1 %Optional.HasValue.call, label %for.body, label %for.done, !dbg !8
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -69,14 +69,14 @@ fn For() {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr i32 @"_CNewCursor.IntRange.Core:Iterate.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !14 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CNewCursor.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !14 {
 // CHECK:STDOUT:   %start = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 0, !dbg !22
 // CHECK:STDOUT:   %start = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 0, !dbg !22
 // CHECK:STDOUT:   %1 = load i32, ptr %start, align 4, !dbg !22
 // CHECK:STDOUT:   %1 = load i32, ptr %start, align 4, !dbg !22
 // CHECK:STDOUT:   ret i32 %1, !dbg !23
 // CHECK:STDOUT:   ret i32 %1, !dbg !23
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CNext.IntRange.Core:Iterate.Core.be1e879c1ad406d8"(ptr sret({ i32, i1 }) %return, ptr %self, ptr %cursor) #0 !dbg !24 {
+// CHECK:STDOUT: define linkonce_odr void @"_CNext.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8"(ptr sret({ i32, i1 }) %return, ptr %self, ptr %cursor) #0 !dbg !24 {
 // CHECK:STDOUT:   %1 = alloca i32, align 4, !dbg !30
 // CHECK:STDOUT:   %1 = alloca i32, align 4, !dbg !30
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %1), !dbg !30
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %1), !dbg !30
 // CHECK:STDOUT:   %2 = load i32, ptr %cursor, align 4, !dbg !31
 // CHECK:STDOUT:   %2 = load i32, ptr %cursor, align 4, !dbg !31
@@ -88,7 +88,7 @@ fn For() {
 // CHECK:STDOUT:   br i1 %5, label %6, label %8, !dbg !34
 // CHECK:STDOUT:   br i1 %5, label %6, label %8, !dbg !34
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: 6:                                                ; preds = %0
 // CHECK:STDOUT: 6:                                                ; preds = %0
-// CHECK:STDOUT:   call void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %cursor), !dbg !35
+// CHECK:STDOUT:   call void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %cursor), !dbg !35
 // CHECK:STDOUT:   %7 = load i32, ptr %1, align 4, !dbg !36
 // CHECK:STDOUT:   %7 = load i32, ptr %1, align 4, !dbg !36
 // CHECK:STDOUT:   call void @_CSome.Optional.Core.a88acd4c94838316(ptr %return, i32 %7), !dbg !37
 // CHECK:STDOUT:   call void @_CSome.Optional.Core.a88acd4c94838316(ptr %return, i32 %7), !dbg !37
 // CHECK:STDOUT:   ret void, !dbg !38
 // CHECK:STDOUT:   ret void, !dbg !38
@@ -113,8 +113,8 @@ fn For() {
 // CHECK:STDOUT: declare void @_CInclusiveRange.Core(ptr sret({ i32, i32 }), i32, i32)
 // CHECK:STDOUT: declare void @_CInclusiveRange.Core(ptr sret({ i32, i32 }), i32, i32)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !54 {
-// CHECK:STDOUT:   call void @"_COp:thunk.Int.Core:AddAssignWith.Core.cfd8ddddc59ca787"(ptr %self, i32 1), !dbg !60
+// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !54 {
+// CHECK:STDOUT:   call void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.cfd8ddddc59ca787"(ptr %self, i32 1), !dbg !60
 // CHECK:STDOUT:   ret void, !dbg !61
 // CHECK:STDOUT:   ret void, !dbg !61
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -146,8 +146,8 @@ fn For() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.Core:AddAssignWith.Core.cfd8ddddc59ca787"(ptr %self, i32 %other) #2 !dbg !84 {
-// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.beca8a3ca33a86fb"(i32 %other), !dbg !90
+// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.cfd8ddddc59ca787"(ptr %self, i32 %other) #2 !dbg !84 {
+// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.beca8a3ca33a86fb"(i32 %other), !dbg !90
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !91
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !91
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !91
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !91
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !91
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !91
@@ -171,7 +171,7 @@ fn For() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.beca8a3ca33a86fb"(i32 %self) #0 !dbg !101 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.beca8a3ca33a86fb"(i32 %self) #0 !dbg !101 {
 // CHECK:STDOUT:   ret i32 %self, !dbg !107
 // CHECK:STDOUT:   ret i32 %self, !dbg !107
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -199,7 +199,7 @@ fn For() {
 // CHECK:STDOUT: !11 = !DILocation(line: 21, column: 3, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 21, column: 3, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 24, column: 3, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 24, column: 3, scope: !4)
 // CHECK:STDOUT: !13 = !DILocation(line: 19, column: 1, scope: !4)
 // CHECK:STDOUT: !13 = !DILocation(line: 19, column: 1, scope: !4)
-// CHECK:STDOUT: !14 = distinct !DISubprogram(name: "NewCursor", linkageName: "_CNewCursor.IntRange.Core:Iterate.Core.be1e879c1ad406d8", scope: null, file: !15, line: 25, type: !16, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !20)
+// CHECK:STDOUT: !14 = distinct !DISubprogram(name: "NewCursor", linkageName: "_CNewCursor.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8", scope: null, file: !15, line: 25, type: !16, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !20)
 // CHECK:STDOUT: !15 = !DIFile(filename: "{{.*}}/range.carbon", directory: "")
 // CHECK:STDOUT: !15 = !DIFile(filename: "{{.*}}/range.carbon", directory: "")
 // CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
 // CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
 // CHECK:STDOUT: !17 = !{!18, !19}
 // CHECK:STDOUT: !17 = !{!18, !19}
@@ -209,7 +209,7 @@ fn For() {
 // CHECK:STDOUT: !21 = !DILocalVariable(arg: 1, scope: !14, type: !19)
 // CHECK:STDOUT: !21 = !DILocalVariable(arg: 1, scope: !14, type: !19)
 // CHECK:STDOUT: !22 = !DILocation(line: 25, column: 51, scope: !14)
 // CHECK:STDOUT: !22 = !DILocation(line: 25, column: 51, scope: !14)
 // CHECK:STDOUT: !23 = !DILocation(line: 25, column: 44, scope: !14)
 // CHECK:STDOUT: !23 = !DILocation(line: 25, column: 44, scope: !14)
-// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "Next", linkageName: "_CNext.IntRange.Core:Iterate.Core.be1e879c1ad406d8", scope: null, file: !15, line: 26, type: !25, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !27)
+// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "Next", linkageName: "_CNext.IntRange.9452f4c51951679b.Core:Iterate.Core.be1e879c1ad406d8", scope: null, file: !15, line: 26, type: !25, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !27)
 // CHECK:STDOUT: !25 = !DISubroutineType(types: !26)
 // CHECK:STDOUT: !25 = !DISubroutineType(types: !26)
 // CHECK:STDOUT: !26 = !{!19, !19, !19}
 // CHECK:STDOUT: !26 = !{!19, !19, !19}
 // CHECK:STDOUT: !27 = !{!28, !29}
 // CHECK:STDOUT: !27 = !{!28, !29}
@@ -239,7 +239,7 @@ fn For() {
 // CHECK:STDOUT: !51 = !DILocalVariable(arg: 1, scope: !49, type: !19)
 // CHECK:STDOUT: !51 = !DILocalVariable(arg: 1, scope: !49, type: !19)
 // CHECK:STDOUT: !52 = !DILocation(line: 36, column: 12, scope: !49)
 // CHECK:STDOUT: !52 = !DILocation(line: 36, column: 12, scope: !49)
 // CHECK:STDOUT: !53 = !DILocation(line: 36, column: 5, scope: !49)
 // CHECK:STDOUT: !53 = !DILocation(line: 36, column: 5, scope: !49)
-// CHECK:STDOUT: !54 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !55, line: 339, type: !56, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !58)
+// CHECK:STDOUT: !54 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !55, line: 339, type: !56, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !58)
 // CHECK:STDOUT: !55 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !55 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !56 = !DISubroutineType(types: !57)
 // CHECK:STDOUT: !56 = !DISubroutineType(types: !57)
 // CHECK:STDOUT: !57 = !{null, !18}
 // CHECK:STDOUT: !57 = !{null, !18}
@@ -269,7 +269,7 @@ fn For() {
 // CHECK:STDOUT: !81 = !DILocalVariable(arg: 1, scope: !79, type: !19)
 // CHECK:STDOUT: !81 = !DILocalVariable(arg: 1, scope: !79, type: !19)
 // CHECK:STDOUT: !82 = !DILocation(line: 116, column: 12, scope: !79)
 // CHECK:STDOUT: !82 = !DILocation(line: 116, column: 12, scope: !79)
 // CHECK:STDOUT: !83 = !DILocation(line: 116, column: 5, scope: !79)
 // CHECK:STDOUT: !83 = !DILocation(line: 116, column: 5, scope: !79)
-// CHECK:STDOUT: !84 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.cfd8ddddc59ca787", scope: null, file: !55, line: 275, type: !85, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !87)
+// CHECK:STDOUT: !84 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.cfd8ddddc59ca787", scope: null, file: !55, line: 275, type: !85, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !87)
 // CHECK:STDOUT: !85 = !DISubroutineType(types: !86)
 // CHECK:STDOUT: !85 = !DISubroutineType(types: !86)
 // CHECK:STDOUT: !86 = !{null, !18, !18}
 // CHECK:STDOUT: !86 = !{null, !18, !18}
 // CHECK:STDOUT: !87 = !{!88, !89}
 // CHECK:STDOUT: !87 = !{!88, !89}
@@ -286,7 +286,7 @@ fn For() {
 // CHECK:STDOUT: !98 = distinct !DISubprogram(name: "None", linkageName: "_CNone.3e8267224c5dc9c2:OptionalStorage.Core.32fa7206ac42c9b7", scope: null, file: !42, line: 99, type: !70, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !98 = distinct !DISubprogram(name: "None", linkageName: "_CNone.3e8267224c5dc9c2:OptionalStorage.Core.32fa7206ac42c9b7", scope: null, file: !42, line: 99, type: !70, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !99 = !DILocation(line: 101, column: 5, scope: !98)
 // CHECK:STDOUT: !99 = !DILocation(line: 101, column: 5, scope: !98)
 // CHECK:STDOUT: !100 = !DILocation(line: 102, column: 5, scope: !98)
 // CHECK:STDOUT: !100 = !DILocation(line: 102, column: 5, scope: !98)
-// CHECK:STDOUT: !101 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.Core.beca8a3ca33a86fb", scope: null, file: !102, line: 24, type: !103, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !105)
+// CHECK:STDOUT: !101 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.beca8a3ca33a86fb", scope: null, file: !102, line: 24, type: !103, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !105)
 // CHECK:STDOUT: !102 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !102 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !103 = !DISubroutineType(types: !104)
 // CHECK:STDOUT: !103 = !DISubroutineType(types: !104)
 // CHECK:STDOUT: !104 = !{!18, !18}
 // CHECK:STDOUT: !104 = !{!18, !18}

+ 3 - 3
toolchain/lower/testdata/function/generic/call_impl_function.carbon

@@ -47,7 +47,7 @@ fn G() {
 // CHECK:STDOUT: source_filename = "call_impl_function.carbon"
 // CHECK:STDOUT: source_filename = "call_impl_function.carbon"
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @"_CF.ImplsSomeInterface.Main:SomeInterface.Main"(i32 %x) #0 !dbg !4 {
+// CHECK:STDOUT: define i32 @"_CF.ImplsSomeInterface.Main:SomeInterface.b88d1103f417c6d4.Main"(i32 %x) #0 !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %Int.as.Negate.impl.Op.call = sub i32 0, %x, !dbg !10
 // CHECK:STDOUT:   %Int.as.Negate.impl.Op.call = sub i32 0, %x, !dbg !10
 // CHECK:STDOUT:   ret i32 %Int.as.Negate.impl.Op.call, !dbg !11
 // CHECK:STDOUT:   ret i32 %Int.as.Negate.impl.Op.call, !dbg !11
@@ -63,7 +63,7 @@ fn G() {
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define linkonce_odr i32 @_CCallGenericMethod.Main.416a86e385b6ba35(i32 %x) #0 !dbg !17 {
 // CHECK:STDOUT: define linkonce_odr i32 @_CCallGenericMethod.Main.416a86e385b6ba35(i32 %x) #0 !dbg !17 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %SomeInterface.F.call = call i32 @"_CF.ImplsSomeInterface.Main:SomeInterface.Main"(i32 %x), !dbg !20
+// CHECK:STDOUT:   %SomeInterface.F.call = call i32 @"_CF.ImplsSomeInterface.Main:SomeInterface.b88d1103f417c6d4.Main"(i32 %x), !dbg !20
 // CHECK:STDOUT:   ret i32 %SomeInterface.F.call, !dbg !21
 // CHECK:STDOUT:   ret i32 %SomeInterface.F.call, !dbg !21
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -76,7 +76,7 @@ fn G() {
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "call_impl_function.carbon", directory: "")
 // CHECK:STDOUT: !3 = !DIFile(filename: "call_impl_function.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.ImplsSomeInterface.Main:SomeInterface.Main", scope: null, file: !3, line: 22, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.ImplsSomeInterface.Main:SomeInterface.b88d1103f417c6d4.Main", scope: null, file: !3, line: 22, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 // CHECK:STDOUT: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)

+ 4 - 4
toolchain/lower/testdata/function/generic/type_representation.carbon

@@ -78,7 +78,7 @@ fn F_nested_tuple(a: ((i32, i32), X)) -> ((i32, i32), X) {
 // CHECK:STDOUT: source_filename = "type_representation.carbon"
 // CHECK:STDOUT: source_filename = "type_representation.carbon"
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define i32 @"_COp.Int.Core:Copy.Main"(i32 %self) #0 !dbg !4 {
+// CHECK:STDOUT: define i32 @"_COp.Int.be1e879c1ad406d8.Core:Copy.Main"(i32 %self) #0 !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   ret i32 %self, !dbg !10
 // CHECK:STDOUT:   ret i32 %self, !dbg !10
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
@@ -171,9 +171,9 @@ fn F_nested_tuple(a: ((i32, i32), X)) -> ((i32, i32), X) {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %_.var = alloca i32, align 4, !dbg !63
 // CHECK:STDOUT:   %_.var = alloca i32, align 4, !dbg !63
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var), !dbg !63
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var), !dbg !63
-// CHECK:STDOUT:   %Copy.Op.call.loc18 = call i32 @"_COp.Int.Core:Copy.Main"(i32 %a), !dbg !64
+// CHECK:STDOUT:   %Copy.Op.call.loc18 = call i32 @"_COp.Int.be1e879c1ad406d8.Core:Copy.Main"(i32 %a), !dbg !64
 // CHECK:STDOUT:   store i32 %Copy.Op.call.loc18, ptr %_.var, align 4, !dbg !63
 // CHECK:STDOUT:   store i32 %Copy.Op.call.loc18, ptr %_.var, align 4, !dbg !63
-// CHECK:STDOUT:   %Copy.Op.call.loc19 = call i32 @"_COp.Int.Core:Copy.Main"(i32 %a), !dbg !65
+// CHECK:STDOUT:   %Copy.Op.call.loc19 = call i32 @"_COp.Int.be1e879c1ad406d8.Core:Copy.Main"(i32 %a), !dbg !65
 // CHECK:STDOUT:   ret i32 %Copy.Op.call.loc19, !dbg !66
 // CHECK:STDOUT:   ret i32 %Copy.Op.call.loc19, !dbg !66
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -233,7 +233,7 @@ fn F_nested_tuple(a: ((i32, i32), X)) -> ((i32, i32), X) {
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "type_representation.carbon", directory: "")
 // CHECK:STDOUT: !3 = !DIFile(filename: "type_representation.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Copy.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.be1e879c1ad406d8.Core:Copy.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 // CHECK:STDOUT: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)

+ 169 - 9
toolchain/lower/testdata/impl/impl.carbon

@@ -10,6 +10,10 @@
 // TIP: To dump output, run:
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/impl/impl.carbon
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/impl/impl.carbon
 
 
+// --- impl.carbon
+
+library "[[@TEST_NAME]]";
+
 interface I {
 interface I {
   fn F[self: Self]() -> i32;
   fn F[self: Self]() -> i32;
 }
 }
@@ -28,15 +32,66 @@ fn Call(a: A) -> i32 {
   return a.(I.F)();
   return a.(I.F)();
 }
 }
 
 
+// --- generic_impls.carbon
+
+library "[[@TEST_NAME]]";
+
+class A {}
+class B {}
+class C {}
+
+interface I(T:! type) {
+  fn F[self: Self]() -> T;
+}
+
+impl C as I(A) {
+  fn F[self: C]() -> A { return {}; }
+}
+
+impl C as I(B) {
+  fn F[self: C]() -> B { return {}; }
+}
+
+fn F1(x: C, y: C) {
+  var a: A = x.(I(A).F)();
+  var b: B = y.(I(B).F)();
+}
+
+fn F2[T:! I(A), U:! I(B)](x: T, y: U) {
+  var a: A = x.F();
+  var b: B = y.F();
+}
+
+// --- generic_class_impls.carbon
+
+library "[[@TEST_NAME]]";
+
+class A {}
+class B {}
+
+class C(T:! type) {}
+
+interface I {
+  fn F();
+}
+
+impl C(A) as I {
+  fn F() {}
+}
+
+impl C(B) as I {
+  fn F() {}
+}
+
 // CHECK:STDOUT: ; ModuleID = 'impl.carbon'
 // CHECK:STDOUT: ; ModuleID = 'impl.carbon'
 // CHECK:STDOUT: source_filename = "impl.carbon"
 // CHECK:STDOUT: source_filename = "impl.carbon"
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define i32 @"_CF.A.Main:I.Main"(ptr %self) #0 !dbg !4 {
 // CHECK:STDOUT: define i32 @"_CF.A.Main:I.Main"(ptr %self) #0 !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %.loc23_16.1.n = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !11
-// CHECK:STDOUT:   %.loc23_16.2 = load i32, ptr %.loc23_16.1.n, align 4, !dbg !11
-// CHECK:STDOUT:   ret i32 %.loc23_16.2, !dbg !12
+// CHECK:STDOUT:   %.loc14_16.1.n = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !11
+// CHECK:STDOUT:   %.loc14_16.2 = load i32, ptr %.loc14_16.1.n, align 4, !dbg !11
+// CHECK:STDOUT:   ret i32 %.loc14_16.2, !dbg !12
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
@@ -55,17 +110,122 @@ fn Call(a: A) -> i32 {
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "impl.carbon", directory: "")
 // CHECK:STDOUT: !3 = !DIFile(filename: "impl.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.A.Main:I.Main", scope: null, file: !3, line: 22, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !9)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.A.Main:I.Main", scope: null, file: !3, line: 13, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !9)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{!7, !8}
 // CHECK:STDOUT: !6 = !{!7, !8}
 // CHECK:STDOUT: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 // CHECK:STDOUT: !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 // CHECK:STDOUT: !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
 // CHECK:STDOUT: !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
 // CHECK:STDOUT: !9 = !{!10}
 // CHECK:STDOUT: !9 = !{!10}
 // CHECK:STDOUT: !10 = !DILocalVariable(arg: 1, scope: !4, type: !8)
 // CHECK:STDOUT: !10 = !DILocalVariable(arg: 1, scope: !4, type: !8)
-// CHECK:STDOUT: !11 = !DILocation(line: 23, column: 12, scope: !4)
-// CHECK:STDOUT: !12 = !DILocation(line: 23, column: 5, scope: !4)
-// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !3, line: 27, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
+// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 12, scope: !4)
+// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 5, scope: !4)
+// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
 // CHECK:STDOUT: !14 = !{!15}
 // CHECK:STDOUT: !14 = !{!15}
 // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !13, type: !8)
 // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !13, type: !8)
-// CHECK:STDOUT: !16 = !DILocation(line: 28, column: 10, scope: !13)
-// CHECK:STDOUT: !17 = !DILocation(line: 28, column: 3, scope: !13)
+// CHECK:STDOUT: !16 = !DILocation(line: 19, column: 10, scope: !13)
+// CHECK:STDOUT: !17 = !DILocation(line: 19, column: 3, scope: !13)
+// CHECK:STDOUT: ; ModuleID = 'generic_impls.carbon'
+// CHECK:STDOUT: source_filename = "generic_impls.carbon"
+// CHECK:STDOUT:
+// CHECK:STDOUT: @A.val.loc13_35 = internal constant {} zeroinitializer
+// CHECK:STDOUT: @B.val.loc17_35 = internal constant {} zeroinitializer
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @"_CF.C.Main:I.96947bccc1c5e61b.Main"(ptr sret({}) %return, ptr %self) #0 !dbg !4 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @A.val.loc13_35, i64 0, i1 false), !dbg !10
+// CHECK:STDOUT:   ret void, !dbg !10
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @"_CF.C.Main:I.707dbe5ae2414d29.Main"(ptr sret({}) %return, ptr %self) #0 !dbg !11 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @B.val.loc17_35, i64 0, i1 false), !dbg !14
+// CHECK:STDOUT:   ret void, !dbg !14
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @_CF1.Main(ptr %x, ptr %y) #0 !dbg !15 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   %a.var = alloca {}, align 8, !dbg !21
+// CHECK:STDOUT:   %b.var = alloca {}, align 8, !dbg !22
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %a.var), !dbg !21
+// CHECK:STDOUT:   call void @"_CF.C.Main:I.96947bccc1c5e61b.Main"(ptr %a.var, ptr %x), !dbg !23
+// CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %b.var), !dbg !22
+// CHECK:STDOUT:   call void @"_CF.C.Main:I.707dbe5ae2414d29.Main"(ptr %b.var, ptr %y), !dbg !24
+// CHECK:STDOUT:   ret void, !dbg !25
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #1
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; uselistorder directives
+// CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 1, 0 }
+// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
+// CHECK:STDOUT:
+// CHECK:STDOUT: attributes #0 = { nounwind }
+// CHECK:STDOUT: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+// CHECK:STDOUT: attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
+// CHECK:STDOUT: !llvm.dbg.cu = !{!2}
+// CHECK:STDOUT:
+// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
+// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
+// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
+// CHECK:STDOUT: !3 = !DIFile(filename: "generic_impls.carbon", directory: "")
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.Main:I.96947bccc1c5e61b.Main", scope: null, file: !3, line: 13, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
+// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
+// CHECK:STDOUT: !6 = !{!7, !7}
+// CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
+// CHECK:STDOUT: !8 = !{!9}
+// CHECK:STDOUT: !9 = !DILocalVariable(arg: 1, scope: !4, type: !7)
+// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 26, scope: !4)
+// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.Main:I.707dbe5ae2414d29.Main", scope: null, file: !3, line: 17, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !12)
+// CHECK:STDOUT: !12 = !{!13}
+// CHECK:STDOUT: !13 = !DILocalVariable(arg: 1, scope: !11, type: !7)
+// CHECK:STDOUT: !14 = !DILocation(line: 17, column: 26, scope: !11)
+// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "F1", linkageName: "_CF1.Main", scope: null, file: !3, line: 20, type: !16, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !18)
+// CHECK:STDOUT: !16 = !DISubroutineType(types: !17)
+// CHECK:STDOUT: !17 = !{null, !7, !7}
+// CHECK:STDOUT: !18 = !{!19, !20}
+// CHECK:STDOUT: !19 = !DILocalVariable(arg: 1, scope: !15, type: !7)
+// CHECK:STDOUT: !20 = !DILocalVariable(arg: 2, scope: !15, type: !7)
+// CHECK:STDOUT: !21 = !DILocation(line: 21, column: 3, scope: !15)
+// CHECK:STDOUT: !22 = !DILocation(line: 22, column: 3, scope: !15)
+// CHECK:STDOUT: !23 = !DILocation(line: 21, column: 14, scope: !15)
+// CHECK:STDOUT: !24 = !DILocation(line: 22, column: 14, scope: !15)
+// CHECK:STDOUT: !25 = !DILocation(line: 20, column: 1, scope: !15)
+// CHECK:STDOUT: ; ModuleID = 'generic_class_impls.carbon'
+// CHECK:STDOUT: source_filename = "generic_class_impls.carbon"
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @"_CF.C.96947bccc1c5e61b.Main:I.Main"() #0 !dbg !4 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   ret void, !dbg !7
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; Function Attrs: nounwind
+// CHECK:STDOUT: define void @"_CF.C.707dbe5ae2414d29.Main:I.Main"() #0 !dbg !8 {
+// CHECK:STDOUT: entry:
+// CHECK:STDOUT:   ret void, !dbg !9
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: attributes #0 = { nounwind }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
+// CHECK:STDOUT: !llvm.dbg.cu = !{!2}
+// CHECK:STDOUT:
+// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
+// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
+// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
+// CHECK:STDOUT: !3 = !DIFile(filename: "generic_class_impls.carbon", directory: "")
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.96947bccc1c5e61b.Main:I.Main", scope: null, file: !3, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !2)
+// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
+// CHECK:STDOUT: !6 = !{null}
+// CHECK:STDOUT: !7 = !DILocation(line: 14, column: 3, scope: !4)
+// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.707dbe5ae2414d29.Main:I.Main", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2)
+// CHECK:STDOUT: !9 = !DILocation(line: 18, column: 3, scope: !8)

+ 3 - 3
toolchain/lower/testdata/impl/import_facet.carbon

@@ -92,7 +92,7 @@ fn F(d: D(i32)) -> i32* {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc5_21.1.temp = alloca {}, align 8, !dbg !10
 // CHECK:STDOUT:   %.loc5_21.1.temp = alloca {}, align 8, !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc5_21.1.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc5_21.1.temp), !dbg !10
-// CHECK:STDOUT:   call void @"_CGetI.D.Main:I.Main.b88d1103f417c6d4"(ptr %.loc5_21.1.temp, ptr %d), !dbg !10
+// CHECK:STDOUT:   call void @"_CGetI.D.eb057aa32837c84e.Main:I.Main.b88d1103f417c6d4"(ptr %.loc5_21.1.temp, ptr %d), !dbg !10
 // CHECK:STDOUT:   %C.GetC.call = call ptr @_CGetC.C.Main.8ef080b43913f36e(ptr %.loc5_21.1.temp), !dbg !10
 // CHECK:STDOUT:   %C.GetC.call = call ptr @_CGetC.C.Main.8ef080b43913f36e(ptr %.loc5_21.1.temp), !dbg !10
 // CHECK:STDOUT:   ret ptr %C.GetC.call, !dbg !11
 // CHECK:STDOUT:   ret ptr %C.GetC.call, !dbg !11
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
@@ -101,7 +101,7 @@ fn F(d: D(i32)) -> i32* {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CGetI.D.Main:I.Main.b88d1103f417c6d4"(ptr sret({}) %return, ptr %self) #0 !dbg !12 {
+// CHECK:STDOUT: define linkonce_odr void @"_CGetI.D.eb057aa32837c84e.Main:I.Main.b88d1103f417c6d4"(ptr sret({}) %return, ptr %self) #0 !dbg !12 {
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @C.val.02c.anon, i64 0, i1 false), !dbg !16
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @C.val.02c.anon, i64 0, i1 false), !dbg !16
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
@@ -136,7 +136,7 @@ fn F(d: D(i32)) -> i32* {
 // CHECK:STDOUT: !9 = !DILocalVariable(arg: 1, scope: !4, type: !7)
 // CHECK:STDOUT: !9 = !DILocalVariable(arg: 1, scope: !4, type: !7)
 // CHECK:STDOUT: !10 = !DILocation(line: 5, column: 10, scope: !4)
 // CHECK:STDOUT: !10 = !DILocation(line: 5, column: 10, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 5, column: 3, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 5, column: 3, scope: !4)
-// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "GetI", linkageName: "_CGetI.D.Main:I.Main.b88d1103f417c6d4", scope: null, file: !13, line: 6, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
+// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "GetI", linkageName: "_CGetI.D.eb057aa32837c84e.Main:I.Main.b88d1103f417c6d4", scope: null, file: !13, line: 6, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
 // CHECK:STDOUT: !13 = !DIFile(filename: "c.carbon", directory: "")
 // CHECK:STDOUT: !13 = !DIFile(filename: "c.carbon", directory: "")
 // CHECK:STDOUT: !14 = !{!15}
 // CHECK:STDOUT: !14 = !{!15}
 // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !12, type: !7)
 // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !12, type: !7)

+ 18 - 18
toolchain/lower/testdata/impl/import_thunk.carbon

@@ -70,7 +70,7 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT: source_filename = "thunk.carbon"
 // CHECK:STDOUT: source_filename = "thunk.carbon"
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @"_CConvert.A.Main:ImplicitAs.Core"(ptr sret({ i32 }) %return, ptr %self) #0 !dbg !4 {
+// CHECK:STDOUT: define void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr sret({ i32 }) %return, ptr %self) #0 !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc9_49.1.a = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !10
 // CHECK:STDOUT:   %.loc9_49.1.a = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !10
 // CHECK:STDOUT:   %.loc9_49.2 = load i32, ptr %.loc9_49.1.a, align 4, !dbg !10
 // CHECK:STDOUT:   %.loc9_49.2 = load i32, ptr %.loc9_49.1.a, align 4, !dbg !10
@@ -80,7 +80,7 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({ i32 }) %return, ptr %self) #0 !dbg !13 {
+// CHECK:STDOUT: define void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr sret({ i32 }) %return, ptr %self) #0 !dbg !13 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc12_49.1.b = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !16
 // CHECK:STDOUT:   %.loc12_49.1.b = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !16
 // CHECK:STDOUT:   %.loc12_49.2 = load i32, ptr %.loc12_49.1.b, align 4, !dbg !16
 // CHECK:STDOUT:   %.loc12_49.2 = load i32, ptr %.loc12_49.1.b, align 4, !dbg !16
@@ -106,9 +106,9 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT:   %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !29
 // CHECK:STDOUT:   %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !29
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_19.1.temp), !dbg !28
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_19.1.temp), !dbg !28
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc16_9.1.temp), !dbg !29
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc16_9.1.temp), !dbg !29
-// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !29
+// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !29
 // CHECK:STDOUT:   call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !28
 // CHECK:STDOUT:   call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !28
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc20_19.1.temp), !dbg !28
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr %return, ptr %.loc20_19.1.temp), !dbg !28
 // CHECK:STDOUT:   ret void, !dbg !28
 // CHECK:STDOUT:   ret void, !dbg !28
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -129,7 +129,7 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "thunk.carbon", directory: "")
 // CHECK:STDOUT: !3 = !DIFile(filename: "thunk.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.A.Main:ImplicitAs.Core", scope: null, file: !3, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core", scope: null, file: !3, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
 // CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
@@ -138,7 +138,7 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT: !10 = !DILocation(line: 9, column: 45, scope: !4)
 // CHECK:STDOUT: !10 = !DILocation(line: 9, column: 45, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 9, column: 39, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 9, column: 39, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 9, column: 32, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 9, column: 32, scope: !4)
-// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.B.Main:ImplicitAs.Core", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
+// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
 // CHECK:STDOUT: !14 = !{!15}
 // CHECK:STDOUT: !14 = !{!15}
 // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !13, type: !7)
 // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !13, type: !7)
 // CHECK:STDOUT: !16 = !DILocation(line: 12, column: 45, scope: !13)
 // CHECK:STDOUT: !16 = !DILocation(line: 12, column: 45, scope: !13)
@@ -167,9 +167,9 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_20.1.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_20.1.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_20.2.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_20.2.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_19.1.temp), !dbg !11
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_19.1.temp), !dbg !11
-// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc7_19.1.temp, ptr %a), !dbg !11
+// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr %.loc7_19.1.temp, ptr %a), !dbg !11
 // CHECK:STDOUT:   call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc7_20.2.temp, ptr %.loc7_19.1.temp), !dbg !10
 // CHECK:STDOUT:   call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc7_20.2.temp, ptr %.loc7_19.1.temp), !dbg !10
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc7_20.2.temp), !dbg !12
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr %return, ptr %.loc7_20.2.temp), !dbg !12
 // CHECK:STDOUT:   ret void, !dbg !12
 // CHECK:STDOUT:   ret void, !dbg !12
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -177,9 +177,9 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: declare void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT: declare void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @"_CConvert.A.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr)
+// CHECK:STDOUT: declare void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr)
+// CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
 // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
@@ -226,15 +226,15 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT:   %.2.temp = alloca { i32 }, align 8
 // CHECK:STDOUT:   %.2.temp = alloca { i32 }, align 8
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_19.1.temp), !dbg !16
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc9_19.1.temp), !dbg !16
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.2.temp)
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.2.temp)
-// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.2.temp, ptr %a), !dbg !17
+// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr %.2.temp, ptr %a), !dbg !17
 // CHECK:STDOUT:   call void @"_CF.X.Main:I.Main"(ptr %.loc9_19.1.temp, ptr %.2.temp), !dbg !16
 // CHECK:STDOUT:   call void @"_CF.X.Main:I.Main"(ptr %.loc9_19.1.temp, ptr %.2.temp), !dbg !16
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc9_19.1.temp), !dbg !16
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr %return, ptr %.loc9_19.1.temp), !dbg !16
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT:   ret void, !dbg !16
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @"_CConvert.A.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr)
+// CHECK:STDOUT: declare void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr)
+// CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
 // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
@@ -279,9 +279,9 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_19.1.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_19.1.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_19.2.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_19.2.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_18.1.temp), !dbg !11
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc8_18.1.temp), !dbg !11
-// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc8_18.1.temp, ptr %a), !dbg !11
+// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr %.loc8_18.1.temp, ptr %a), !dbg !11
 // CHECK:STDOUT:   call void @"_CF.X.Main:I.Main"(ptr %.loc8_19.2.temp, ptr %.loc8_18.1.temp), !dbg !10
 // CHECK:STDOUT:   call void @"_CF.X.Main:I.Main"(ptr %.loc8_19.2.temp, ptr %.loc8_18.1.temp), !dbg !10
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc8_19.2.temp), !dbg !12
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr %return, ptr %.loc8_19.2.temp), !dbg !12
 // CHECK:STDOUT:   ret void, !dbg !12
 // CHECK:STDOUT:   ret void, !dbg !12
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -289,9 +289,9 @@ fn Test(a: A) -> C {
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: declare void @"_CF.X.Main:I.Main"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT: declare void @"_CF.X.Main:I.Main"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @"_CConvert.A.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr)
+// CHECK:STDOUT: declare void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
-// CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr)
+// CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr sret({ i32 }), ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
 // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1

+ 23 - 23
toolchain/lower/testdata/impl/thunk.carbon

@@ -74,7 +74,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: source_filename = "thunk.carbon"
 // CHECK:STDOUT: source_filename = "thunk.carbon"
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @"_CConvert.A.Main:ImplicitAs.Core"(ptr sret({ i32 }) %return, ptr %self) #0 !dbg !4 {
+// CHECK:STDOUT: define void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr sret({ i32 }) %return, ptr %self) #0 !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc9_49.1.a = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !10
 // CHECK:STDOUT:   %.loc9_49.1.a = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !10
 // CHECK:STDOUT:   %.loc9_49.2 = load i32, ptr %.loc9_49.1.a, align 4, !dbg !10
 // CHECK:STDOUT:   %.loc9_49.2 = load i32, ptr %.loc9_49.1.a, align 4, !dbg !10
@@ -84,7 +84,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({ i32 }) %return, ptr %self) #0 !dbg !13 {
+// CHECK:STDOUT: define void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr sret({ i32 }) %return, ptr %self) #0 !dbg !13 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc12_49.1.b = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !16
 // CHECK:STDOUT:   %.loc12_49.1.b = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !16
 // CHECK:STDOUT:   %.loc12_49.2 = load i32, ptr %.loc12_49.1.b, align 4, !dbg !16
 // CHECK:STDOUT:   %.loc12_49.2 = load i32, ptr %.loc12_49.1.b, align 4, !dbg !16
@@ -110,9 +110,9 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT:   %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !29
 // CHECK:STDOUT:   %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !29
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_19.1.temp), !dbg !28
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc20_19.1.temp), !dbg !28
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc16_9.1.temp), !dbg !29
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc16_9.1.temp), !dbg !29
-// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !29
+// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !29
 // CHECK:STDOUT:   call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !28
 // CHECK:STDOUT:   call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !28
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc20_19.1.temp), !dbg !28
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr %return, ptr %.loc20_19.1.temp), !dbg !28
 // CHECK:STDOUT:   ret void, !dbg !28
 // CHECK:STDOUT:   ret void, !dbg !28
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -125,9 +125,9 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_20.1.temp), !dbg !33
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_20.1.temp), !dbg !33
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_20.2.temp), !dbg !33
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_20.2.temp), !dbg !33
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_19.1.temp), !dbg !34
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc24_19.1.temp), !dbg !34
-// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc24_19.1.temp, ptr %a), !dbg !34
+// CHECK:STDOUT:   call void @"_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core"(ptr %.loc24_19.1.temp, ptr %a), !dbg !34
 // CHECK:STDOUT:   call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc24_20.2.temp, ptr %.loc24_19.1.temp), !dbg !33
 // CHECK:STDOUT:   call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc24_20.2.temp, ptr %.loc24_19.1.temp), !dbg !33
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc24_20.2.temp), !dbg !35
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core"(ptr %return, ptr %.loc24_20.2.temp), !dbg !35
 // CHECK:STDOUT:   ret void, !dbg !35
 // CHECK:STDOUT:   ret void, !dbg !35
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -148,7 +148,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "thunk.carbon", directory: "")
 // CHECK:STDOUT: !3 = !DIFile(filename: "thunk.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.A.Main:ImplicitAs.Core", scope: null, file: !3, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.A.Main:ImplicitAs.707dbe5ae2414d29.Core", scope: null, file: !3, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
 // CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
@@ -157,7 +157,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: !10 = !DILocation(line: 9, column: 45, scope: !4)
 // CHECK:STDOUT: !10 = !DILocation(line: 9, column: 45, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 9, column: 39, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 9, column: 39, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 9, column: 32, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 9, column: 32, scope: !4)
-// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.B.Main:ImplicitAs.Core", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
+// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.B.Main:ImplicitAs.0c4ab795cec6cb27.Core", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
 // CHECK:STDOUT: !14 = !{!15}
 // CHECK:STDOUT: !14 = !{!15}
 // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !13, type: !7)
 // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !13, type: !7)
 // CHECK:STDOUT: !16 = !DILocation(line: 12, column: 45, scope: !13)
 // CHECK:STDOUT: !16 = !DILocation(line: 12, column: 45, scope: !13)
@@ -187,7 +187,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: @B.val.loc18_42 = internal constant {} zeroinitializer
 // CHECK:STDOUT: @B.val.loc18_42 = internal constant {} zeroinitializer
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({}) %return, ptr %self) #0 !dbg !4 {
+// CHECK:STDOUT: define void @"_CConvert.B.Main:ImplicitAs.96947bccc1c5e61b.Core"(ptr sret({}) %return, ptr %self) #0 !dbg !4 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @A.val.loc7_46, i64 0, i1 false), !dbg !10
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @A.val.loc7_46, i64 0, i1 false), !dbg !10
 // CHECK:STDOUT:   ret void, !dbg !10
 // CHECK:STDOUT:   ret void, !dbg !10
@@ -202,12 +202,12 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT:   %.loc22_22.1.temp = alloca {}, align 8, !dbg !18
 // CHECK:STDOUT:   %.loc22_22.1.temp = alloca {}, align 8, !dbg !18
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_23.1.temp), !dbg !17
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_23.1.temp), !dbg !17
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_23.3.temp), !dbg !17
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_23.3.temp), !dbg !17
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_23.3.temp, ptr %b), !dbg !17
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.96947bccc1c5e61b.Core"(ptr %.loc22_23.3.temp, ptr %b), !dbg !17
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_23.7.temp), !dbg !17
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_23.7.temp), !dbg !17
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_22.1.temp), !dbg !18
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_22.1.temp), !dbg !18
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_22.1.temp, ptr %b), !dbg !18
-// CHECK:STDOUT:   call void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr %.loc22_23.7.temp, ptr %c, ptr %.loc22_22.1.temp), !dbg !17
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc22_23.7.temp), !dbg !19
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.96947bccc1c5e61b.Core"(ptr %.loc22_22.1.temp, ptr %b), !dbg !18
+// CHECK:STDOUT:   call void @"_CF.C.eb057aa32837c84e.Main:I.eb057aa32837c84e.Main.e43630e9a6c38c3f"(ptr %.loc22_23.7.temp, ptr %c, ptr %.loc22_22.1.temp), !dbg !17
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.96947bccc1c5e61b.Core"(ptr %return, ptr %.loc22_23.7.temp), !dbg !19
 // CHECK:STDOUT:   ret void, !dbg !19
 // CHECK:STDOUT:   ret void, !dbg !19
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -225,7 +225,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr sret({}) %return, ptr %self, ptr %_) #0 !dbg !26 {
+// CHECK:STDOUT: define linkonce_odr void @"_CF.C.eb057aa32837c84e.Main:I.eb057aa32837c84e.Main.e43630e9a6c38c3f"(ptr sret({}) %return, ptr %self, ptr %_) #0 !dbg !26 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @B.val.loc18_42, i64 0, i1 false), !dbg !30
 // CHECK:STDOUT:   call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @B.val.loc18_42, i64 0, i1 false), !dbg !30
 // CHECK:STDOUT:   ret void, !dbg !30
 // CHECK:STDOUT:   ret void, !dbg !30
@@ -234,23 +234,23 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define linkonce_odr void @_CCallGeneric.Main.0bac38e8a17f7a1f(ptr sret({}) %return, ptr %c, ptr %b) #0 !dbg !31 {
 // CHECK:STDOUT: define linkonce_odr void @_CCallGeneric.Main.0bac38e8a17f7a1f(ptr sret({}) %return, ptr %c, ptr %b) #0 !dbg !31 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   call void @"_CF:thunk.C.Main:I.Main.e43630e9a6c38c3f"(ptr %return, ptr %c, ptr %b), !dbg !35
+// CHECK:STDOUT:   call void @"_CF:thunk.C.eb057aa32837c84e.Main:I.eb057aa32837c84e.Main.e43630e9a6c38c3f"(ptr %return, ptr %c, ptr %b), !dbg !35
 // CHECK:STDOUT:   ret void, !dbg !36
 // CHECK:STDOUT:   ret void, !dbg !36
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CF:thunk.C.Main:I.Main.e43630e9a6c38c3f"(ptr sret({}) %return, ptr %self, ptr %x) #3 !dbg !37 {
+// CHECK:STDOUT: define linkonce_odr void @"_CF:thunk.C.eb057aa32837c84e.Main:I.eb057aa32837c84e.Main.e43630e9a6c38c3f"(ptr sret({}) %return, ptr %self, ptr %x) #3 !dbg !37 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc18_31.2.temp = alloca {}, align 8, !dbg !41
 // CHECK:STDOUT:   %.loc18_31.2.temp = alloca {}, align 8, !dbg !41
 // CHECK:STDOUT:   %.loc18_31.6.temp = alloca {}, align 8, !dbg !41
 // CHECK:STDOUT:   %.loc18_31.6.temp = alloca {}, align 8, !dbg !41
 // CHECK:STDOUT:   %.loc12_21.1.temp = alloca {}, align 8, !dbg !42
 // CHECK:STDOUT:   %.loc12_21.1.temp = alloca {}, align 8, !dbg !42
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc18_31.2.temp), !dbg !41
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc18_31.2.temp), !dbg !41
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc18_31.2.temp, ptr %x), !dbg !41
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.96947bccc1c5e61b.Core"(ptr %.loc18_31.2.temp, ptr %x), !dbg !41
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc18_31.6.temp), !dbg !41
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc18_31.6.temp), !dbg !41
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_21.1.temp), !dbg !42
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_21.1.temp), !dbg !42
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc12_21.1.temp, ptr %x), !dbg !42
-// CHECK:STDOUT:   call void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr %.loc18_31.6.temp, ptr %self, ptr %.loc12_21.1.temp), !dbg !41
-// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc18_31.6.temp), !dbg !41
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.96947bccc1c5e61b.Core"(ptr %.loc12_21.1.temp, ptr %x), !dbg !42
+// CHECK:STDOUT:   call void @"_CF.C.eb057aa32837c84e.Main:I.eb057aa32837c84e.Main.e43630e9a6c38c3f"(ptr %.loc18_31.6.temp, ptr %self, ptr %.loc12_21.1.temp), !dbg !41
+// CHECK:STDOUT:   call void @"_CConvert.B.Main:ImplicitAs.96947bccc1c5e61b.Core"(ptr %return, ptr %.loc18_31.6.temp), !dbg !41
 // CHECK:STDOUT:   ret void, !dbg !41
 // CHECK:STDOUT:   ret void, !dbg !41
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -269,7 +269,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
 // CHECK:STDOUT: !3 = !DIFile(filename: "generic_thunk.carbon", directory: "")
 // CHECK:STDOUT: !3 = !DIFile(filename: "generic_thunk.carbon", directory: "")
-// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.B.Main:ImplicitAs.Core", scope: null, file: !3, line: 7, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
+// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.B.Main:ImplicitAs.96947bccc1c5e61b.Core", scope: null, file: !3, line: 7, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !6 = !{!7, !7}
 // CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
 // CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 8)
@@ -291,7 +291,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: !23 = !DILocalVariable(arg: 2, scope: !20, type: !7)
 // CHECK:STDOUT: !23 = !DILocalVariable(arg: 2, scope: !20, type: !7)
 // CHECK:STDOUT: !24 = !DILocation(line: 30, column: 10, scope: !20)
 // CHECK:STDOUT: !24 = !DILocation(line: 30, column: 10, scope: !20)
 // CHECK:STDOUT: !25 = !DILocation(line: 30, column: 3, scope: !20)
 // CHECK:STDOUT: !25 = !DILocation(line: 30, column: 3, scope: !20)
-// CHECK:STDOUT: !26 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.Main:I.Main.e43630e9a6c38c3f", scope: null, file: !3, line: 18, type: !12, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !27)
+// CHECK:STDOUT: !26 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.eb057aa32837c84e.Main:I.eb057aa32837c84e.Main.e43630e9a6c38c3f", scope: null, file: !3, line: 18, type: !12, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !27)
 // CHECK:STDOUT: !27 = !{!28, !29}
 // CHECK:STDOUT: !27 = !{!28, !29}
 // CHECK:STDOUT: !28 = !DILocalVariable(arg: 1, scope: !26, type: !7)
 // CHECK:STDOUT: !28 = !DILocalVariable(arg: 1, scope: !26, type: !7)
 // CHECK:STDOUT: !29 = !DILocalVariable(arg: 2, scope: !26, type: !7)
 // CHECK:STDOUT: !29 = !DILocalVariable(arg: 2, scope: !26, type: !7)
@@ -302,7 +302,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A {
 // CHECK:STDOUT: !34 = !DILocalVariable(arg: 2, scope: !31, type: !7)
 // CHECK:STDOUT: !34 = !DILocalVariable(arg: 2, scope: !31, type: !7)
 // CHECK:STDOUT: !35 = !DILocation(line: 26, column: 10, scope: !31)
 // CHECK:STDOUT: !35 = !DILocation(line: 26, column: 10, scope: !31)
 // CHECK:STDOUT: !36 = !DILocation(line: 26, column: 3, scope: !31)
 // CHECK:STDOUT: !36 = !DILocation(line: 26, column: 3, scope: !31)
-// CHECK:STDOUT: !37 = distinct !DISubprogram(name: "F", linkageName: "_CF:thunk.C.Main:I.Main.e43630e9a6c38c3f", scope: null, file: !3, line: 18, type: !12, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38)
+// CHECK:STDOUT: !37 = distinct !DISubprogram(name: "F", linkageName: "_CF:thunk.C.eb057aa32837c84e.Main:I.eb057aa32837c84e.Main.e43630e9a6c38c3f", scope: null, file: !3, line: 18, type: !12, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38)
 // CHECK:STDOUT: !38 = !{!39, !40}
 // CHECK:STDOUT: !38 = !{!39, !40}
 // CHECK:STDOUT: !39 = !DILocalVariable(arg: 1, scope: !37, type: !7)
 // CHECK:STDOUT: !39 = !DILocalVariable(arg: 1, scope: !37, type: !7)
 // CHECK:STDOUT: !40 = !DILocalVariable(arg: 2, scope: !37, type: !7)
 // CHECK:STDOUT: !40 = !DILocalVariable(arg: 2, scope: !37, type: !7)

+ 7 - 7
toolchain/lower/testdata/interop/cpp/nullptr.carbon

@@ -59,7 +59,7 @@ fn ConvertNullptrConstant() -> Core.Optional(i32*) {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc12_18.2.temp = alloca ptr, align 8, !dbg !10
 // CHECK:STDOUT:   %.loc12_18.2.temp = alloca ptr, align 8, !dbg !10
 // CHECK:STDOUT:   %.loc14_22.1.temp = alloca ptr, align 8, !dbg !11
 // CHECK:STDOUT:   %.loc14_22.1.temp = alloca ptr, align 8, !dbg !11
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.Core.b88d1103f417c6d4"(ptr poison), !dbg !10
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr poison), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_18.2.temp), !dbg !10
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc12_18.2.temp), !dbg !10
 // CHECK:STDOUT:   store ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, ptr %.loc12_18.2.temp, align 8, !dbg !10
 // CHECK:STDOUT:   store ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, ptr %.loc12_18.2.temp, align 8, !dbg !10
 // CHECK:STDOUT:   %.loc12_18.4 = load ptr, ptr %.loc12_18.2.temp, align 8, !dbg !10
 // CHECK:STDOUT:   %.loc12_18.4 = load ptr, ptr %.loc12_18.2.temp, align 8, !dbg !10
@@ -105,7 +105,7 @@ fn ConvertNullptrConstant() -> Core.Optional(i32*) {
 // CHECK:STDOUT:   %.loc27_44.2 = load ptr, ptr %.loc27_44.1.temp, align 8, !dbg !28
 // CHECK:STDOUT:   %.loc27_44.2 = load ptr, ptr %.loc27_44.1.temp, align 8, !dbg !28
 // CHECK:STDOUT:   store ptr %.loc27_44.2, ptr %a.var, align 8, !dbg !27
 // CHECK:STDOUT:   store ptr %.loc27_44.2, ptr %a.var, align 8, !dbg !27
 // CHECK:STDOUT:   %.loc28_10 = load ptr, ptr %a.var, align 8, !dbg !29
 // CHECK:STDOUT:   %.loc28_10 = load ptr, ptr %a.var, align 8, !dbg !29
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.Core.b88d1103f417c6d4"(ptr %.loc28_10), !dbg !30
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %.loc28_10), !dbg !30
 // CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !30
 // CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !30
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -116,19 +116,19 @@ fn ConvertNullptrConstant() -> Core.Optional(i32*) {
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc32_28.1.temp), !dbg !32
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc32_28.1.temp), !dbg !32
 // CHECK:STDOUT:   call void @_Z13ReturnNullptrv.carbon_thunk(ptr %.loc32_28.1.temp), !dbg !32
 // CHECK:STDOUT:   call void @_Z13ReturnNullptrv.carbon_thunk(ptr %.loc32_28.1.temp), !dbg !32
 // CHECK:STDOUT:   %.loc32_28.2 = load ptr, ptr %.loc32_28.1.temp, align 8, !dbg !32
 // CHECK:STDOUT:   %.loc32_28.2 = load ptr, ptr %.loc32_28.1.temp, align 8, !dbg !32
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.Core.b88d1103f417c6d4"(ptr %.loc32_28.2), !dbg !33
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %.loc32_28.2), !dbg !33
 // CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !33
 // CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !33
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: define ptr @_CConvertNullptrConstant.Main() #0 !dbg !34 {
 // CHECK:STDOUT: define ptr @_CConvertNullptrConstant.Main() #0 !dbg !34 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
-// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.Core.b88d1103f417c6d4"(ptr poison), !dbg !35
+// CHECK:STDOUT:   %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr poison), !dbg !35
 // CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !35
 // CHECK:STDOUT:   ret ptr %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.call, !dbg !35
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.Core.b88d1103f417c6d4"(ptr %self) #0 !dbg !36 {
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4"(ptr %self) #0 !dbg !36 {
 // CHECK:STDOUT:   %1 = call ptr @_CNone.Optional.Core.7bfe1822cd6dd563(), !dbg !42
 // CHECK:STDOUT:   %1 = call ptr @_CNone.Optional.Core.7bfe1822cd6dd563(), !dbg !42
 // CHECK:STDOUT:   ret ptr %1, !dbg !43
 // CHECK:STDOUT:   ret ptr %1, !dbg !43
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
@@ -169,7 +169,7 @@ fn ConvertNullptrConstant() -> Core.Optional(i32*) {
 // CHECK:STDOUT: declare ptr @_Z13ReturnNullptrv() #3
 // CHECK:STDOUT: declare ptr @_Z13ReturnNullptrv() #3
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: ; uselistorder directives
-// CHECK:STDOUT: uselistorder ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.Core.b88d1103f417c6d4", { 3, 2, 1, 0 }
+// CHECK:STDOUT: uselistorder ptr @"_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4", { 3, 2, 1, 0 }
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 5, 4, 3, 2, 1, 0 }
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 5, 4, 3, 2, 1, 0 }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: attributes #0 = { nounwind }
 // CHECK:STDOUT: attributes #0 = { nounwind }
@@ -216,7 +216,7 @@ fn ConvertNullptrConstant() -> Core.Optional(i32*) {
 // CHECK:STDOUT: !33 = !DILocation(line: 32, column: 3, scope: !31)
 // CHECK:STDOUT: !33 = !DILocation(line: 32, column: 3, scope: !31)
 // CHECK:STDOUT: !34 = distinct !DISubprogram(name: "ConvertNullptrConstant", linkageName: "_CConvertNullptrConstant.Main", scope: null, file: !6, line: 35, type: !16, spFlags: DISPFlagDefinition, unit: !5)
 // CHECK:STDOUT: !34 = distinct !DISubprogram(name: "ConvertNullptrConstant", linkageName: "_CConvertNullptrConstant.Main", scope: null, file: !6, line: 35, type: !16, spFlags: DISPFlagDefinition, unit: !5)
 // CHECK:STDOUT: !35 = !DILocation(line: 36, column: 3, scope: !34)
 // CHECK:STDOUT: !35 = !DILocation(line: 36, column: 3, scope: !34)
-// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.NullptrT.CppCompat.Core:ImplicitAs.Core.b88d1103f417c6d4", scope: null, file: !37, line: 46, type: !38, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !40)
+// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.NullptrT.CppCompat.Core:ImplicitAs.95db8d3a03540861.Core.b88d1103f417c6d4", scope: null, file: !37, line: 46, type: !38, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !40)
 // CHECK:STDOUT: !37 = !DIFile(filename: "{{.*}}/prelude/types/cpp/nullptr.carbon", directory: "")
 // CHECK:STDOUT: !37 = !DIFile(filename: "{{.*}}/prelude/types/cpp/nullptr.carbon", directory: "")
 // CHECK:STDOUT: !38 = !DISubroutineType(types: !39)
 // CHECK:STDOUT: !38 = !DISubroutineType(types: !39)
 // CHECK:STDOUT: !39 = !{!18, !18}
 // CHECK:STDOUT: !39 = !{!18, !18}

+ 8 - 8
toolchain/lower/testdata/interop/cpp/pointer.carbon

@@ -198,7 +198,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: define void @_CPassNonnullPtr.Main(ptr %p) #0 !dbg !14 {
 // CHECK:STDOUT: define void @_CPassNonnullPtr.Main(ptr %p) #0 !dbg !14 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc22_15.2.temp = alloca ptr, align 8, !dbg !17
 // CHECK:STDOUT:   %.loc22_15.2.temp = alloca ptr, align 8, !dbg !17
-// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.5b1b7c6bb83e5c41"(ptr %p), !dbg !17
+// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %p), !dbg !17
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_15.2.temp), !dbg !17
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc22_15.2.temp), !dbg !17
 // CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc22_15.2.temp, align 8, !dbg !17
 // CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc22_15.2.temp, align 8, !dbg !17
 // CHECK:STDOUT:   %.loc22_15.4 = load ptr, ptr %.loc22_15.2.temp, align 8, !dbg !17
 // CHECK:STDOUT:   %.loc22_15.4 = load ptr, ptr %.loc22_15.2.temp, align 8, !dbg !17
@@ -227,7 +227,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: define void @_CPassNonnullPtrWithThunk.Main(ptr %p) #0 !dbg !29 {
 // CHECK:STDOUT: define void @_CPassNonnullPtrWithThunk.Main(ptr %p) #0 !dbg !29 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc35_24.2.temp = alloca ptr, align 8, !dbg !32
 // CHECK:STDOUT:   %.loc35_24.2.temp = alloca ptr, align 8, !dbg !32
-// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.5b1b7c6bb83e5c41"(ptr %p), !dbg !32
+// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %p), !dbg !32
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc35_24.2.temp), !dbg !32
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc35_24.2.temp), !dbg !32
 // CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc35_24.2.temp, align 8, !dbg !32
 // CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc35_24.2.temp, align 8, !dbg !32
 // CHECK:STDOUT:   %.loc35_24.4 = load ptr, ptr %.loc35_24.2.temp, align 8, !dbg !32
 // CHECK:STDOUT:   %.loc35_24.4 = load ptr, ptr %.loc35_24.2.temp, align 8, !dbg !32
@@ -243,8 +243,8 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.5b1b7c6bb83e5c41"(ptr %self) #0 !dbg !38 {
-// CHECK:STDOUT:   %1 = call ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.Core.ea71e3f17b6b4efb"(ptr %self), !dbg !44
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41"(ptr %self) #0 !dbg !38 {
+// CHECK:STDOUT:   %1 = call ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb"(ptr %self), !dbg !44
 // CHECK:STDOUT:   ret ptr %1, !dbg !45
 // CHECK:STDOUT:   ret ptr %1, !dbg !45
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -252,7 +252,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.Core.ea71e3f17b6b4efb"(ptr %self) #0 !dbg !46 {
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb"(ptr %self) #0 !dbg !46 {
 // CHECK:STDOUT:   %1 = call ptr @_CSome.Optional.Core.ea71e3f17b6b4efb(ptr %self), !dbg !49
 // CHECK:STDOUT:   %1 = call ptr @_CSome.Optional.Core.ea71e3f17b6b4efb(ptr %self), !dbg !49
 // CHECK:STDOUT:   ret ptr %1, !dbg !50
 // CHECK:STDOUT:   ret ptr %1, !dbg !50
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
@@ -294,7 +294,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: declare ptr @_Z18ReturnPtrWithThunki(i32) #3
 // CHECK:STDOUT: declare ptr @_Z18ReturnPtrWithThunki(i32) #3
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: ; uselistorder directives
-// CHECK:STDOUT: uselistorder ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.5b1b7c6bb83e5c41", { 1, 0 }
+// CHECK:STDOUT: uselistorder ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41", { 1, 0 }
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 2, 1 }
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 2, 1 }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: attributes #0 = { nounwind }
 // CHECK:STDOUT: attributes #0 = { nounwind }
@@ -343,7 +343,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: !35 = distinct !DISubprogram(name: "ReturnPtrWithThunk", linkageName: "_CReturnPtrWithThunk.Main", scope: null, file: !6, line: 38, type: !21, spFlags: DISPFlagDefinition, unit: !5)
 // CHECK:STDOUT: !35 = distinct !DISubprogram(name: "ReturnPtrWithThunk", linkageName: "_CReturnPtrWithThunk.Main", scope: null, file: !6, line: 38, type: !21, spFlags: DISPFlagDefinition, unit: !5)
 // CHECK:STDOUT: !36 = !DILocation(line: 39, column: 10, scope: !35)
 // CHECK:STDOUT: !36 = !DILocation(line: 39, column: 10, scope: !35)
 // CHECK:STDOUT: !37 = !DILocation(line: 39, column: 3, scope: !35)
 // CHECK:STDOUT: !37 = !DILocation(line: 39, column: 3, scope: !35)
-// CHECK:STDOUT: !38 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.5b1b7c6bb83e5c41", scope: null, file: !39, line: 82, type: !40, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !42)
+// CHECK:STDOUT: !38 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5b1b7c6bb83e5c41", scope: null, file: !39, line: 82, type: !40, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !42)
 // CHECK:STDOUT: !39 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
 // CHECK:STDOUT: !39 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
 // CHECK:STDOUT: !40 = !DISubroutineType(types: !41)
 // CHECK:STDOUT: !40 = !DISubroutineType(types: !41)
 // CHECK:STDOUT: !41 = !{!10, !10}
 // CHECK:STDOUT: !41 = !{!10, !10}
@@ -351,7 +351,7 @@ fn ReturnPtrWithThunk() -> Core.Optional(Cpp.C*) {
 // CHECK:STDOUT: !43 = !DILocalVariable(arg: 1, scope: !38, type: !10)
 // CHECK:STDOUT: !43 = !DILocalVariable(arg: 1, scope: !38, type: !10)
 // CHECK:STDOUT: !44 = !DILocation(line: 83, column: 12, scope: !38)
 // CHECK:STDOUT: !44 = !DILocation(line: 83, column: 12, scope: !38)
 // CHECK:STDOUT: !45 = !DILocation(line: 83, column: 5, scope: !38)
 // CHECK:STDOUT: !45 = !DILocation(line: 83, column: 5, scope: !38)
-// CHECK:STDOUT: !46 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.90961d7b1ce4f089:OptionalAs.Core.ea71e3f17b6b4efb", scope: null, file: !39, line: 68, type: !40, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !47)
+// CHECK:STDOUT: !46 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.ea71e3f17b6b4efb", scope: null, file: !39, line: 68, type: !40, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !47)
 // CHECK:STDOUT: !47 = !{!48}
 // CHECK:STDOUT: !47 = !{!48}
 // CHECK:STDOUT: !48 = !DILocalVariable(arg: 1, scope: !46, type: !10)
 // CHECK:STDOUT: !48 = !DILocalVariable(arg: 1, scope: !46, type: !10)
 // CHECK:STDOUT: !49 = !DILocation(line: 69, column: 12, scope: !46)
 // CHECK:STDOUT: !49 = !DILocation(line: 69, column: 12, scope: !46)

+ 6 - 6
toolchain/lower/testdata/interop/cpp/void.carbon

@@ -33,7 +33,7 @@ fn PassVoidPtr(a: Cpp.void*) {
 // CHECK:STDOUT: define void @_CPassVoidPtr.Main(ptr %a) #0 !dbg !7 {
 // CHECK:STDOUT: define void @_CPassVoidPtr.Main(ptr %a) #0 !dbg !7 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc7_21.2.temp = alloca ptr, align 8, !dbg !13
 // CHECK:STDOUT:   %.loc7_21.2.temp = alloca ptr, align 8, !dbg !13
-// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.5c62f2dbad753cd9"(ptr %a), !dbg !13
+// CHECK:STDOUT:   %U.binding.as_type.as.ImplicitAs.impl.Convert.call = call ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5c62f2dbad753cd9"(ptr %a), !dbg !13
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_21.2.temp), !dbg !13
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc7_21.2.temp), !dbg !13
 // CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc7_21.2.temp, align 8, !dbg !13
 // CHECK:STDOUT:   store ptr %U.binding.as_type.as.ImplicitAs.impl.Convert.call, ptr %.loc7_21.2.temp, align 8, !dbg !13
 // CHECK:STDOUT:   %.loc7_21.4 = load ptr, ptr %.loc7_21.2.temp, align 8, !dbg !13
 // CHECK:STDOUT:   %.loc7_21.4 = load ptr, ptr %.loc7_21.2.temp, align 8, !dbg !13
@@ -44,8 +44,8 @@ fn PassVoidPtr(a: Cpp.void*) {
 // CHECK:STDOUT: declare void @_Z13take_void_ptrPv(ptr)
 // CHECK:STDOUT: declare void @_Z13take_void_ptrPv(ptr)
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.5c62f2dbad753cd9"(ptr %self) #0 !dbg !16 {
-// CHECK:STDOUT:   %1 = call ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.Core.d2075df181ac34c1"(ptr %self), !dbg !22
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5c62f2dbad753cd9"(ptr %self) #0 !dbg !16 {
+// CHECK:STDOUT:   %1 = call ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.d2075df181ac34c1"(ptr %self), !dbg !22
 // CHECK:STDOUT:   ret ptr %1, !dbg !23
 // CHECK:STDOUT:   ret ptr %1, !dbg !23
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -53,7 +53,7 @@ fn PassVoidPtr(a: Cpp.void*) {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.Core.d2075df181ac34c1"(ptr %self) #0 !dbg !24 {
+// CHECK:STDOUT: define linkonce_odr ptr @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.d2075df181ac34c1"(ptr %self) #0 !dbg !24 {
 // CHECK:STDOUT:   %1 = call ptr @_CSome.Optional.Core.d2075df181ac34c1(ptr %self), !dbg !27
 // CHECK:STDOUT:   %1 = call ptr @_CSome.Optional.Core.d2075df181ac34c1(ptr %self), !dbg !27
 // CHECK:STDOUT:   ret ptr %1, !dbg !28
 // CHECK:STDOUT:   ret ptr %1, !dbg !28
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
@@ -95,7 +95,7 @@ fn PassVoidPtr(a: Cpp.void*) {
 // CHECK:STDOUT: !13 = !DILocation(line: 7, column: 21, scope: !7)
 // CHECK:STDOUT: !13 = !DILocation(line: 7, column: 21, scope: !7)
 // CHECK:STDOUT: !14 = !DILocation(line: 7, column: 3, scope: !7)
 // CHECK:STDOUT: !14 = !DILocation(line: 7, column: 3, scope: !7)
 // CHECK:STDOUT: !15 = !DILocation(line: 6, column: 1, scope: !7)
 // CHECK:STDOUT: !15 = !DILocation(line: 6, column: 1, scope: !7)
-// CHECK:STDOUT: !16 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.5c62f2dbad753cd9", scope: null, file: !17, line: 82, type: !18, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !20)
+// CHECK:STDOUT: !16 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.5c62f2dbad753cd9", scope: null, file: !17, line: 82, type: !18, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !20)
 // CHECK:STDOUT: !17 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
 // CHECK:STDOUT: !17 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")
 // CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
 // CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
 // CHECK:STDOUT: !19 = !{!10, !10}
 // CHECK:STDOUT: !19 = !{!10, !10}
@@ -103,7 +103,7 @@ fn PassVoidPtr(a: Cpp.void*) {
 // CHECK:STDOUT: !21 = !DILocalVariable(arg: 1, scope: !16, type: !10)
 // CHECK:STDOUT: !21 = !DILocalVariable(arg: 1, scope: !16, type: !10)
 // CHECK:STDOUT: !22 = !DILocation(line: 83, column: 12, scope: !16)
 // CHECK:STDOUT: !22 = !DILocation(line: 83, column: 12, scope: !16)
 // CHECK:STDOUT: !23 = !DILocation(line: 83, column: 5, scope: !16)
 // CHECK:STDOUT: !23 = !DILocation(line: 83, column: 5, scope: !16)
-// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.90961d7b1ce4f089:OptionalAs.Core.d2075df181ac34c1", scope: null, file: !17, line: 68, type: !18, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !25)
+// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.d2075df181ac34c1", scope: null, file: !17, line: 68, type: !18, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !25)
 // CHECK:STDOUT: !25 = !{!26}
 // CHECK:STDOUT: !25 = !{!26}
 // CHECK:STDOUT: !26 = !DILocalVariable(arg: 1, scope: !24, type: !10)
 // CHECK:STDOUT: !26 = !DILocalVariable(arg: 1, scope: !24, type: !10)
 // CHECK:STDOUT: !27 = !DILocation(line: 69, column: 12, scope: !24)
 // CHECK:STDOUT: !27 = !DILocation(line: 69, column: 12, scope: !24)

+ 9 - 9
toolchain/lower/testdata/operators/increment.carbon

@@ -28,7 +28,7 @@ fn IncrSigned() {
 // CHECK:STDOUT:   %from.var = alloca i32, align 4, !dbg !7
 // CHECK:STDOUT:   %from.var = alloca i32, align 4, !dbg !7
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %from.var), !dbg !7
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %from.var), !dbg !7
 // CHECK:STDOUT:   store i32 0, ptr %from.var, align 4, !dbg !7
 // CHECK:STDOUT:   store i32 0, ptr %from.var, align 4, !dbg !7
-// CHECK:STDOUT:   call void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %from.var), !dbg !8
+// CHECK:STDOUT:   call void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %from.var), !dbg !8
 // CHECK:STDOUT:   ret void, !dbg !9
 // CHECK:STDOUT:   ret void, !dbg !9
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -36,14 +36,14 @@ fn IncrSigned() {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !10 {
-// CHECK:STDOUT:   call void @"_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5"(ptr %self, i32 1), !dbg !17
+// CHECK:STDOUT: define linkonce_odr void @"_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8"(ptr %self) #0 !dbg !10 {
+// CHECK:STDOUT:   call void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5"(ptr %self, i32 1), !dbg !17
 // CHECK:STDOUT:   ret void, !dbg !18
 // CHECK:STDOUT:   ret void, !dbg !18
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
 // CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5"(ptr %self, i32 %other) #2 !dbg !19 {
-// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e"(i32 %other), !dbg !25
+// CHECK:STDOUT: define linkonce_odr void @"_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5"(ptr %self, i32 %other) #2 !dbg !19 {
+// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e"(i32 %other), !dbg !25
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !26
 // CHECK:STDOUT:   %2 = load i32, ptr %self, align 4, !dbg !26
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !26
 // CHECK:STDOUT:   %3 = add i32 %2, %1, !dbg !26
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !26
 // CHECK:STDOUT:   store i32 %3, ptr %self, align 4, !dbg !26
@@ -51,7 +51,7 @@ fn IncrSigned() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e"(i32 %self) #0 !dbg !27 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e"(i32 %self) #0 !dbg !27 {
 // CHECK:STDOUT:   ret i32 %self, !dbg !33
 // CHECK:STDOUT:   ret i32 %self, !dbg !33
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -72,7 +72,7 @@ fn IncrSigned() {
 // CHECK:STDOUT: !7 = !DILocation(line: 5, column: 3, scope: !4)
 // CHECK:STDOUT: !7 = !DILocation(line: 5, column: 3, scope: !4)
 // CHECK:STDOUT: !8 = !DILocation(line: 6, column: 3, scope: !4)
 // CHECK:STDOUT: !8 = !DILocation(line: 6, column: 3, scope: !4)
 // CHECK:STDOUT: !9 = !DILocation(line: 4, column: 1, scope: !4)
 // CHECK:STDOUT: !9 = !DILocation(line: 4, column: 1, scope: !4)
-// CHECK:STDOUT: !10 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !11, line: 339, type: !12, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15)
+// CHECK:STDOUT: !10 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Int.9452f4c51951679b.Core:Inc.Core.be1e879c1ad406d8", scope: null, file: !11, line: 339, type: !12, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15)
 // CHECK:STDOUT: !11 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !11 = !DIFile(filename: "{{.*}}/prelude/types/int.carbon", directory: "")
 // CHECK:STDOUT: !12 = !DISubroutineType(types: !13)
 // CHECK:STDOUT: !12 = !DISubroutineType(types: !13)
 // CHECK:STDOUT: !13 = !{null, !14}
 // CHECK:STDOUT: !13 = !{null, !14}
@@ -81,7 +81,7 @@ fn IncrSigned() {
 // CHECK:STDOUT: !16 = !DILocalVariable(arg: 1, scope: !10, type: !14)
 // CHECK:STDOUT: !16 = !DILocalVariable(arg: 1, scope: !10, type: !14)
 // CHECK:STDOUT: !17 = !DILocation(line: 341, column: 5, scope: !10)
 // CHECK:STDOUT: !17 = !DILocation(line: 341, column: 5, scope: !10)
 // CHECK:STDOUT: !18 = !DILocation(line: 339, column: 3, scope: !10)
 // CHECK:STDOUT: !18 = !DILocation(line: 339, column: 3, scope: !10)
-// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.Core:AddAssignWith.Core.75bec4d236c9daa5", scope: null, file: !11, line: 275, type: !20, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !22)
+// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "Op", linkageName: "_COp:thunk.Int.9452f4c51951679b.Core:AddAssignWith.5375cfcbca6d9e35.Core.75bec4d236c9daa5", scope: null, file: !11, line: 275, type: !20, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !22)
 // CHECK:STDOUT: !20 = !DISubroutineType(types: !21)
 // CHECK:STDOUT: !20 = !DISubroutineType(types: !21)
 // CHECK:STDOUT: !21 = !{null, !14, !14}
 // CHECK:STDOUT: !21 = !{null, !14, !14}
 // CHECK:STDOUT: !22 = !{!23, !24}
 // CHECK:STDOUT: !22 = !{!23, !24}
@@ -89,7 +89,7 @@ fn IncrSigned() {
 // CHECK:STDOUT: !24 = !DILocalVariable(arg: 2, scope: !19, type: !14)
 // CHECK:STDOUT: !24 = !DILocalVariable(arg: 2, scope: !19, type: !14)
 // CHECK:STDOUT: !25 = !DILocation(line: 4294967295, scope: !19)
 // CHECK:STDOUT: !25 = !DILocation(line: 4294967295, scope: !19)
 // CHECK:STDOUT: !26 = !DILocation(line: 275, column: 3, scope: !19)
 // CHECK:STDOUT: !26 = !DILocation(line: 275, column: 3, scope: !19)
-// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e", scope: null, file: !28, line: 24, type: !29, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !31)
+// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e", scope: null, file: !28, line: 24, type: !29, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !31)
 // CHECK:STDOUT: !28 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !28 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !29 = !DISubroutineType(types: !30)
 // CHECK:STDOUT: !29 = !DISubroutineType(types: !30)
 // CHECK:STDOUT: !30 = !{!14, !14}
 // CHECK:STDOUT: !30 = !{!14, !14}

+ 3 - 3
toolchain/lower/testdata/operators/overloaded.carbon

@@ -47,7 +47,7 @@ fn Calculate(a: Number, b: Number) -> Number {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define void @"_COp.Number.Main:MulWith.Core"(ptr sret({ i1 }) %return, ptr %self, ptr %other) #0 !dbg !14 {
+// CHECK:STDOUT: define void @"_COp.Number.Main:MulWith.44027391c5135f93.Core"(ptr sret({ i1 }) %return, ptr %self, ptr %other) #0 !dbg !14 {
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT: entry:
 // CHECK:STDOUT:   %.loc24_33.1.is_positive = getelementptr inbounds nuw { i1 }, ptr %self, i32 0, i32 0, !dbg !20
 // CHECK:STDOUT:   %.loc24_33.1.is_positive = getelementptr inbounds nuw { i1 }, ptr %self, i32 0, i32 0, !dbg !20
 // CHECK:STDOUT:   %.loc24_33.2 = load i8, ptr %.loc24_33.1.is_positive, align 1, !dbg !20
 // CHECK:STDOUT:   %.loc24_33.2 = load i8, ptr %.loc24_33.1.is_positive, align 1, !dbg !20
@@ -97,7 +97,7 @@ fn Calculate(a: Number, b: Number) -> Number {
 // CHECK:STDOUT:   %.loc30_10.1.temp = alloca { i1 }, align 8, !dbg !33
 // CHECK:STDOUT:   %.loc30_10.1.temp = alloca { i1 }, align 8, !dbg !33
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc30_10.1.temp), !dbg !33
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %.loc30_10.1.temp), !dbg !33
 // CHECK:STDOUT:   call void @"_COp.Number.Main:Negate.Core"(ptr %.loc30_10.1.temp, ptr %a), !dbg !33
 // CHECK:STDOUT:   call void @"_COp.Number.Main:Negate.Core"(ptr %.loc30_10.1.temp, ptr %a), !dbg !33
-// CHECK:STDOUT:   call void @"_COp.Number.Main:MulWith.Core"(ptr %return, ptr %.loc30_10.1.temp, ptr %b), !dbg !33
+// CHECK:STDOUT:   call void @"_COp.Number.Main:MulWith.44027391c5135f93.Core"(ptr %return, ptr %.loc30_10.1.temp, ptr %b), !dbg !33
 // CHECK:STDOUT:   ret void, !dbg !34
 // CHECK:STDOUT:   ret void, !dbg !34
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -124,7 +124,7 @@ fn Calculate(a: Number, b: Number) -> Number {
 // CHECK:STDOUT: !11 = !DILocation(line: 19, column: 28, scope: !4)
 // CHECK:STDOUT: !11 = !DILocation(line: 19, column: 28, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 19, column: 12, scope: !4)
 // CHECK:STDOUT: !12 = !DILocation(line: 19, column: 12, scope: !4)
 // CHECK:STDOUT: !13 = !DILocation(line: 19, column: 5, scope: !4)
 // CHECK:STDOUT: !13 = !DILocation(line: 19, column: 5, scope: !4)
-// CHECK:STDOUT: !14 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Number.Main:MulWith.Core", scope: null, file: !3, line: 23, type: !15, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17)
+// CHECK:STDOUT: !14 = distinct !DISubprogram(name: "Op", linkageName: "_COp.Number.Main:MulWith.44027391c5135f93.Core", scope: null, file: !3, line: 23, type: !15, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17)
 // CHECK:STDOUT: !15 = !DISubroutineType(types: !16)
 // CHECK:STDOUT: !15 = !DISubroutineType(types: !16)
 // CHECK:STDOUT: !16 = !{!7, !7, !7}
 // CHECK:STDOUT: !16 = !{!7, !7, !7}
 // CHECK:STDOUT: !17 = !{!18, !19}
 // CHECK:STDOUT: !17 = !{!18, !19}

+ 44 - 44
toolchain/lower/testdata/primitives/optional.carbon

@@ -43,7 +43,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: if.then:                                          ; preds = %entry
 // CHECK:STDOUT: if.then:                                          ; preds = %entry
 // CHECK:STDOUT:   %Optional.Get.call = call ptr @_CGet.Optional.Core.cb8cde10e3c2d324(ptr %o), !dbg !12
 // CHECK:STDOUT:   %Optional.Get.call = call ptr @_CGet.Optional.Core.cb8cde10e3c2d324(ptr %o), !dbg !12
 // CHECK:STDOUT:   %.loc18_12.2 = load i32, ptr %Optional.Get.call, align 4, !dbg !13
 // CHECK:STDOUT:   %.loc18_12.2 = load i32, ptr %Optional.Get.call, align 4, !dbg !13
-// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.622e77b643a0d3a8"(ptr %return, i32 %.loc18_12.2), !dbg !14
+// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.622e77b643a0d3a8"(ptr %return, i32 %.loc18_12.2), !dbg !14
 // CHECK:STDOUT:   ret void, !dbg !14
 // CHECK:STDOUT:   ret void, !dbg !14
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: if.else:                                          ; preds = %entry
 // CHECK:STDOUT: if.else:                                          ; preds = %entry
@@ -63,21 +63,21 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT:   %_.var.loc30 = alloca { i32, i1 }, align 8, !dbg !30
 // CHECK:STDOUT:   %_.var.loc30 = alloca { i32, i1 }, align 8, !dbg !30
 // CHECK:STDOUT:   %_.var.loc31 = alloca { i32, i1 }, align 8, !dbg !31
 // CHECK:STDOUT:   %_.var.loc31 = alloca { i32, i1 }, align 8, !dbg !31
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc24), !dbg !24
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc24), !dbg !24
-// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.622e77b643a0d3a8"(ptr %_.var.loc24, i32 %a), !dbg !24
+// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.622e77b643a0d3a8"(ptr %_.var.loc24, i32 %a), !dbg !24
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc25), !dbg !25
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc25), !dbg !25
-// CHECK:STDOUT:   call void @"_CConvert.a44fce96e16342e7:ImplicitAs.Core.bd3a79eb4ffd3025"(ptr %_.var.loc25, i32 %a), !dbg !25
+// CHECK:STDOUT:   call void @"_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.bd3a79eb4ffd3025"(ptr %_.var.loc25, i32 %a), !dbg !25
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc26), !dbg !26
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc26), !dbg !26
-// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.a7b795aef3d7a0e5"(ptr %_.var.loc26, i32 %a), !dbg !26
+// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.a7b795aef3d7a0e5"(ptr %_.var.loc26, i32 %a), !dbg !26
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc27), !dbg !27
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc27), !dbg !27
-// CHECK:STDOUT:   call void @"_CConvert.a44fce96e16342e7:ImplicitAs.Core.b37806f50d6ac6f2"(ptr %_.var.loc27, i32 %a), !dbg !27
+// CHECK:STDOUT:   call void @"_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.b37806f50d6ac6f2"(ptr %_.var.loc27, i32 %a), !dbg !27
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc28), !dbg !28
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc28), !dbg !28
-// CHECK:STDOUT:   call void @"_CConvert.17f42c13d842b71d:ImplicitAs.Core.bd3a79eb4ffd3025"(ptr %_.var.loc28, i32 %b), !dbg !28
+// CHECK:STDOUT:   call void @"_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.bd3a79eb4ffd3025"(ptr %_.var.loc28, i32 %b), !dbg !28
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc29), !dbg !29
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc29), !dbg !29
-// CHECK:STDOUT:   call void @"_CConvert.17f42c13d842b71d:ImplicitAs.Core.fdb5566b9a89e24d"(ptr %_.var.loc29, i32 %b), !dbg !29
+// CHECK:STDOUT:   call void @"_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.fdb5566b9a89e24d"(ptr %_.var.loc29, i32 %b), !dbg !29
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc30), !dbg !30
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc30), !dbg !30
-// CHECK:STDOUT:   call void @"_CConvert.17f42c13d842b71d:ImplicitAs.Core.b37806f50d6ac6f2"(ptr %_.var.loc30, i32 %b), !dbg !30
+// CHECK:STDOUT:   call void @"_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.b37806f50d6ac6f2"(ptr %_.var.loc30, i32 %b), !dbg !30
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc31), !dbg !31
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %_.var.loc31), !dbg !31
-// CHECK:STDOUT:   call void @"_CConvert.17f42c13d842b71d:ImplicitAs.Core.5fb98646c26c8976"(ptr %_.var.loc31, i32 %b), !dbg !31
+// CHECK:STDOUT:   call void @"_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.5fb98646c26c8976"(ptr %_.var.loc31, i32 %b), !dbg !31
 // CHECK:STDOUT:   ret void, !dbg !32
 // CHECK:STDOUT:   ret void, !dbg !32
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -94,8 +94,8 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.622e77b643a0d3a8"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !44 {
-// CHECK:STDOUT:   call void @"_CConvert.90961d7b1ce4f089:OptionalAs.Core.d4e523823e737747"(ptr %return, i32 %self), !dbg !49
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.622e77b643a0d3a8"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !44 {
+// CHECK:STDOUT:   call void @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.d4e523823e737747"(ptr %return, i32 %self), !dbg !49
 // CHECK:STDOUT:   ret void, !dbg !50
 // CHECK:STDOUT:   ret void, !dbg !50
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -109,48 +109,48 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.a44fce96e16342e7:ImplicitAs.Core.bd3a79eb4ffd3025"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !56 {
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.bd3a79eb4ffd3025"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !56 {
 // CHECK:STDOUT:   %temp = alloca { i32, i1 }, align 8, !dbg !60
 // CHECK:STDOUT:   %temp = alloca { i32, i1 }, align 8, !dbg !60
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %temp), !dbg !60
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %temp), !dbg !60
-// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.622e77b643a0d3a8"(ptr %temp, i32 %self), !dbg !60
+// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.622e77b643a0d3a8"(ptr %temp, i32 %self), !dbg !60
 // CHECK:STDOUT:   ret void, !dbg !61
 // CHECK:STDOUT:   ret void, !dbg !61
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.a7b795aef3d7a0e5"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !62 {
-// CHECK:STDOUT:   call void @"_CConvert.3667eb502d1ddfa9:OptionalAs.Core.dbad48707eb766d5"(ptr %return, i32 %self), !dbg !65
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.a7b795aef3d7a0e5"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !62 {
+// CHECK:STDOUT:   call void @"_CConvert.3667eb502d1ddfa9:OptionalAs.c7a50af9bdd61b43.Core.dbad48707eb766d5"(ptr %return, i32 %self), !dbg !65
 // CHECK:STDOUT:   ret void, !dbg !66
 // CHECK:STDOUT:   ret void, !dbg !66
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.a44fce96e16342e7:ImplicitAs.Core.b37806f50d6ac6f2"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !67 {
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.b37806f50d6ac6f2"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !67 {
 // CHECK:STDOUT:   %temp = alloca { i32, i1 }, align 8, !dbg !70
 // CHECK:STDOUT:   %temp = alloca { i32, i1 }, align 8, !dbg !70
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %temp), !dbg !70
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %temp), !dbg !70
-// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.a7b795aef3d7a0e5"(ptr %temp, i32 %self), !dbg !70
+// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.a7b795aef3d7a0e5"(ptr %temp, i32 %self), !dbg !70
 // CHECK:STDOUT:   ret void, !dbg !71
 // CHECK:STDOUT:   ret void, !dbg !71
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.17f42c13d842b71d:ImplicitAs.Core.bd3a79eb4ffd3025"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !72 {
-// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.622e77b643a0d3a8"(ptr %return, i32 %self), !dbg !75
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.bd3a79eb4ffd3025"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !72 {
+// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.622e77b643a0d3a8"(ptr %return, i32 %self), !dbg !75
 // CHECK:STDOUT:   ret void, !dbg !76
 // CHECK:STDOUT:   ret void, !dbg !76
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.17f42c13d842b71d:ImplicitAs.Core.fdb5566b9a89e24d"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !77 {
-// CHECK:STDOUT:   call void @"_CConvert.a44fce96e16342e7:ImplicitAs.Core.bd3a79eb4ffd3025"(ptr %return, i32 %self), !dbg !80
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.fdb5566b9a89e24d"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !77 {
+// CHECK:STDOUT:   call void @"_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.bd3a79eb4ffd3025"(ptr %return, i32 %self), !dbg !80
 // CHECK:STDOUT:   ret void, !dbg !81
 // CHECK:STDOUT:   ret void, !dbg !81
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.17f42c13d842b71d:ImplicitAs.Core.b37806f50d6ac6f2"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !82 {
-// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.a7b795aef3d7a0e5"(ptr %return, i32 %self), !dbg !85
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.b37806f50d6ac6f2"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !82 {
+// CHECK:STDOUT:   call void @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.a7b795aef3d7a0e5"(ptr %return, i32 %self), !dbg !85
 // CHECK:STDOUT:   ret void, !dbg !86
 // CHECK:STDOUT:   ret void, !dbg !86
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.17f42c13d842b71d:ImplicitAs.Core.5fb98646c26c8976"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !87 {
-// CHECK:STDOUT:   call void @"_CConvert.a44fce96e16342e7:ImplicitAs.Core.b37806f50d6ac6f2"(ptr %return, i32 %self), !dbg !90
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.5fb98646c26c8976"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !87 {
+// CHECK:STDOUT:   call void @"_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.b37806f50d6ac6f2"(ptr %return, i32 %self), !dbg !90
 // CHECK:STDOUT:   ret void, !dbg !91
 // CHECK:STDOUT:   ret void, !dbg !91
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -160,7 +160,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.90961d7b1ce4f089:OptionalAs.Core.d4e523823e737747"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !96 {
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.d4e523823e737747"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !96 {
 // CHECK:STDOUT:   call void @_CSome.Optional.Core.d4e523823e737747(ptr %return, i32 %self), !dbg !99
 // CHECK:STDOUT:   call void @_CSome.Optional.Core.d4e523823e737747(ptr %return, i32 %self), !dbg !99
 // CHECK:STDOUT:   ret void, !dbg !100
 // CHECK:STDOUT:   ret void, !dbg !100
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
@@ -173,10 +173,10 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr void @"_CConvert.3667eb502d1ddfa9:OptionalAs.Core.dbad48707eb766d5"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !104 {
+// CHECK:STDOUT: define linkonce_odr void @"_CConvert.3667eb502d1ddfa9:OptionalAs.c7a50af9bdd61b43.Core.dbad48707eb766d5"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !104 {
 // CHECK:STDOUT:   %temp = alloca i32, align 4, !dbg !107
 // CHECK:STDOUT:   %temp = alloca i32, align 4, !dbg !107
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %temp), !dbg !107
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %temp), !dbg !107
-// CHECK:STDOUT:   %1 = call i32 @"_CConvert.a44fce96e16342e7:ImplicitAs.Core.b930bfdac0979466"(i32 %self), !dbg !107
+// CHECK:STDOUT:   %1 = call i32 @"_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.b930bfdac0979466"(i32 %self), !dbg !107
 // CHECK:STDOUT:   store i32 %1, ptr %temp, align 4, !dbg !107
 // CHECK:STDOUT:   store i32 %1, ptr %temp, align 4, !dbg !107
 // CHECK:STDOUT:   %2 = load i32, ptr %temp, align 4, !dbg !107
 // CHECK:STDOUT:   %2 = load i32, ptr %temp, align 4, !dbg !107
 // CHECK:STDOUT:   call void @_CSome.Optional.Core.2a814810f68c37ba(ptr %return, i32 %2), !dbg !108
 // CHECK:STDOUT:   call void @_CSome.Optional.Core.2a814810f68c37ba(ptr %return, i32 %2), !dbg !108
@@ -190,10 +190,10 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.a44fce96e16342e7:ImplicitAs.Core.b930bfdac0979466"(i32 %self) #0 !dbg !115 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.b930bfdac0979466"(i32 %self) #0 !dbg !115 {
 // CHECK:STDOUT:   %temp = alloca i32, align 4, !dbg !118
 // CHECK:STDOUT:   %temp = alloca i32, align 4, !dbg !118
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %temp), !dbg !118
 // CHECK:STDOUT:   call void @llvm.lifetime.start.p0(ptr %temp), !dbg !118
-// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e"(i32 %self), !dbg !118
+// CHECK:STDOUT:   %1 = call i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e"(i32 %self), !dbg !118
 // CHECK:STDOUT:   ret i32 %1, !dbg !119
 // CHECK:STDOUT:   ret i32 %1, !dbg !119
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -213,7 +213,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; Function Attrs: nounwind
 // CHECK:STDOUT: ; Function Attrs: nounwind
-// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e"(i32 %self) #0 !dbg !131 {
+// CHECK:STDOUT: define linkonce_odr i32 @"_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e"(i32 %self) #0 !dbg !131 {
 // CHECK:STDOUT:   ret i32 %self, !dbg !136
 // CHECK:STDOUT:   ret i32 %self, !dbg !136
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
@@ -233,7 +233,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: ; uselistorder directives
 // CHECK:STDOUT: ; uselistorder directives
-// CHECK:STDOUT: uselistorder ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.622e77b643a0d3a8", { 0, 1, 3, 2 }
+// CHECK:STDOUT: uselistorder ptr @"_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.622e77b643a0d3a8", { 0, 1, 3, 2 }
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4 }
 // CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4 }
 // CHECK:STDOUT:
 // CHECK:STDOUT:
 // CHECK:STDOUT: attributes #0 = { nounwind }
 // CHECK:STDOUT: attributes #0 = { nounwind }
@@ -286,7 +286,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: !41 = !DILocalVariable(arg: 1, scope: !39, type: !7)
 // CHECK:STDOUT: !41 = !DILocalVariable(arg: 1, scope: !39, type: !7)
 // CHECK:STDOUT: !42 = !DILocation(line: 36, column: 12, scope: !39)
 // CHECK:STDOUT: !42 = !DILocation(line: 36, column: 12, scope: !39)
 // CHECK:STDOUT: !43 = !DILocation(line: 36, column: 5, scope: !39)
 // CHECK:STDOUT: !43 = !DILocation(line: 36, column: 5, scope: !39)
-// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.622e77b643a0d3a8", scope: null, file: !34, line: 82, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !47)
+// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.622e77b643a0d3a8", scope: null, file: !34, line: 82, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !47)
 // CHECK:STDOUT: !45 = !DISubroutineType(types: !46)
 // CHECK:STDOUT: !45 = !DISubroutineType(types: !46)
 // CHECK:STDOUT: !46 = !{!7, !20}
 // CHECK:STDOUT: !46 = !{!7, !20}
 // CHECK:STDOUT: !47 = !{!48}
 // CHECK:STDOUT: !47 = !{!48}
@@ -298,38 +298,38 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: !53 = !{!7}
 // CHECK:STDOUT: !53 = !{!7}
 // CHECK:STDOUT: !54 = !DILocation(line: 27, column: 12, scope: !51)
 // CHECK:STDOUT: !54 = !DILocation(line: 27, column: 12, scope: !51)
 // CHECK:STDOUT: !55 = !DILocation(line: 27, column: 5, scope: !51)
 // CHECK:STDOUT: !55 = !DILocation(line: 27, column: 5, scope: !51)
-// CHECK:STDOUT: !56 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.a44fce96e16342e7:ImplicitAs.Core.bd3a79eb4ffd3025", scope: null, file: !57, line: 28, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !58)
+// CHECK:STDOUT: !56 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.bd3a79eb4ffd3025", scope: null, file: !57, line: 28, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !58)
 // CHECK:STDOUT: !57 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !57 = !DIFile(filename: "{{.*}}/prelude/operators/as.carbon", directory: "")
 // CHECK:STDOUT: !58 = !{!59}
 // CHECK:STDOUT: !58 = !{!59}
 // CHECK:STDOUT: !59 = !DILocalVariable(arg: 1, scope: !56, type: !20)
 // CHECK:STDOUT: !59 = !DILocalVariable(arg: 1, scope: !56, type: !20)
 // CHECK:STDOUT: !60 = !DILocation(line: 28, column: 45, scope: !56)
 // CHECK:STDOUT: !60 = !DILocation(line: 28, column: 45, scope: !56)
 // CHECK:STDOUT: !61 = !DILocation(line: 28, column: 38, scope: !56)
 // CHECK:STDOUT: !61 = !DILocation(line: 28, column: 38, scope: !56)
-// CHECK:STDOUT: !62 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.Core.a7b795aef3d7a0e5", scope: null, file: !34, line: 82, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !63)
+// CHECK:STDOUT: !62 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.e5cf8fcbb4feaae2:ImplicitAs.0f95c9e18c91e00a.Core.a7b795aef3d7a0e5", scope: null, file: !34, line: 82, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !63)
 // CHECK:STDOUT: !63 = !{!64}
 // CHECK:STDOUT: !63 = !{!64}
 // CHECK:STDOUT: !64 = !DILocalVariable(arg: 1, scope: !62, type: !20)
 // CHECK:STDOUT: !64 = !DILocalVariable(arg: 1, scope: !62, type: !20)
 // CHECK:STDOUT: !65 = !DILocation(line: 83, column: 12, scope: !62)
 // CHECK:STDOUT: !65 = !DILocation(line: 83, column: 12, scope: !62)
 // CHECK:STDOUT: !66 = !DILocation(line: 83, column: 5, scope: !62)
 // CHECK:STDOUT: !66 = !DILocation(line: 83, column: 5, scope: !62)
-// CHECK:STDOUT: !67 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.a44fce96e16342e7:ImplicitAs.Core.b37806f50d6ac6f2", scope: null, file: !57, line: 28, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !68)
+// CHECK:STDOUT: !67 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.b37806f50d6ac6f2", scope: null, file: !57, line: 28, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !68)
 // CHECK:STDOUT: !68 = !{!69}
 // CHECK:STDOUT: !68 = !{!69}
 // CHECK:STDOUT: !69 = !DILocalVariable(arg: 1, scope: !67, type: !20)
 // CHECK:STDOUT: !69 = !DILocalVariable(arg: 1, scope: !67, type: !20)
 // CHECK:STDOUT: !70 = !DILocation(line: 28, column: 45, scope: !67)
 // CHECK:STDOUT: !70 = !DILocation(line: 28, column: 45, scope: !67)
 // CHECK:STDOUT: !71 = !DILocation(line: 28, column: 38, scope: !67)
 // CHECK:STDOUT: !71 = !DILocation(line: 28, column: 38, scope: !67)
-// CHECK:STDOUT: !72 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.17f42c13d842b71d:ImplicitAs.Core.bd3a79eb4ffd3025", scope: null, file: !57, line: 32, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !73)
+// CHECK:STDOUT: !72 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.bd3a79eb4ffd3025", scope: null, file: !57, line: 32, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !73)
 // CHECK:STDOUT: !73 = !{!74}
 // CHECK:STDOUT: !73 = !{!74}
 // CHECK:STDOUT: !74 = !DILocalVariable(arg: 1, scope: !72, type: !20)
 // CHECK:STDOUT: !74 = !DILocalVariable(arg: 1, scope: !72, type: !20)
 // CHECK:STDOUT: !75 = !DILocation(line: 32, column: 45, scope: !72)
 // CHECK:STDOUT: !75 = !DILocation(line: 32, column: 45, scope: !72)
 // CHECK:STDOUT: !76 = !DILocation(line: 32, column: 38, scope: !72)
 // CHECK:STDOUT: !76 = !DILocation(line: 32, column: 38, scope: !72)
-// CHECK:STDOUT: !77 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.17f42c13d842b71d:ImplicitAs.Core.fdb5566b9a89e24d", scope: null, file: !57, line: 32, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !78)
+// CHECK:STDOUT: !77 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.fdb5566b9a89e24d", scope: null, file: !57, line: 32, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !78)
 // CHECK:STDOUT: !78 = !{!79}
 // CHECK:STDOUT: !78 = !{!79}
 // CHECK:STDOUT: !79 = !DILocalVariable(arg: 1, scope: !77, type: !20)
 // CHECK:STDOUT: !79 = !DILocalVariable(arg: 1, scope: !77, type: !20)
 // CHECK:STDOUT: !80 = !DILocation(line: 32, column: 45, scope: !77)
 // CHECK:STDOUT: !80 = !DILocation(line: 32, column: 45, scope: !77)
 // CHECK:STDOUT: !81 = !DILocation(line: 32, column: 38, scope: !77)
 // CHECK:STDOUT: !81 = !DILocation(line: 32, column: 38, scope: !77)
-// CHECK:STDOUT: !82 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.17f42c13d842b71d:ImplicitAs.Core.b37806f50d6ac6f2", scope: null, file: !57, line: 32, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83)
+// CHECK:STDOUT: !82 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.b37806f50d6ac6f2", scope: null, file: !57, line: 32, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83)
 // CHECK:STDOUT: !83 = !{!84}
 // CHECK:STDOUT: !83 = !{!84}
 // CHECK:STDOUT: !84 = !DILocalVariable(arg: 1, scope: !82, type: !20)
 // CHECK:STDOUT: !84 = !DILocalVariable(arg: 1, scope: !82, type: !20)
 // CHECK:STDOUT: !85 = !DILocation(line: 32, column: 45, scope: !82)
 // CHECK:STDOUT: !85 = !DILocation(line: 32, column: 45, scope: !82)
 // CHECK:STDOUT: !86 = !DILocation(line: 32, column: 38, scope: !82)
 // CHECK:STDOUT: !86 = !DILocation(line: 32, column: 38, scope: !82)
-// CHECK:STDOUT: !87 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.17f42c13d842b71d:ImplicitAs.Core.5fb98646c26c8976", scope: null, file: !57, line: 32, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !88)
+// CHECK:STDOUT: !87 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.17f42c13d842b71d:ImplicitAs.eb057aa32837c84e.Core.5fb98646c26c8976", scope: null, file: !57, line: 32, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !88)
 // CHECK:STDOUT: !88 = !{!89}
 // CHECK:STDOUT: !88 = !{!89}
 // CHECK:STDOUT: !89 = !DILocalVariable(arg: 1, scope: !87, type: !20)
 // CHECK:STDOUT: !89 = !DILocalVariable(arg: 1, scope: !87, type: !20)
 // CHECK:STDOUT: !90 = !DILocation(line: 32, column: 45, scope: !87)
 // CHECK:STDOUT: !90 = !DILocation(line: 32, column: 45, scope: !87)
@@ -338,7 +338,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: !93 = !{!94}
 // CHECK:STDOUT: !93 = !{!94}
 // CHECK:STDOUT: !94 = !DILocalVariable(arg: 1, scope: !92, type: !7)
 // CHECK:STDOUT: !94 = !DILocalVariable(arg: 1, scope: !92, type: !7)
 // CHECK:STDOUT: !95 = !DILocation(line: 132, column: 5, scope: !92)
 // CHECK:STDOUT: !95 = !DILocation(line: 132, column: 5, scope: !92)
-// CHECK:STDOUT: !96 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.90961d7b1ce4f089:OptionalAs.Core.d4e523823e737747", scope: null, file: !34, line: 68, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !97)
+// CHECK:STDOUT: !96 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.90961d7b1ce4f089:OptionalAs.0e326e799dad0c64.Core.d4e523823e737747", scope: null, file: !34, line: 68, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !97)
 // CHECK:STDOUT: !97 = !{!98}
 // CHECK:STDOUT: !97 = !{!98}
 // CHECK:STDOUT: !98 = !DILocalVariable(arg: 1, scope: !96, type: !20)
 // CHECK:STDOUT: !98 = !DILocalVariable(arg: 1, scope: !96, type: !20)
 // CHECK:STDOUT: !99 = !DILocation(line: 69, column: 12, scope: !96)
 // CHECK:STDOUT: !99 = !DILocation(line: 69, column: 12, scope: !96)
@@ -346,7 +346,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: !101 = distinct !DISubprogram(name: "None", linkageName: "_CNone.3e8267224c5dc9c2:OptionalStorage.Core.329e9a7481f16207", scope: null, file: !34, line: 99, type: !52, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !101 = distinct !DISubprogram(name: "None", linkageName: "_CNone.3e8267224c5dc9c2:OptionalStorage.Core.329e9a7481f16207", scope: null, file: !34, line: 99, type: !52, spFlags: DISPFlagDefinition, unit: !2)
 // CHECK:STDOUT: !102 = !DILocation(line: 101, column: 5, scope: !101)
 // CHECK:STDOUT: !102 = !DILocation(line: 101, column: 5, scope: !101)
 // CHECK:STDOUT: !103 = !DILocation(line: 102, column: 5, scope: !101)
 // CHECK:STDOUT: !103 = !DILocation(line: 102, column: 5, scope: !101)
-// CHECK:STDOUT: !104 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.3667eb502d1ddfa9:OptionalAs.Core.dbad48707eb766d5", scope: null, file: !34, line: 75, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !105)
+// CHECK:STDOUT: !104 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.3667eb502d1ddfa9:OptionalAs.c7a50af9bdd61b43.Core.dbad48707eb766d5", scope: null, file: !34, line: 75, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !105)
 // CHECK:STDOUT: !105 = !{!106}
 // CHECK:STDOUT: !105 = !{!106}
 // CHECK:STDOUT: !106 = !DILocalVariable(arg: 1, scope: !104, type: !20)
 // CHECK:STDOUT: !106 = !DILocalVariable(arg: 1, scope: !104, type: !20)
 // CHECK:STDOUT: !107 = !DILocation(line: 76, column: 29, scope: !104)
 // CHECK:STDOUT: !107 = !DILocation(line: 76, column: 29, scope: !104)
@@ -357,7 +357,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: !112 = !DILocalVariable(arg: 1, scope: !110, type: !20)
 // CHECK:STDOUT: !112 = !DILocalVariable(arg: 1, scope: !110, type: !20)
 // CHECK:STDOUT: !113 = !DILocation(line: 30, column: 12, scope: !110)
 // CHECK:STDOUT: !113 = !DILocation(line: 30, column: 12, scope: !110)
 // CHECK:STDOUT: !114 = !DILocation(line: 30, column: 5, scope: !110)
 // CHECK:STDOUT: !114 = !DILocation(line: 30, column: 5, scope: !110)
-// CHECK:STDOUT: !115 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.a44fce96e16342e7:ImplicitAs.Core.b930bfdac0979466", scope: null, file: !57, line: 28, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !116)
+// CHECK:STDOUT: !115 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.a44fce96e16342e7:ImplicitAs.ad22d1bbc0605210.Core.b930bfdac0979466", scope: null, file: !57, line: 28, type: !45, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !116)
 // CHECK:STDOUT: !116 = !{!117}
 // CHECK:STDOUT: !116 = !{!117}
 // CHECK:STDOUT: !117 = !DILocalVariable(arg: 1, scope: !115, type: !20)
 // CHECK:STDOUT: !117 = !DILocalVariable(arg: 1, scope: !115, type: !20)
 // CHECK:STDOUT: !118 = !DILocation(line: 28, column: 45, scope: !115)
 // CHECK:STDOUT: !118 = !DILocation(line: 28, column: 45, scope: !115)
@@ -373,7 +373,7 @@ fn AddOrRemoveConst(a: i32, b: const i32) {
 // CHECK:STDOUT: !128 = !DILocation(line: 108, column: 5, scope: !125)
 // CHECK:STDOUT: !128 = !DILocation(line: 108, column: 5, scope: !125)
 // CHECK:STDOUT: !129 = !DILocation(line: 109, column: 5, scope: !125)
 // CHECK:STDOUT: !129 = !DILocation(line: 109, column: 5, scope: !125)
 // CHECK:STDOUT: !130 = !DILocation(line: 110, column: 5, scope: !125)
 // CHECK:STDOUT: !130 = !DILocation(line: 110, column: 5, scope: !125)
-// CHECK:STDOUT: !131 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.Core.64ccbb8e5d9a0b8e", scope: null, file: !57, line: 24, type: !132, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !134)
+// CHECK:STDOUT: !131 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.14b8745117b2bc54:ImplicitAs.a9271c1e04015f9c.Core.64ccbb8e5d9a0b8e", scope: null, file: !57, line: 24, type: !132, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !134)
 // CHECK:STDOUT: !132 = !DISubroutineType(types: !133)
 // CHECK:STDOUT: !132 = !DISubroutineType(types: !133)
 // CHECK:STDOUT: !133 = !{!20, !20}
 // CHECK:STDOUT: !133 = !{!20, !20}
 // CHECK:STDOUT: !134 = !{!135}
 // CHECK:STDOUT: !134 = !{!135}