Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 1 | ; RUN: opt -S -instcombine %s -o - | FileCheck %s |
| 2 | target datalayout = "e-p:32:32:32-p1:64:64:64-p2:8:8:8-p3:16:16:16-p4:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32" |
| 3 | |
| 4 | @g = addrspace(3) global i32 89 |
| 5 | |
| 6 | @const_zero_i8_as1 = addrspace(1) constant i8 0 |
| 7 | @const_zero_i32_as1 = addrspace(1) constant i32 0 |
| 8 | |
| 9 | @const_zero_i8_as2 = addrspace(2) constant i8 0 |
| 10 | @const_zero_i32_as2 = addrspace(2) constant i32 0 |
| 11 | |
| 12 | @const_zero_i8_as3 = addrspace(3) constant i8 0 |
| 13 | @const_zero_i32_as3 = addrspace(3) constant i32 0 |
| 14 | |
| 15 | ; Test constant folding of inttoptr (ptrtoint constantexpr) |
| 16 | ; The intermediate integer size is the same as the pointer size |
| 17 | define i32 addrspace(3)* @test_constant_fold_inttoptr_as_pointer_same_size() { |
| 18 | ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_same_size( |
| 19 | ; CHECK-NEXT: ret i32 addrspace(3)* @const_zero_i32_as3 |
| 20 | %x = ptrtoint i32 addrspace(3)* @const_zero_i32_as3 to i32 |
| 21 | %y = inttoptr i32 %x to i32 addrspace(3)* |
| 22 | ret i32 addrspace(3)* %y |
| 23 | } |
| 24 | |
| 25 | ; The intermediate integer size is larger than the pointer size |
| 26 | define i32 addrspace(2)* @test_constant_fold_inttoptr_as_pointer_smaller() { |
| 27 | ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller( |
| 28 | ; CHECK-NEXT: ret i32 addrspace(2)* @const_zero_i32_as2 |
| 29 | %x = ptrtoint i32 addrspace(2)* @const_zero_i32_as2 to i16 |
| 30 | %y = inttoptr i16 %x to i32 addrspace(2)* |
| 31 | ret i32 addrspace(2)* %y |
| 32 | } |
| 33 | |
| 34 | ; Different address spaces that are the same size, but they are |
Matt Arsenault | b03bd4d | 2013-11-15 01:34:59 +0000 | [diff] [blame] | 35 | ; different so nothing should happen |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 36 | define i32 addrspace(4)* @test_constant_fold_inttoptr_as_pointer_smaller_different_as() { |
| 37 | ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller_different_as( |
Matt Arsenault | b03bd4d | 2013-11-15 01:34:59 +0000 | [diff] [blame] | 38 | ; CHECK-NEXT: ret i32 addrspace(4)* inttoptr (i16 ptrtoint (i32 addrspace(3)* @const_zero_i32_as3 to i16) to i32 addrspace(4)*) |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 39 | %x = ptrtoint i32 addrspace(3)* @const_zero_i32_as3 to i16 |
| 40 | %y = inttoptr i16 %x to i32 addrspace(4)* |
| 41 | ret i32 addrspace(4)* %y |
| 42 | } |
| 43 | |
| 44 | ; Make sure we don't introduce a bitcast between different sized |
| 45 | ; address spaces when folding this |
| 46 | define i32 addrspace(2)* @test_constant_fold_inttoptr_as_pointer_smaller_different_size_as() { |
| 47 | ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller_different_size_as( |
| 48 | ; CHECK-NEXT: ret i32 addrspace(2)* inttoptr (i32 ptrtoint (i32 addrspace(3)* @const_zero_i32_as3 to i32) to i32 addrspace(2)*) |
| 49 | %x = ptrtoint i32 addrspace(3)* @const_zero_i32_as3 to i32 |
| 50 | %y = inttoptr i32 %x to i32 addrspace(2)* |
| 51 | ret i32 addrspace(2)* %y |
| 52 | } |
| 53 | |
| 54 | ; The intermediate integer size is too small, nothing should happen |
| 55 | define i32 addrspace(3)* @test_constant_fold_inttoptr_as_pointer_larger() { |
| 56 | ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_larger( |
| 57 | ; CHECK-NEXT: ret i32 addrspace(3)* inttoptr (i8 ptrtoint (i32 addrspace(3)* @const_zero_i32_as3 to i8) to i32 addrspace(3)*) |
| 58 | %x = ptrtoint i32 addrspace(3)* @const_zero_i32_as3 to i8 |
| 59 | %y = inttoptr i8 %x to i32 addrspace(3)* |
| 60 | ret i32 addrspace(3)* %y |
| 61 | } |
| 62 | |
| 63 | define i8 @const_fold_ptrtoint() { |
| 64 | ; CHECK-LABEL: @const_fold_ptrtoint( |
| 65 | ; CHECK-NEXT: ret i8 4 |
| 66 | ret i8 ptrtoint (i32 addrspace(2)* inttoptr (i4 4 to i32 addrspace(2)*) to i8) |
| 67 | } |
| 68 | |
| 69 | ; Test that mask happens when the destination pointer is smaller than |
| 70 | ; the original |
| 71 | define i8 @const_fold_ptrtoint_mask() { |
| 72 | ; CHECK-LABEL: @const_fold_ptrtoint_mask( |
| 73 | ; CHECK-NEXT: ret i8 1 |
| 74 | ret i8 ptrtoint (i32 addrspace(3)* inttoptr (i32 257 to i32 addrspace(3)*) to i8) |
| 75 | } |
| 76 | |
Matt Arsenault | d12e802 | 2013-09-17 23:23:16 +0000 | [diff] [blame] | 77 | ; Address space 0 is too small for the correct mask, should mask with |
| 78 | ; 64-bits instead of 32 |
| 79 | define i64 @const_fold_ptrtoint_mask_small_as0() { |
| 80 | ; CHECK-LABEL: @const_fold_ptrtoint_mask_small_as0( |
| 81 | ; CHECK: ret i64 -1 |
| 82 | ret i64 ptrtoint (i32 addrspace(1)* inttoptr (i128 -1 to i32 addrspace(1)*) to i64) |
| 83 | } |
| 84 | |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 85 | define i32 addrspace(3)* @const_inttoptr() { |
| 86 | ; CHECK-LABEL: @const_inttoptr( |
| 87 | ; CHECK-NEXT: ret i32 addrspace(3)* inttoptr (i16 4 to i32 addrspace(3)*) |
| 88 | %p = inttoptr i16 4 to i32 addrspace(3)* |
| 89 | ret i32 addrspace(3)* %p |
| 90 | } |
| 91 | |
| 92 | define i16 @const_ptrtoint() { |
| 93 | ; CHECK-LABEL: @const_ptrtoint( |
| 94 | ; CHECK-NEXT: ret i16 ptrtoint (i32 addrspace(3)* @g to i16) |
| 95 | %i = ptrtoint i32 addrspace(3)* @g to i16 |
| 96 | ret i16 %i |
| 97 | } |
| 98 | |
| 99 | define i16 @const_inttoptr_ptrtoint() { |
| 100 | ; CHECK-LABEL: @const_inttoptr_ptrtoint( |
| 101 | ; CHECK-NEXT: ret i16 9 |
| 102 | ret i16 ptrtoint (i32 addrspace(3)* inttoptr (i16 9 to i32 addrspace(3)*) to i16) |
| 103 | } |
| 104 | |
| 105 | define i1 @constant_fold_cmp_constantexpr_inttoptr() { |
| 106 | ; CHECK-LABEL: @constant_fold_cmp_constantexpr_inttoptr( |
| 107 | ; CHECK-NEXT: ret i1 true |
| 108 | %x = icmp eq i32 addrspace(3)* inttoptr (i16 0 to i32 addrspace(3)*), null |
| 109 | ret i1 %x |
| 110 | } |
| 111 | |
| 112 | define i1 @constant_fold_inttoptr_null(i16 %i) { |
| 113 | ; CHECK-LABEL: @constant_fold_inttoptr_null( |
| 114 | ; CHECK-NEXT: ret i1 false |
| 115 | %x = icmp eq i32 addrspace(3)* inttoptr (i16 99 to i32 addrspace(3)*), inttoptr (i16 0 to i32 addrspace(3)*) |
| 116 | ret i1 %x |
| 117 | } |
| 118 | |
| 119 | define i1 @constant_fold_ptrtoint_null() { |
| 120 | ; CHECK-LABEL: @constant_fold_ptrtoint_null( |
| 121 | ; CHECK-NEXT: ret i1 false |
| 122 | %x = icmp eq i16 ptrtoint (i32 addrspace(3)* @g to i16), ptrtoint (i32 addrspace(3)* null to i16) |
| 123 | ret i1 %x |
| 124 | } |
| 125 | |
| 126 | define i1 @constant_fold_ptrtoint_null_2() { |
| 127 | ; CHECK-LABEL: @constant_fold_ptrtoint_null_2( |
| 128 | ; CHECK-NEXT: ret i1 false |
| 129 | %x = icmp eq i16 ptrtoint (i32 addrspace(3)* null to i16), ptrtoint (i32 addrspace(3)* @g to i16) |
| 130 | ret i1 %x |
| 131 | } |
| 132 | |
| 133 | define i1 @constant_fold_ptrtoint() { |
| 134 | ; CHECK-LABEL: @constant_fold_ptrtoint( |
| 135 | ; CHECK-NEXT: ret i1 true |
| 136 | %x = icmp eq i16 ptrtoint (i32 addrspace(3)* @g to i16), ptrtoint (i32 addrspace(3)* @g to i16) |
| 137 | ret i1 %x |
| 138 | } |
| 139 | |
| 140 | define i1 @constant_fold_inttoptr() { |
| 141 | ; CHECK-LABEL: @constant_fold_inttoptr( |
| 142 | ; CHECK-NEXT: ret i1 false |
| 143 | %x = icmp eq i32 addrspace(3)* inttoptr (i16 99 to i32 addrspace(3)*), inttoptr (i16 27 to i32 addrspace(3)*) |
| 144 | ret i1 %x |
| 145 | } |
| 146 | |
| 147 | @g_float_as3 = addrspace(3) global float zeroinitializer |
| 148 | @g_v4f_as3 = addrspace(3) global <4 x float> zeroinitializer |
| 149 | |
| 150 | define float @constant_fold_bitcast_ftoi_load() { |
| 151 | ; CHECK-LABEL: @constant_fold_bitcast_ftoi_load( |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 152 | ; CHECK: load float, float addrspace(3)* bitcast (i32 addrspace(3)* @g to float addrspace(3)*), align 4 |
| 153 | %a = load float, float addrspace(3)* bitcast (i32 addrspace(3)* @g to float addrspace(3)*), align 4 |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 154 | ret float %a |
| 155 | } |
| 156 | |
| 157 | define i32 @constant_fold_bitcast_itof_load() { |
| 158 | ; CHECK-LABEL: @constant_fold_bitcast_itof_load( |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 159 | ; CHECK: load i32, i32 addrspace(3)* bitcast (float addrspace(3)* @g_float_as3 to i32 addrspace(3)*), align 4 |
| 160 | %a = load i32, i32 addrspace(3)* bitcast (float addrspace(3)* @g_float_as3 to i32 addrspace(3)*), align 4 |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 161 | ret i32 %a |
| 162 | } |
| 163 | |
Chandler Carruth | 2f75fcf | 2014-10-18 06:36:22 +0000 | [diff] [blame] | 164 | define <4 x float> @constant_fold_bitcast_vector_as() { |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 165 | ; CHECK-LABEL: @constant_fold_bitcast_vector_as( |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 166 | ; CHECK: load <4 x float>, <4 x float> addrspace(3)* @g_v4f_as3, align 16 |
| 167 | %a = load <4 x float>, <4 x float> addrspace(3)* bitcast (<4 x i32> addrspace(3)* bitcast (<4 x float> addrspace(3)* @g_v4f_as3 to <4 x i32> addrspace(3)*) to <4 x float> addrspace(3)*), align 4 |
Chandler Carruth | 2f75fcf | 2014-10-18 06:36:22 +0000 | [diff] [blame] | 168 | ret <4 x float> %a |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 169 | } |
| 170 | |
| 171 | @i32_array_as3 = addrspace(3) global [10 x i32] zeroinitializer |
| 172 | |
| 173 | define i32 @test_cast_gep_small_indices_as() { |
| 174 | ; CHECK-LABEL: @test_cast_gep_small_indices_as( |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 175 | ; CHECK: load i32, i32 addrspace(3)* getelementptr inbounds ([10 x i32] addrspace(3)* @i32_array_as3, i16 0, i16 0), align 16 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 176 | %p = getelementptr [10 x i32], [10 x i32] addrspace(3)* @i32_array_as3, i7 0, i7 0 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 177 | %x = load i32, i32 addrspace(3)* %p, align 4 |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 178 | ret i32 %x |
| 179 | } |
| 180 | |
| 181 | %struct.foo = type { float, float, [4 x i32], i32 addrspace(3)* } |
| 182 | |
| 183 | @constant_fold_global_ptr = addrspace(3) global %struct.foo { |
| 184 | float 0.0, |
| 185 | float 0.0, |
| 186 | [4 x i32] zeroinitializer, |
| 187 | i32 addrspace(3)* getelementptr ([10 x i32] addrspace(3)* @i32_array_as3, i64 0, i64 0) |
| 188 | } |
| 189 | |
| 190 | define i32 @test_cast_gep_large_indices_as() { |
| 191 | ; CHECK-LABEL: @test_cast_gep_large_indices_as( |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 192 | ; CHECK: load i32, i32 addrspace(3)* getelementptr inbounds ([10 x i32] addrspace(3)* @i32_array_as3, i16 0, i16 0), align 16 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 193 | %p = getelementptr [10 x i32], [10 x i32] addrspace(3)* @i32_array_as3, i64 0, i64 0 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 194 | %x = load i32, i32 addrspace(3)* %p, align 4 |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 195 | ret i32 %x |
| 196 | } |
| 197 | |
| 198 | define i32 @test_constant_cast_gep_struct_indices_as() { |
| 199 | ; CHECK-LABEL: @test_constant_cast_gep_struct_indices_as( |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 200 | ; CHECK: load i32, i32 addrspace(3)* getelementptr inbounds (%struct.foo addrspace(3)* @constant_fold_global_ptr, i16 0, i32 2, i16 2), align 8 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 201 | %x = getelementptr %struct.foo, %struct.foo addrspace(3)* @constant_fold_global_ptr, i18 0, i32 2, i12 2 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 202 | %y = load i32, i32 addrspace(3)* %x, align 4 |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 203 | ret i32 %y |
| 204 | } |
| 205 | |
| 206 | @constant_data_as3 = addrspace(3) constant [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5] |
| 207 | |
| 208 | define i32 @test_read_data_from_global_as3() { |
| 209 | ; CHECK-LABEL: @test_read_data_from_global_as3( |
| 210 | ; CHECK-NEXT: ret i32 2 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 211 | %x = getelementptr [5 x i32], [5 x i32] addrspace(3)* @constant_data_as3, i32 0, i32 1 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 212 | %y = load i32, i32 addrspace(3)* %x, align 4 |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 213 | ret i32 %y |
| 214 | } |
| 215 | |
| 216 | @a = addrspace(1) constant i32 9 |
| 217 | @b = addrspace(1) constant i32 23 |
| 218 | @c = addrspace(1) constant i32 34 |
| 219 | @d = addrspace(1) constant i32 99 |
| 220 | |
| 221 | @ptr_array = addrspace(2) constant [4 x i32 addrspace(1)*] [ i32 addrspace(1)* @a, i32 addrspace(1)* @b, i32 addrspace(1)* @c, i32 addrspace(1)* @d] |
| 222 | @indirect = addrspace(0) constant i32 addrspace(1)* addrspace(2)* getelementptr inbounds ([4 x i32 addrspace(1)*] addrspace(2)* @ptr_array, i1 0, i32 2) |
| 223 | |
| 224 | define i32 @constant_through_array_as_ptrs() { |
| 225 | ; CHECK-LABEL: @constant_through_array_as_ptrs( |
| 226 | ; CHECK-NEXT: ret i32 34 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 227 | %p = load i32 addrspace(1)* addrspace(2)*, i32 addrspace(1)* addrspace(2)* addrspace(0)* @indirect, align 4 |
| 228 | %a = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(2)* %p, align 4 |
| 229 | %b = load i32, i32 addrspace(1)* %a, align 4 |
Matt Arsenault | 7a960a8 | 2013-08-20 21:20:04 +0000 | [diff] [blame] | 230 | ret i32 %b |
| 231 | } |
Jingyue Wu | baabe50 | 2014-06-15 21:40:57 +0000 | [diff] [blame] | 232 | |
| 233 | @shared_mem = external addrspace(3) global [0 x i8] |
| 234 | |
| 235 | define float @canonicalize_addrspacecast(i32 %i) { |
| 236 | ; CHECK-LABEL: @canonicalize_addrspacecast |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 237 | ; CHECK-NEXT: getelementptr inbounds float, float* addrspacecast (float addrspace(3)* bitcast ([0 x i8] addrspace(3)* @shared_mem to float addrspace(3)*) to float*), i32 %i |
| 238 | %p = getelementptr inbounds float, float* addrspacecast ([0 x i8] addrspace(3)* @shared_mem to float*), i32 %i |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 239 | %v = load float, float* %p |
Jingyue Wu | baabe50 | 2014-06-15 21:40:57 +0000 | [diff] [blame] | 240 | ret float %v |
| 241 | } |