@@ -1729,3 +1729,61 @@ define i32 @test_ret_only_capture() {
17291729 %v = load i32 , ptr %a
17301730 ret i32 %v
17311731}
1732+
1733+ declare ptr @captures_address_only (ptr captures(address))
1734+
1735+ ; Can transform: Only one address captured.
1736+ define void @test_captures_address_captures_none () {
1737+ ; CHECK-LABEL: define void @test_captures_address_captures_none() {
1738+ ; CHECK-NEXT: [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
1739+ ; CHECK-NEXT: store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1740+ ; CHECK-NEXT: call void @captures_address_only(ptr [[SRC]])
1741+ ; CHECK-NEXT: call void @use_nocapture(ptr [[SRC]])
1742+ ; CHECK-NEXT: ret void
1743+ ;
1744+ %src = alloca %struct.Foo , align 4
1745+ %dst = alloca %struct.Foo , align 4
1746+ store %struct.Foo { i32 10 , i32 20 , i32 30 }, ptr %src
1747+ call void @captures_address_only (ptr %src )
1748+ call void @llvm.memcpy.p0.p0.i64 (ptr align 4 %dst , ptr align 4 %src , i64 12 , i1 false )
1749+ call void @use_nocapture (ptr %dst )
1750+ ret void
1751+ }
1752+
1753+ ; Can transform: Only one address captured.
1754+ define void @test_captures_none_and_captures_address () {
1755+ ; CHECK-LABEL: define void @test_captures_none_and_captures_address() {
1756+ ; CHECK-NEXT: [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
1757+ ; CHECK-NEXT: store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1758+ ; CHECK-NEXT: call void @use_nocapture(ptr [[SRC]])
1759+ ; CHECK-NEXT: call void @captures_address_only(ptr [[SRC]])
1760+ ; CHECK-NEXT: ret void
1761+ ;
1762+ %src = alloca %struct.Foo , align 4
1763+ %dst = alloca %struct.Foo , align 4
1764+ store %struct.Foo { i32 10 , i32 20 , i32 30 }, ptr %src
1765+ call void @use_nocapture (ptr %src )
1766+ call void @llvm.memcpy.p0.p0.i64 (ptr align 4 %dst , ptr align 4 %src , i64 12 , i1 false )
1767+ call void @captures_address_only (ptr %dst )
1768+ ret void
1769+ }
1770+
1771+ ; Cannot transform: Both addresses captured.
1772+ define void @test_captures_address_and_captures_address () {
1773+ ; CHECK-LABEL: define void @test_captures_address_and_captures_address() {
1774+ ; CHECK-NEXT: [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
1775+ ; CHECK-NEXT: [[DST:%.*]] = alloca [[STRUCT_FOO]], align 4
1776+ ; CHECK-NEXT: store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1777+ ; CHECK-NEXT: call void @captures_address_only(ptr [[SRC]])
1778+ ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DST]], ptr align 4 [[SRC]], i64 12, i1 false)
1779+ ; CHECK-NEXT: call void @captures_address_only(ptr [[DST]])
1780+ ; CHECK-NEXT: ret void
1781+ ;
1782+ %src = alloca %struct.Foo , align 4
1783+ %dst = alloca %struct.Foo , align 4
1784+ store %struct.Foo { i32 10 , i32 20 , i32 30 }, ptr %src
1785+ call void @captures_address_only (ptr %src )
1786+ call void @llvm.memcpy.p0.p0.i64 (ptr align 4 %dst , ptr align 4 %src , i64 12 , i1 false )
1787+ call void @captures_address_only (ptr %dst )
1788+ ret void
1789+ }
0 commit comments