380 lines · plain
1// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s2 3// CHECK-LABEL: declare ptr @llvm_ptr_address_space(ptr addrspace(1), ptr addrspace(3))4llvm.func @llvm_ptr_address_space(!ptr.ptr<#llvm.address_space<1>>, !ptr.ptr<#llvm.address_space<3>>) -> !ptr.ptr<#llvm.address_space<0>>5 6// CHECK-LABEL: define void @llvm_ops_with_ptr_values7// CHECK-SAME: (ptr %[[ARG:.*]]) {8// CHECK-NEXT: %[[V0:.*]] = load ptr addrspace(1), ptr %[[ARG]], align 89// CHECK-NEXT: store ptr addrspace(1) %[[V0]], ptr %[[ARG]], align 810// CHECK-NEXT: ret void11// CHECK-NEXT: }12llvm.func @llvm_ops_with_ptr_values(%arg0: !llvm.ptr) {13 %1 = llvm.load %arg0 : !llvm.ptr -> !ptr.ptr<#llvm.address_space<1>>14 llvm.store %1, %arg0 : !ptr.ptr<#llvm.address_space<1>>, !llvm.ptr15 llvm.return16}17 18// CHECK-LABEL: define ptr @ptr_add19// CHECK-SAME: (ptr %[[PTR:.*]], i32 %[[OFF:.*]]) {20// CHECK-NEXT: %[[RES:.*]] = getelementptr i8, ptr %[[PTR]], i32 %[[OFF]]21// CHECK-NEXT: %[[RES0:.*]] = getelementptr i8, ptr %[[PTR]], i32 %[[OFF]]22// CHECK-NEXT: %[[RES1:.*]] = getelementptr nusw i8, ptr %[[PTR]], i32 %[[OFF]]23// CHECK-NEXT: %[[RES2:.*]] = getelementptr nuw i8, ptr %[[PTR]], i32 %[[OFF]]24// CHECK-NEXT: %[[RES3:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i32 %[[OFF]]25// CHECK-NEXT: ret ptr %[[RES]]26// CHECK-NEXT: }27llvm.func @ptr_add(%ptr: !ptr.ptr<#llvm.address_space<0>>, %off: i32) -> !ptr.ptr<#llvm.address_space<0>> {28 %res = ptr.ptr_add %ptr, %off : !ptr.ptr<#llvm.address_space<0>>, i3229 %res0 = ptr.ptr_add none %ptr, %off : !ptr.ptr<#llvm.address_space<0>>, i3230 %res1 = ptr.ptr_add nusw %ptr, %off : !ptr.ptr<#llvm.address_space<0>>, i3231 %res2 = ptr.ptr_add nuw %ptr, %off : !ptr.ptr<#llvm.address_space<0>>, i3232 %res3 = ptr.ptr_add inbounds %ptr, %off : !ptr.ptr<#llvm.address_space<0>>, i3233 llvm.return %res : !ptr.ptr<#llvm.address_space<0>>34}35 36// CHECK-LABEL: define { i32, i32, i32, i32 } @type_offset37// CHECK-NEXT: ret { i32, i32, i32, i32 } { i32 8, i32 1, i32 2, i32 4 }38llvm.func @type_offset(%arg0: !ptr.ptr<#llvm.address_space<0>>) -> !llvm.struct<(i32, i32, i32, i32)> {39 %0 = ptr.type_offset f64 : i3240 %1 = ptr.type_offset i8 : i3241 %2 = ptr.type_offset i16 : i3242 %3 = ptr.type_offset i32 : i3243 %4 = llvm.mlir.poison : !llvm.struct<(i32, i32, i32, i32)>44 %5 = llvm.insertvalue %0, %4[0] : !llvm.struct<(i32, i32, i32, i32)>45 %6 = llvm.insertvalue %1, %5[1] : !llvm.struct<(i32, i32, i32, i32)>46 %7 = llvm.insertvalue %2, %6[2] : !llvm.struct<(i32, i32, i32, i32)>47 %8 = llvm.insertvalue %3, %7[3] : !llvm.struct<(i32, i32, i32, i32)>48 llvm.return %8 : !llvm.struct<(i32, i32, i32, i32)>49}50 51// CHECK-LABEL: define void @load_ops52// CHECK-SAME: (ptr %[[PTR:.*]]) {53// CHECK-NEXT: %[[V0:.*]] = load float, ptr %[[PTR]], align 454// CHECK-NEXT: %[[V1:.*]] = load volatile float, ptr %[[PTR]], align 455// CHECK-NEXT: %[[V2:.*]] = load float, ptr %[[PTR]], align 4, !nontemporal !{{.*}}56// CHECK-NEXT: %[[V3:.*]] = load float, ptr %[[PTR]], align 4, !invariant.load !{{.*}}57// CHECK-NEXT: %[[V4:.*]] = load float, ptr %[[PTR]], align 4, !invariant.group !{{.*}}58// CHECK-NEXT: %[[V5:.*]] = load atomic i64, ptr %[[PTR]] monotonic, align 859// CHECK-NEXT: %[[V6:.*]] = load atomic volatile i32, ptr %[[PTR]] syncscope("workgroup") acquire, align 4, !nontemporal !{{.*}}60// CHECK-NEXT: ret void61// CHECK-NEXT: }62llvm.func @load_ops(%arg0: !ptr.ptr<#llvm.address_space<0>>) {63 %0 = ptr.load %arg0 : !ptr.ptr<#llvm.address_space<0>> -> f3264 %1 = ptr.load volatile %arg0 : !ptr.ptr<#llvm.address_space<0>> -> f3265 %2 = ptr.load %arg0 nontemporal : !ptr.ptr<#llvm.address_space<0>> -> f3266 %3 = ptr.load %arg0 invariant : !ptr.ptr<#llvm.address_space<0>> -> f3267 %4 = ptr.load %arg0 invariant_group : !ptr.ptr<#llvm.address_space<0>> -> f3268 %5 = ptr.load %arg0 atomic monotonic alignment = 8 : !ptr.ptr<#llvm.address_space<0>> -> i6469 %6 = ptr.load volatile %arg0 atomic syncscope("workgroup") acquire nontemporal alignment = 4 : !ptr.ptr<#llvm.address_space<0>> -> i3270 llvm.return71}72 73// CHECK-LABEL: define void @store_ops74// CHECK-SAME: (ptr %[[PTR:.*]], float %[[ARG1:.*]], i64 %[[ARG2:.*]], i32 %[[ARG3:.*]]) {75// CHECK-NEXT: store float %[[ARG1]], ptr %[[PTR]], align 476// CHECK-NEXT: store volatile float %[[ARG1]], ptr %[[PTR]], align 477// CHECK-NEXT: store float %[[ARG1]], ptr %[[PTR]], align 4, !nontemporal !{{.*}}78// CHECK-NEXT: store float %[[ARG1]], ptr %[[PTR]], align 4, !invariant.group !{{.*}}79// CHECK-NEXT: store atomic i64 %[[ARG2]], ptr %[[PTR]] monotonic, align 880// CHECK-NEXT: store atomic volatile i32 %[[ARG3]], ptr %[[PTR]] syncscope("workgroup") release, align 4, !nontemporal !{{.*}}81// CHECK-NEXT: ret void82// CHECK-NEXT: }83llvm.func @store_ops(%arg0: !ptr.ptr<#llvm.address_space<0>>, %arg1: f32, %arg2: i64, %arg3: i32) {84 ptr.store %arg1, %arg0 : f32, !ptr.ptr<#llvm.address_space<0>>85 ptr.store volatile %arg1, %arg0 : f32, !ptr.ptr<#llvm.address_space<0>>86 ptr.store %arg1, %arg0 nontemporal : f32, !ptr.ptr<#llvm.address_space<0>>87 ptr.store %arg1, %arg0 invariant_group : f32, !ptr.ptr<#llvm.address_space<0>>88 ptr.store %arg2, %arg0 atomic monotonic alignment = 8 : i64, !ptr.ptr<#llvm.address_space<0>>89 ptr.store volatile %arg3, %arg0 atomic syncscope("workgroup") release nontemporal alignment = 4 : i32, !ptr.ptr<#llvm.address_space<0>>90 llvm.return91}92 93// CHECK-LABEL: define <4 x float> @gather_ops94// CHECK-SAME: (<4 x ptr> %[[PTRS:.*]], <4 x i1> %[[MASK:.*]], <4 x float> %[[PASSTHROUGH:.*]]) {95// CHECK-NEXT: %[[V0:.*]] = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> align 1 %[[PTRS]], <4 x i1> %[[MASK]], <4 x float> %[[PASSTHROUGH]])96// CHECK-NEXT: %[[V1:.*]] = call <4 x float> @llvm.masked.gather.v4f32.v4p0(<4 x ptr> align 4 %[[PTRS]], <4 x i1> %[[MASK]], <4 x float> %[[PASSTHROUGH]])97// CHECK-NEXT: ret <4 x float> %[[V0]]98// CHECK-NEXT: }99llvm.func @gather_ops(%ptrs: vector<4x!ptr.ptr<#llvm.address_space<0>>>, %mask: vector<4xi1>, %passthrough: vector<4xf32>) -> vector<4xf32> {100 // Basic gather101 %0 = ptr.gather %ptrs, %mask, %passthrough : vector<4x!ptr.ptr<#llvm.address_space<0>>> -> vector<4xf32>102 // Gather with alignment103 %1 = ptr.gather %ptrs, %mask, %passthrough alignment = 4 : vector<4x!ptr.ptr<#llvm.address_space<0>>> -> vector<4xf32>104 llvm.return %0 : vector<4xf32>105}106 107// CHECK-LABEL: define <8 x i32> @gather_ops_i32108// CHECK-SAME: (<8 x ptr> %[[PTRS:.*]], <8 x i1> %[[MASK:.*]], <8 x i32> %[[PASSTHROUGH:.*]]) {109// CHECK-NEXT: %[[V0:.*]] = call <8 x i32> @llvm.masked.gather.v8i32.v8p0(<8 x ptr> align 8 %[[PTRS]], <8 x i1> %[[MASK]], <8 x i32> %[[PASSTHROUGH]])110// CHECK-NEXT: ret <8 x i32> %[[V0]]111// CHECK-NEXT: }112llvm.func @gather_ops_i32(%ptrs: vector<8x!ptr.ptr<#llvm.address_space<0>>>, %mask: vector<8xi1>, %passthrough: vector<8xi32>) -> vector<8xi32> {113 %0 = ptr.gather %ptrs, %mask, %passthrough alignment = 8 : vector<8x!ptr.ptr<#llvm.address_space<0>>> -> vector<8xi32>114 llvm.return %0 : vector<8xi32>115}116 117// CHECK-LABEL: define <4 x float> @masked_load_ops118// CHECK-SAME: (ptr %[[PTR:.*]], <4 x i1> %[[MASK:.*]], <4 x float> %[[PASSTHROUGH:.*]]) {119// CHECK-NEXT: %[[V0:.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 1 %[[PTR]], <4 x i1> %[[MASK]], <4 x float> %[[PASSTHROUGH]])120// CHECK-NEXT: %[[V1:.*]] = call <4 x float> @llvm.masked.load.v4f32.p0(ptr align 16 %[[PTR]], <4 x i1> %[[MASK]], <4 x float> %[[PASSTHROUGH]])121// CHECK-NEXT: ret <4 x float> %[[V0]]122// CHECK-NEXT: }123llvm.func @masked_load_ops(%ptr: !ptr.ptr<#llvm.address_space<0>>, %mask: vector<4xi1>, %passthrough: vector<4xf32>) -> vector<4xf32> {124 // Basic masked load125 %0 = ptr.masked_load %ptr, %mask, %passthrough : !ptr.ptr<#llvm.address_space<0>> -> vector<4xf32>126 // Masked load with alignment127 %1 = ptr.masked_load %ptr, %mask, %passthrough alignment = 16 : !ptr.ptr<#llvm.address_space<0>> -> vector<4xf32>128 llvm.return %0 : vector<4xf32>129}130 131// CHECK-LABEL: define <8 x i64> @masked_load_ops_i64132// CHECK-SAME: (ptr %[[PTR:.*]], <8 x i1> %[[MASK:.*]], <8 x i64> %[[PASSTHROUGH:.*]]) {133// CHECK-NEXT: %[[V0:.*]] = call <8 x i64> @llvm.masked.load.v8i64.p0(ptr align 8 %[[PTR]], <8 x i1> %[[MASK]], <8 x i64> %[[PASSTHROUGH]])134// CHECK-NEXT: ret <8 x i64> %[[V0]]135// CHECK-NEXT: }136llvm.func @masked_load_ops_i64(%ptr: !ptr.ptr<#llvm.address_space<0>>, %mask: vector<8xi1>, %passthrough: vector<8xi64>) -> vector<8xi64> {137 %0 = ptr.masked_load %ptr, %mask, %passthrough alignment = 8 : !ptr.ptr<#llvm.address_space<0>> -> vector<8xi64>138 llvm.return %0 : vector<8xi64>139}140 141// CHECK-LABEL: define void @masked_store_ops142// CHECK-SAME: (ptr %[[PTR:.*]], <4 x float> %[[VALUE:.*]], <4 x i1> %[[MASK:.*]]) {143// CHECK-NEXT: call void @llvm.masked.store.v4f32.p0(<4 x float> %[[VALUE]], ptr align 1 %[[PTR]], <4 x i1> %[[MASK]])144// CHECK-NEXT: call void @llvm.masked.store.v4f32.p0(<4 x float> %[[VALUE]], ptr align 32 %[[PTR]], <4 x i1> %[[MASK]])145// CHECK-NEXT: ret void146// CHECK-NEXT: }147llvm.func @masked_store_ops(%ptr: !ptr.ptr<#llvm.address_space<0>>, %value: vector<4xf32>, %mask: vector<4xi1>) {148 // Basic masked store149 ptr.masked_store %value, %ptr, %mask : vector<4xf32>, !ptr.ptr<#llvm.address_space<0>>150 // Masked store with alignment151 ptr.masked_store %value, %ptr, %mask alignment = 32 : vector<4xf32>, !ptr.ptr<#llvm.address_space<0>>152 llvm.return153}154 155// CHECK-LABEL: define void @masked_store_ops_i16156// CHECK-SAME: (ptr %[[PTR:.*]], <8 x i16> %[[VALUE:.*]], <8 x i1> %[[MASK:.*]]) {157// CHECK-NEXT: call void @llvm.masked.store.v8i16.p0(<8 x i16> %[[VALUE]], ptr align 4 %[[PTR]], <8 x i1> %[[MASK]])158// CHECK-NEXT: ret void159// CHECK-NEXT: }160llvm.func @masked_store_ops_i16(%ptr: !ptr.ptr<#llvm.address_space<0>>, %value: vector<8xi16>, %mask: vector<8xi1>) {161 ptr.masked_store %value, %ptr, %mask alignment = 4 : vector<8xi16>, !ptr.ptr<#llvm.address_space<0>>162 llvm.return163}164 165// CHECK-LABEL: define void @scatter_ops166// CHECK-SAME: (<4 x float> %[[VALUE:.*]], <4 x ptr> %[[PTRS:.*]], <4 x i1> %[[MASK:.*]]) {167// CHECK-NEXT: call void @llvm.masked.scatter.v4f32.v4p0(<4 x float> %[[VALUE]], <4 x ptr> align 1 %[[PTRS]], <4 x i1> %[[MASK]])168// CHECK-NEXT: call void @llvm.masked.scatter.v4f32.v4p0(<4 x float> %[[VALUE]], <4 x ptr> align 8 %[[PTRS]], <4 x i1> %[[MASK]])169// CHECK-NEXT: ret void170// CHECK-NEXT: }171llvm.func @scatter_ops(%value: vector<4xf32>, %ptrs: vector<4x!ptr.ptr<#llvm.address_space<0>>>, %mask: vector<4xi1>) {172 // Basic scatter173 ptr.scatter %value, %ptrs, %mask : vector<4xf32>, vector<4x!ptr.ptr<#llvm.address_space<0>>>174 // Scatter with alignment175 ptr.scatter %value, %ptrs, %mask alignment = 8 : vector<4xf32>, vector<4x!ptr.ptr<#llvm.address_space<0>>>176 llvm.return177}178 179// CHECK-LABEL: define void @scatter_ops_i64180// CHECK-SAME: (<8 x i64> %[[VALUE:.*]], <8 x ptr> %[[PTRS:.*]], <8 x i1> %[[MASK:.*]]) {181// CHECK-NEXT: call void @llvm.masked.scatter.v8i64.v8p0(<8 x i64> %[[VALUE]], <8 x ptr> align 16 %[[PTRS]], <8 x i1> %[[MASK]])182// CHECK-NEXT: ret void183// CHECK-NEXT: }184llvm.func @scatter_ops_i64(%value: vector<8xi64>, %ptrs: vector<8x!ptr.ptr<#llvm.address_space<0>>>, %mask: vector<8xi1>) {185 ptr.scatter %value, %ptrs, %mask alignment = 16 : vector<8xi64>, vector<8x!ptr.ptr<#llvm.address_space<0>>>186 llvm.return187}188 189// CHECK-LABEL: define void @mixed_masked_ops_address_spaces190// CHECK-SAME: (ptr addrspace(3) %[[PTR_SHARED:.*]], <4 x ptr addrspace(3)> %[[PTRS_SHARED:.*]], <4 x i1> %[[MASK:.*]], <4 x double> %[[VALUE_F64:.*]], <4 x double> %[[PASSTHROUGH_F64:.*]]) {191// CHECK-NEXT: %[[V0:.*]] = call <4 x double> @llvm.masked.gather.v4f64.v4p3(<4 x ptr addrspace(3)> align 8 %[[PTRS_SHARED]], <4 x i1> %[[MASK]], <4 x double> %[[PASSTHROUGH_F64]])192// CHECK-NEXT: call void @llvm.masked.scatter.v4f64.v4p3(<4 x double> %[[VALUE_F64]], <4 x ptr addrspace(3)> align 8 %[[PTRS_SHARED]], <4 x i1> %[[MASK]])193// CHECK-NEXT: %[[V1:.*]] = call <4 x double> @llvm.masked.load.v4f64.p3(ptr addrspace(3) align 8 %[[PTR_SHARED]], <4 x i1> %[[MASK]], <4 x double> %[[PASSTHROUGH_F64]])194// CHECK-NEXT: call void @llvm.masked.store.v4f64.p3(<4 x double> %[[VALUE_F64]], ptr addrspace(3) align 8 %[[PTR_SHARED]], <4 x i1> %[[MASK]])195// CHECK-NEXT: ret void196// CHECK-NEXT: }197llvm.func @mixed_masked_ops_address_spaces(%ptr: !ptr.ptr<#llvm.address_space<3>>, %ptrs: vector<4x!ptr.ptr<#llvm.address_space<3>>>,198 %mask: vector<4xi1>, %value: vector<4xf64>, %passthrough: vector<4xf64>) {199 // Test with shared memory address space (3) and f64 elements200 %0 = ptr.gather %ptrs, %mask, %passthrough alignment = 8 : vector<4x!ptr.ptr<#llvm.address_space<3>>> -> vector<4xf64>201 ptr.scatter %value, %ptrs, %mask alignment = 8 : vector<4xf64>, vector<4x!ptr.ptr<#llvm.address_space<3>>>202 %1 = ptr.masked_load %ptr, %mask, %passthrough alignment = 8 : !ptr.ptr<#llvm.address_space<3>> -> vector<4xf64>203 ptr.masked_store %value, %ptr, %mask alignment = 8 : vector<4xf64>, !ptr.ptr<#llvm.address_space<3>>204 llvm.return205}206 207// CHECK-LABEL: define <4 x ptr> @ptr_add_vector208// CHECK-SAME: (<4 x ptr> %[[PTRS:.*]], <4 x i32> %[[OFFSETS:.*]]) {209// CHECK-NEXT: %[[RES:.*]] = getelementptr i8, <4 x ptr> %[[PTRS]], <4 x i32> %[[OFFSETS]]210// CHECK-NEXT: ret <4 x ptr> %[[RES]]211// CHECK-NEXT: }212llvm.func @ptr_add_vector(%ptrs: vector<4x!ptr.ptr<#llvm.address_space<0>>>, %offsets: vector<4xi32>) -> vector<4x!ptr.ptr<#llvm.address_space<0>>> {213 %res = ptr.ptr_add %ptrs, %offsets : vector<4x!ptr.ptr<#llvm.address_space<0>>>, vector<4xi32>214 llvm.return %res : vector<4x!ptr.ptr<#llvm.address_space<0>>>215}216 217// CHECK-LABEL: define <4 x ptr> @ptr_add_scalar_base_vector_offsets218// CHECK-SAME: (ptr %[[PTR:.*]], <4 x i32> %[[OFFSETS:.*]]) {219// CHECK-NEXT: %[[RES:.*]] = getelementptr i8, ptr %[[PTR]], <4 x i32> %[[OFFSETS]]220// CHECK-NEXT: ret <4 x ptr> %[[RES]]221// CHECK-NEXT: }222llvm.func @ptr_add_scalar_base_vector_offsets(%ptr: !ptr.ptr<#llvm.address_space<0>>, %offsets: vector<4xi32>) -> vector<4x!ptr.ptr<#llvm.address_space<0>>> {223 %res = ptr.ptr_add %ptr, %offsets : !ptr.ptr<#llvm.address_space<0>>, vector<4xi32>224 llvm.return %res : vector<4x!ptr.ptr<#llvm.address_space<0>>>225}226 227// CHECK-LABEL: define <4 x ptr> @ptr_add_vector_base_scalar_offset228// CHECK-SAME: (<4 x ptr> %[[PTRS:.*]], i32 %[[OFFSET:.*]]) {229// CHECK-NEXT: %[[RES:.*]] = getelementptr i8, <4 x ptr> %[[PTRS]], i32 %[[OFFSET]]230// CHECK-NEXT: ret <4 x ptr> %[[RES]]231// CHECK-NEXT: }232llvm.func @ptr_add_vector_base_scalar_offset(%ptrs: vector<4x!ptr.ptr<#llvm.address_space<0>>>, %offset: i32) -> vector<4x!ptr.ptr<#llvm.address_space<0>>> {233 %res = ptr.ptr_add %ptrs, %offset : vector<4x!ptr.ptr<#llvm.address_space<0>>>, i32234 llvm.return %res : vector<4x!ptr.ptr<#llvm.address_space<0>>>235}236 237// CHECK-LABEL: declare ptr @nvvm_ptr_address_space(ptr addrspace(1), ptr addrspace(3), ptr addrspace(4), ptr addrspace(5), ptr addrspace(6), ptr addrspace(7))238llvm.func @nvvm_ptr_address_space(239 !ptr.ptr<#nvvm.memory_space<global>>,240 !ptr.ptr<#nvvm.memory_space<shared>>,241 !ptr.ptr<#nvvm.memory_space<constant>>,242 !ptr.ptr<#nvvm.memory_space<local>>,243 !ptr.ptr<#nvvm.memory_space<tensor>>,244 !ptr.ptr<#nvvm.memory_space<shared_cluster>>245 ) -> !ptr.ptr<#nvvm.memory_space<generic>>246 247// CHECK-LABEL: define void @llvm_ops_with_ptr_nvvm_values248// CHECK-SAME: (ptr %[[ARG:.*]]) {249// CHECK-NEXT: %[[V0:.*]] = load ptr addrspace(1), ptr %[[ARG]], align 8250// CHECK-NEXT: store ptr addrspace(1) %[[V0]], ptr %[[ARG]], align 8251// CHECK-NEXT: ret void252// CHECK-NEXT: }253llvm.func @llvm_ops_with_ptr_nvvm_values(%arg0: !llvm.ptr) {254 %1 = llvm.load %arg0 : !llvm.ptr -> !ptr.ptr<#nvvm.memory_space<global>>255 llvm.store %1, %arg0 : !ptr.ptr<#nvvm.memory_space<global>>, !llvm.ptr256 llvm.return257}258 259// CHECK-LABEL: define { ptr, ptr addrspace(1), ptr addrspace(2) } @constant_address_op() {260// CHECK-NEXT: ret { ptr, ptr addrspace(1), ptr addrspace(2) } { ptr null, ptr addrspace(1) inttoptr (i64 4096 to ptr addrspace(1)), ptr addrspace(2) inttoptr (i64 3735928559 to ptr addrspace(2)) }261llvm.func @constant_address_op() ->262 !llvm.struct<(!ptr.ptr<#llvm.address_space<0>>,263 !ptr.ptr<#llvm.address_space<1>>,264 !ptr.ptr<#llvm.address_space<2>>)> {265 %0 = ptr.constant #ptr.null : !ptr.ptr<#llvm.address_space<0>>266 %1 = ptr.constant #ptr.address<0x1000> : !ptr.ptr<#llvm.address_space<1>>267 %2 = ptr.constant #ptr.address<3735928559> : !ptr.ptr<#llvm.address_space<2>>268 %3 = llvm.mlir.poison : !llvm.struct<(!ptr.ptr<#llvm.address_space<0>>, !ptr.ptr<#llvm.address_space<1>>, !ptr.ptr<#llvm.address_space<2>>)>269 %4 = llvm.insertvalue %0, %3[0] : !llvm.struct<(!ptr.ptr<#llvm.address_space<0>>, !ptr.ptr<#llvm.address_space<1>>, !ptr.ptr<#llvm.address_space<2>>)>270 %5 = llvm.insertvalue %1, %4[1] : !llvm.struct<(!ptr.ptr<#llvm.address_space<0>>, !ptr.ptr<#llvm.address_space<1>>, !ptr.ptr<#llvm.address_space<2>>)>271 %6 = llvm.insertvalue %2, %5[2] : !llvm.struct<(!ptr.ptr<#llvm.address_space<0>>, !ptr.ptr<#llvm.address_space<1>>, !ptr.ptr<#llvm.address_space<2>>)>272 llvm.return %6 : !llvm.struct<(!ptr.ptr<#llvm.address_space<0>>, !ptr.ptr<#llvm.address_space<1>>, !ptr.ptr<#llvm.address_space<2>>)>273}274 275// Test gep folders.276// CHECK-LABEL: define ptr @ptr_add_cst() {277// CHECK-NEXT: ret ptr inttoptr (i64 42 to ptr)278llvm.func @ptr_add_cst() -> !ptr.ptr<#llvm.address_space<0>> {279 %off = llvm.mlir.constant(42 : i32) : i32280 %ptr = ptr.constant #ptr.null : !ptr.ptr<#llvm.address_space<0>>281 %res = ptr.ptr_add %ptr, %off : !ptr.ptr<#llvm.address_space<0>>, i32282 llvm.return %res : !ptr.ptr<#llvm.address_space<0>>283}284 285// CHECK-LABEL: define i64 @ptr_diff_scalar286// CHECK-SAME: (ptr %[[PTR1:.*]], ptr %[[PTR2:.*]]) {287// CHECK-NEXT: %[[P1INT:.*]] = ptrtoaddr ptr %[[PTR1]] to i64288// CHECK-NEXT: %[[P2INT:.*]] = ptrtoaddr ptr %[[PTR2]] to i64289// CHECK-NEXT: %[[DIFF:.*]] = sub i64 %[[P1INT]], %[[P2INT]]290// CHECK-NEXT: ret i64 %[[DIFF]]291// CHECK-NEXT: }292llvm.func @ptr_diff_scalar(%ptr1: !ptr.ptr<#llvm.address_space<0>>, %ptr2: !ptr.ptr<#llvm.address_space<0>>) -> i64 {293 %diff = ptr.ptr_diff %ptr1, %ptr2 : !ptr.ptr<#llvm.address_space<0>> -> i64294 llvm.return %diff : i64295}296 297// CHECK-LABEL: define i32 @ptr_diff_scalar_i32298// CHECK-SAME: (ptr %[[PTR1:.*]], ptr %[[PTR2:.*]]) {299// CHECK-NEXT: %[[P1INT:.*]] = ptrtoaddr ptr %[[PTR1]] to i64300// CHECK-NEXT: %[[P2INT:.*]] = ptrtoaddr ptr %[[PTR2]] to i64301// CHECK-NEXT: %[[DIFF:.*]] = sub i64 %[[P1INT]], %[[P2INT]]302// CHECK-NEXT: %[[TRUNC:.*]] = trunc i64 %[[DIFF]] to i32303// CHECK-NEXT: ret i32 %[[TRUNC]]304// CHECK-NEXT: }305llvm.func @ptr_diff_scalar_i32(%ptr1: !ptr.ptr<#llvm.address_space<0>>, %ptr2: !ptr.ptr<#llvm.address_space<0>>) -> i32 {306 %diff = ptr.ptr_diff %ptr1, %ptr2 : !ptr.ptr<#llvm.address_space<0>> -> i32307 llvm.return %diff : i32308}309 310// CHECK-LABEL: define <4 x i64> @ptr_diff_vector311// CHECK-SAME: (<4 x ptr> %[[PTRS1:.*]], <4 x ptr> %[[PTRS2:.*]]) {312// CHECK-NEXT: %[[P1INT:.*]] = ptrtoaddr <4 x ptr> %[[PTRS1]] to <4 x i64>313// CHECK-NEXT: %[[P2INT:.*]] = ptrtoaddr <4 x ptr> %[[PTRS2]] to <4 x i64>314// CHECK-NEXT: %[[DIFF:.*]] = sub <4 x i64> %[[P1INT]], %[[P2INT]]315// CHECK-NEXT: ret <4 x i64> %[[DIFF]]316// CHECK-NEXT: }317llvm.func @ptr_diff_vector(%ptrs1: vector<4x!ptr.ptr<#llvm.address_space<0>>>, %ptrs2: vector<4x!ptr.ptr<#llvm.address_space<0>>>) -> vector<4xi64> {318 %diffs = ptr.ptr_diff %ptrs1, %ptrs2 : vector<4x!ptr.ptr<#llvm.address_space<0>>> -> vector<4xi64>319 llvm.return %diffs : vector<4xi64>320}321 322// CHECK-LABEL: define <8 x i32> @ptr_diff_vector_i32323// CHECK-SAME: (<8 x ptr> %[[PTRS1:.*]], <8 x ptr> %[[PTRS2:.*]]) {324// CHECK-NEXT: %[[P1INT:.*]] = ptrtoaddr <8 x ptr> %[[PTRS1]] to <8 x i64>325// CHECK-NEXT: %[[P2INT:.*]] = ptrtoaddr <8 x ptr> %[[PTRS2]] to <8 x i64>326// CHECK-NEXT: %[[DIFF:.*]] = sub <8 x i64> %[[P1INT]], %[[P2INT]]327// CHECK-NEXT: %[[TRUNC:.*]] = trunc <8 x i64> %[[DIFF]] to <8 x i32>328// CHECK-NEXT: ret <8 x i32> %[[TRUNC]]329// CHECK-NEXT: }330llvm.func @ptr_diff_vector_i32(%ptrs1: vector<8x!ptr.ptr<#llvm.address_space<0>>>, %ptrs2: vector<8x!ptr.ptr<#llvm.address_space<0>>>) -> vector<8xi32> {331 %diffs = ptr.ptr_diff %ptrs1, %ptrs2 : vector<8x!ptr.ptr<#llvm.address_space<0>>> -> vector<8xi32>332 llvm.return %diffs : vector<8xi32>333}334 335// CHECK-LABEL: define i64 @ptr_diff_with_constants() {336// CHECK-NEXT: ret i64 4096337// CHECK-NEXT: }338llvm.func @ptr_diff_with_constants() -> i64 {339 %ptr1 = ptr.constant #ptr.address<0x2000> : !ptr.ptr<#llvm.address_space<0>>340 %ptr2 = ptr.constant #ptr.address<0x1000> : !ptr.ptr<#llvm.address_space<0>>341 %diff = ptr.ptr_diff %ptr1, %ptr2 : !ptr.ptr<#llvm.address_space<0>> -> i64342 llvm.return %diff : i64343}344 345// CHECK-LABEL: define i64 @ptr_diff_with_flags_nsw346// CHECK-SAME: (ptr %[[PTR1:.*]], ptr %[[PTR2:.*]]) {347// CHECK-NEXT: %[[P1INT:.*]] = ptrtoaddr ptr %[[PTR1]] to i64348// CHECK-NEXT: %[[P2INT:.*]] = ptrtoaddr ptr %[[PTR2]] to i64349// CHECK-NEXT: %[[DIFF:.*]] = sub nsw i64 %[[P1INT]], %[[P2INT]]350// CHECK-NEXT: ret i64 %[[DIFF]]351// CHECK-NEXT: }352llvm.func @ptr_diff_with_flags_nsw(%ptr1: !ptr.ptr<#llvm.address_space<0>>, %ptr2: !ptr.ptr<#llvm.address_space<0>>) -> i64 {353 %diff = ptr.ptr_diff nsw %ptr1, %ptr2 : !ptr.ptr<#llvm.address_space<0>> -> i64354 llvm.return %diff : i64355}356 357// CHECK-LABEL: define i64 @ptr_diff_with_flags_nuw358// CHECK-SAME: (ptr %[[PTR1:.*]], ptr %[[PTR2:.*]]) {359// CHECK-NEXT: %[[P1INT:.*]] = ptrtoaddr ptr %[[PTR1]] to i64360// CHECK-NEXT: %[[P2INT:.*]] = ptrtoaddr ptr %[[PTR2]] to i64361// CHECK-NEXT: %[[DIFF:.*]] = sub nuw i64 %[[P1INT]], %[[P2INT]]362// CHECK-NEXT: ret i64 %[[DIFF]]363// CHECK-NEXT: }364llvm.func @ptr_diff_with_flags_nuw(%ptr1: !ptr.ptr<#llvm.address_space<0>>, %ptr2: !ptr.ptr<#llvm.address_space<0>>) -> i64 {365 %diff = ptr.ptr_diff nuw %ptr1, %ptr2 : !ptr.ptr<#llvm.address_space<0>> -> i64366 llvm.return %diff : i64367}368 369// CHECK-LABEL: define i64 @ptr_diff_with_flags_nsw_nuw370// CHECK-SAME: (ptr %[[PTR1:.*]], ptr %[[PTR2:.*]]) {371// CHECK-NEXT: %[[P1INT:.*]] = ptrtoaddr ptr %[[PTR1]] to i64372// CHECK-NEXT: %[[P2INT:.*]] = ptrtoaddr ptr %[[PTR2]] to i64373// CHECK-NEXT: %[[DIFF:.*]] = sub nuw nsw i64 %[[P1INT]], %[[P2INT]]374// CHECK-NEXT: ret i64 %[[DIFF]]375// CHECK-NEXT: }376llvm.func @ptr_diff_with_flags_nsw_nuw(%ptr1: !ptr.ptr<#llvm.address_space<0>>, %ptr2: !ptr.ptr<#llvm.address_space<0>>) -> i64 {377 %diff = ptr.ptr_diff nsw | nuw %ptr1, %ptr2 : !ptr.ptr<#llvm.address_space<0>> -> i64378 llvm.return %diff : i64379}380