[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InferAddressSpaces / AMDGPU / infer-address-space.ll
blob3116fce33d0aff05938a6d195c367260de075207
1 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -infer-address-spaces %s | FileCheck %s
2 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=infer-address-spaces %s | FileCheck %s
3 ; Ports of most of test/CodeGen/NVPTX/access-non-generic.ll
5 @scalar = internal addrspace(3) global float 0.0, align 4
6 @array = internal addrspace(3) global [10 x float] zeroinitializer, align 4
8 ; CHECK-LABEL: @load_store_lds_f32(
9 ; CHECK: %tmp = load float, float addrspace(3)* @scalar, align 4
10 ; CHECK: call void @use(float %tmp)
11 ; CHECK: store float %v, float addrspace(3)* @scalar, align 4
12 ; CHECK: call void @llvm.amdgcn.s.barrier()
13 ; CHECK: %tmp2 = load float, float addrspace(3)* @scalar, align 4
14 ; CHECK: call void @use(float %tmp2)
15 ; CHECK: store float %v, float addrspace(3)* @scalar, align 4
16 ; CHECK: call void @llvm.amdgcn.s.barrier()
17 ; CHECK: %tmp3 = load float, float addrspace(3)* getelementptr inbounds ([10 x float], [10 x float] addrspace(3)* @array, i32 0, i32 5), align 4
18 ; CHECK: call void @use(float %tmp3)
19 ; CHECK: store float %v, float addrspace(3)* getelementptr inbounds ([10 x float], [10 x float] addrspace(3)* @array, i32 0, i32 5), align 4
20 ; CHECK: call void @llvm.amdgcn.s.barrier()
21 ; CHECK: %tmp4 = getelementptr inbounds [10 x float], [10 x float] addrspace(3)* @array, i32 0, i32 5
22 ; CHECK: %tmp5 = load float, float addrspace(3)* %tmp4, align 4
23 ; CHECK: call void @use(float %tmp5)
24 ; CHECK: store float %v, float addrspace(3)* %tmp4, align 4
25 ; CHECK: call void @llvm.amdgcn.s.barrier()
26 ; CHECK: %tmp7 = getelementptr inbounds [10 x float], [10 x float] addrspace(3)* @array, i32 0, i32 %i
27 ; CHECK: %tmp8 = load float, float addrspace(3)* %tmp7, align 4
28 ; CHECK: call void @use(float %tmp8)
29 ; CHECK: store float %v, float addrspace(3)* %tmp7, align 4
30 ; CHECK: call void @llvm.amdgcn.s.barrier()
31 ; CHECK: ret void
32 define amdgpu_kernel void @load_store_lds_f32(i32 %i, float %v) #0 {
33 bb:
34   %tmp = load float, float* addrspacecast (float addrspace(3)* @scalar to float*), align 4
35   call void @use(float %tmp)
36   store float %v, float* addrspacecast (float addrspace(3)* @scalar to float*), align 4
37   call void @llvm.amdgcn.s.barrier()
38   %tmp1 = addrspacecast float addrspace(3)* @scalar to float*
39   %tmp2 = load float, float* %tmp1, align 4
40   call void @use(float %tmp2)
41   store float %v, float* %tmp1, align 4
42   call void @llvm.amdgcn.s.barrier()
43   %tmp3 = load float, float* getelementptr inbounds ([10 x float], [10 x float]* addrspacecast ([10 x float] addrspace(3)* @array to [10 x float]*), i32 0, i32 5), align 4
44   call void @use(float %tmp3)
45   store float %v, float* getelementptr inbounds ([10 x float], [10 x float]* addrspacecast ([10 x float] addrspace(3)* @array to [10 x float]*), i32 0, i32 5), align 4
46   call void @llvm.amdgcn.s.barrier()
47   %tmp4 = getelementptr inbounds [10 x float], [10 x float]* addrspacecast ([10 x float] addrspace(3)* @array to [10 x float]*), i32 0, i32 5
48   %tmp5 = load float, float* %tmp4, align 4
49   call void @use(float %tmp5)
50   store float %v, float* %tmp4, align 4
51   call void @llvm.amdgcn.s.barrier()
52   %tmp6 = addrspacecast [10 x float] addrspace(3)* @array to [10 x float]*
53   %tmp7 = getelementptr inbounds [10 x float], [10 x float]* %tmp6, i32 0, i32 %i
54   %tmp8 = load float, float* %tmp7, align 4
55   call void @use(float %tmp8)
56   store float %v, float* %tmp7, align 4
57   call void @llvm.amdgcn.s.barrier()
58   ret void
61 ; CHECK-LABEL: @constexpr_load_int_from_float_lds(
62 ; CHECK: %tmp = load i32, i32 addrspace(3)* bitcast (float addrspace(3)* @scalar to i32 addrspace(3)*), align 4
63 define i32 @constexpr_load_int_from_float_lds() #0 {
64 bb:
65   %tmp = load i32, i32* addrspacecast (i32 addrspace(3)* bitcast (float addrspace(3)* @scalar to i32 addrspace(3)*) to i32*), align 4
66   ret i32 %tmp
69 ; CHECK-LABEL: @load_int_from_global_float(
70 ; CHECK: %tmp1 = getelementptr float, float addrspace(1)* %input, i32 %i
71 ; CHECK: %tmp2 = getelementptr float, float addrspace(1)* %tmp1, i32 %j
72 ; CHECK: %tmp3 = bitcast float addrspace(1)* %tmp2 to i32 addrspace(1)*
73 ; CHECK: %tmp4 = load i32, i32 addrspace(1)* %tmp3
74 ; CHECK: ret i32 %tmp4
75 define i32 @load_int_from_global_float(float addrspace(1)* %input, i32 %i, i32 %j) #0 {
76 bb:
77   %tmp = addrspacecast float addrspace(1)* %input to float*
78   %tmp1 = getelementptr float, float* %tmp, i32 %i
79   %tmp2 = getelementptr float, float* %tmp1, i32 %j
80   %tmp3 = bitcast float* %tmp2 to i32*
81   %tmp4 = load i32, i32* %tmp3
82   ret i32 %tmp4
85 ; CHECK-LABEL: @nested_const_expr(
86 ; CHECK: store i32 1, i32 addrspace(3)* bitcast (float addrspace(3)* getelementptr inbounds ([10 x float], [10 x float] addrspace(3)* @array, i64 0, i64 1) to i32 addrspace(3)*), align 4
87 define amdgpu_kernel void @nested_const_expr() #0 {
88   store i32 1, i32* bitcast (float* getelementptr ([10 x float], [10 x float]* addrspacecast ([10 x float] addrspace(3)* @array to [10 x float]*), i64 0, i64 1) to i32*), align 4
89   ret void
92 ; CHECK-LABEL: @rauw(
93 ; CHECK: %addr = getelementptr float, float addrspace(1)* %input, i64 10
94 ; CHECK-NEXT: %v = load float, float addrspace(1)* %addr
95 ; CHECK-NEXT: store float %v, float addrspace(1)* %addr
96 ; CHECK-NEXT: ret void
97 define amdgpu_kernel void @rauw(float addrspace(1)* %input) #0 {
98 bb:
99   %generic_input = addrspacecast float addrspace(1)* %input to float*
100   %addr = getelementptr float, float* %generic_input, i64 10
101   %v = load float, float* %addr
102   store float %v, float* %addr
103   ret void
106 ; FIXME: Should be able to eliminate the cast inside the loop
107 ; CHECK-LABEL: @loop(
109 ; CHECK: %p = bitcast [10 x float] addrspace(3)* @array to float addrspace(3)*
110 ; CHECK: %end = getelementptr float, float addrspace(3)* %p, i64 10
111 ; CHECK: br label %loop
113 ; CHECK: loop:                                             ; preds = %loop, %entry
114 ; CHECK: %i = phi float addrspace(3)* [ %p, %entry ], [ %i2, %loop ]
115 ; CHECK: %v = load float, float addrspace(3)* %i
116 ; CHECK: call void @use(float %v)
117 ; CHECK: %i2 = getelementptr float, float addrspace(3)* %i, i64 1
118 ; CHECK: %exit_cond = icmp eq float addrspace(3)* %i2, %end
120 ; CHECK: br i1 %exit_cond, label %exit, label %loop
121 define amdgpu_kernel void @loop() #0 {
122 entry:
123   %p = addrspacecast [10 x float] addrspace(3)* @array to float*
124   %end = getelementptr float, float* %p, i64 10
125   br label %loop
127 loop:                                             ; preds = %loop, %entry
128   %i = phi float* [ %p, %entry ], [ %i2, %loop ]
129   %v = load float, float* %i
130   call void @use(float %v)
131   %i2 = getelementptr float, float* %i, i64 1
132   %exit_cond = icmp eq float* %i2, %end
133   br i1 %exit_cond, label %exit, label %loop
135 exit:                                             ; preds = %loop
136   ret void
139 @generic_end = external addrspace(1) global float*
141 ; CHECK-LABEL: @loop_with_generic_bound(
142 ; CHECK: %p = bitcast [10 x float] addrspace(3)* @array to float addrspace(3)*
143 ; CHECK: %end = load float*, float* addrspace(1)* @generic_end
144 ; CHECK: br label %loop
146 ; CHECK: loop:
147 ; CHECK: %i = phi float addrspace(3)* [ %p, %entry ], [ %i2, %loop ]
148 ; CHECK: %v = load float, float addrspace(3)* %i
149 ; CHECK: call void @use(float %v)
150 ; CHECK: %i2 = getelementptr float, float addrspace(3)* %i, i64 1
151 ; CHECK: %0 = addrspacecast float addrspace(3)* %i2 to float*
152 ; CHECK: %exit_cond = icmp eq float* %0, %end
153 ; CHECK: br i1 %exit_cond, label %exit, label %loop
154 define amdgpu_kernel void @loop_with_generic_bound() #0 {
155 entry:
156   %p = addrspacecast [10 x float] addrspace(3)* @array to float*
157   %end = load float*, float* addrspace(1)* @generic_end
158   br label %loop
160 loop:                                             ; preds = %loop, %entry
161   %i = phi float* [ %p, %entry ], [ %i2, %loop ]
162   %v = load float, float* %i
163   call void @use(float %v)
164   %i2 = getelementptr float, float* %i, i64 1
165   %exit_cond = icmp eq float* %i2, %end
166   br i1 %exit_cond, label %exit, label %loop
168 exit:                                             ; preds = %loop
169   ret void
172 ; CHECK-LABEL: @select_bug(
173 ; CHECK: %add.ptr157 = getelementptr inbounds i64, i64* undef, i64 select (i1 icmp ne (i32* inttoptr (i64 4873 to i32*), i32* null), i64 73, i64 93)
174 ; CHECK: %cmp169 = icmp uge i64* undef, %add.ptr157
175 define void @select_bug() #0 {
176   %add.ptr157 = getelementptr inbounds i64, i64* undef, i64 select (i1 icmp ne (i32* inttoptr (i64 4873 to i32*), i32* null), i64 73, i64 93)
177   %cmp169 = icmp uge i64* undef, %add.ptr157
178   unreachable
181 declare void @llvm.amdgcn.s.barrier() #1
182 declare void @use(float) #0
184 attributes #0 = { nounwind }
185 attributes #1 = { convergent nounwind }