1; RUN: opt < %s -instcombine -S | FileCheck %s
2
3@test.data = private unnamed_addr addrspace(2) constant [8 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7], align 4
4
5; CHECK-LABEL: test_load
6; CHECK: %[[GEP:.*]] = getelementptr [8 x i32], [8 x i32] addrspace(2)* @test.data, i64 0, i64 %x
7; CHECK: %{{.*}} = load i32, i32 addrspace(2)* %[[GEP]]
8; CHECK-NOT: alloca
9; CHECK-NOT: call void @llvm.memcpy.p0i8.p2i8.i64
10; CHECK-NOT: addrspacecast
11; CHECK-NOT: load i32, i32*
12define void @test_load(i32 addrspace(1)* %out, i64 %x) {
13entry:
14  %data = alloca [8 x i32], align 4
15  %0 = bitcast [8 x i32]* %data to i8*
16  call void @llvm.memcpy.p0i8.p2i8.i64(i8* align 4 %0, i8 addrspace(2)* align 4 bitcast ([8 x i32] addrspace(2)* @test.data to i8 addrspace(2)*), i64 32, i1 false)
17  %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* %data, i64 0, i64 %x
18  %1 = load i32, i32* %arrayidx, align 4
19  %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %x
20  store i32 %1, i32 addrspace(1)* %arrayidx1, align 4
21  ret void
22}
23
24; CHECK-LABEL: test_load_bitcast_chain
25; CHECK: %[[GEP:.*]] = getelementptr [8 x i32], [8 x i32] addrspace(2)* @test.data, i64 0, i64 %x
26; CHECK: %{{.*}} = load i32, i32 addrspace(2)* %[[GEP]]
27; CHECK-NOT: alloca
28; CHECK-NOT: call void @llvm.memcpy.p0i8.p2i8.i64
29; CHECK-NOT: addrspacecast
30; CHECK-NOT: load i32, i32*
31define void @test_load_bitcast_chain(i32 addrspace(1)* %out, i64 %x) {
32entry:
33  %data = alloca [8 x i32], align 4
34  %0 = bitcast [8 x i32]* %data to i8*
35  call void @llvm.memcpy.p0i8.p2i8.i64(i8* align 4 %0, i8 addrspace(2)* align 4 bitcast ([8 x i32] addrspace(2)* @test.data to i8 addrspace(2)*), i64 32, i1 false)
36  %1 = bitcast i8* %0 to i32*
37  %arrayidx = getelementptr inbounds i32, i32* %1, i64 %x
38  %2 = load i32, i32* %arrayidx, align 4
39  %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %x
40  store i32 %2, i32 addrspace(1)* %arrayidx1, align 4
41  ret void
42}
43
44; CHECK-LABEL: test_call
45; CHECK: alloca
46; CHECK: call void @llvm.memcpy.p0i8.p2i8.i64
47; CHECK-NOT: addrspacecast
48; CHECK: call i32 @foo(i32* nonnull %{{.*}})
49define void @test_call(i32 addrspace(1)* %out, i64 %x) {
50entry:
51  %data = alloca [8 x i32], align 4
52  %0 = bitcast [8 x i32]* %data to i8*
53  call void @llvm.memcpy.p0i8.p2i8.i64(i8* align 4 %0, i8 addrspace(2)* align 4 bitcast ([8 x i32] addrspace(2)* @test.data to i8 addrspace(2)*), i64 32, i1 false)
54  %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* %data, i64 0, i64 %x
55  %1 = call i32 @foo(i32* %arrayidx)
56  %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %x
57  store i32 %1, i32 addrspace(1)* %arrayidx1, align 4
58  ret void
59}
60
61; CHECK-LABEL: test_call_no_null_opt
62; CHECK: alloca
63; CHECK: call void @llvm.memcpy.p0i8.p2i8.i64
64; CHECK-NOT: addrspacecast
65; CHECK: call i32 @foo(i32* %{{.*}})
66define void @test_call_no_null_opt(i32 addrspace(1)* %out, i64 %x) #0 {
67entry:
68  %data = alloca [8 x i32], align 4
69  %0 = bitcast [8 x i32]* %data to i8*
70  call void @llvm.memcpy.p0i8.p2i8.i64(i8* align 4 %0, i8 addrspace(2)* align 4 bitcast ([8 x i32] addrspace(2)* @test.data to i8 addrspace(2)*), i64 32, i1 false)
71  %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* %data, i64 0, i64 %x
72  %1 = call i32 @foo(i32* %arrayidx)
73  %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %x
74  store i32 %1, i32 addrspace(1)* %arrayidx1, align 4
75  ret void
76}
77
78; CHECK-LABEL: test_load_and_call
79; CHECK: alloca
80; CHECK: call void @llvm.memcpy.p0i8.p2i8.i64
81; CHECK: load i32, i32* %{{.*}}
82; CHECK: call i32 @foo(i32* nonnull %{{.*}})
83; CHECK-NOT: addrspacecast
84; CHECK-NOT: load i32, i32 addrspace(2)*
85define void @test_load_and_call(i32 addrspace(1)* %out, i64 %x, i64 %y) {
86entry:
87  %data = alloca [8 x i32], align 4
88  %0 = bitcast [8 x i32]* %data to i8*
89  call void @llvm.memcpy.p0i8.p2i8.i64(i8* align 4 %0, i8 addrspace(2)* align 4 bitcast ([8 x i32] addrspace(2)* @test.data to i8 addrspace(2)*), i64 32, i1 false)
90  %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* %data, i64 0, i64 %x
91  %1 = load i32, i32* %arrayidx, align 4
92  %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %x
93  store i32 %1, i32 addrspace(1)* %arrayidx1, align 4
94  %2 = call i32 @foo(i32* %arrayidx)
95  %arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %y
96  store i32 %2, i32 addrspace(1)* %arrayidx2, align 4
97  ret void
98}
99
100; CHECK-LABEL: test_load_and_call_no_null_opt
101; CHECK: alloca
102; CHECK: call void @llvm.memcpy.p0i8.p2i8.i64
103; CHECK: load i32, i32* %{{.*}}
104; CHECK: call i32 @foo(i32* %{{.*}})
105; CHECK-NOT: addrspacecast
106; CHECK-NOT: load i32, i32 addrspace(2)*
107define void @test_load_and_call_no_null_opt(i32 addrspace(1)* %out, i64 %x, i64 %y) #0 {
108entry:
109  %data = alloca [8 x i32], align 4
110  %0 = bitcast [8 x i32]* %data to i8*
111  call void @llvm.memcpy.p0i8.p2i8.i64(i8* align 4 %0, i8 addrspace(2)* align 4 bitcast ([8 x i32] addrspace(2)* @test.data to i8 addrspace(2)*), i64 32, i1 false)
112  %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* %data, i64 0, i64 %x
113  %1 = load i32, i32* %arrayidx, align 4
114  %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %x
115  store i32 %1, i32 addrspace(1)* %arrayidx1, align 4
116  %2 = call i32 @foo(i32* %arrayidx)
117  %arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %y
118  store i32 %2, i32 addrspace(1)* %arrayidx2, align 4
119  ret void
120}
121
122declare void @llvm.memcpy.p0i8.p2i8.i64(i8* nocapture writeonly, i8 addrspace(2)* nocapture readonly, i64, i1)
123declare i32 @foo(i32* %x)
124
125attributes #0 = { "null-pointer-is-valid"="true" }
126