122 lines · plain
1// RUN: mlir-opt --canonicalize %s | FileCheck %s2 3/// Check `ptr_add` canonicalizer patterns.4 5// CHECK-LABEL: @zero_offset6// CHECK-SAME: (%[[PTR_0:.*]]: !ptr.ptr<#ptr.generic_space>)7func.func @zero_offset(%ptr: !ptr.ptr<#ptr.generic_space>) -> !ptr.ptr<#ptr.generic_space> {8 // CHECK-NOT: index.constant9 // CHECK-NOT: ptr.ptr_add10 // CHECK: return %[[PTR_0]] : !ptr.ptr<#ptr.generic_space>11 // CHECK: }12 %off = index.constant 013 %res0 = ptr.ptr_add %ptr, %off : !ptr.ptr<#ptr.generic_space>, index14 return %res0 : !ptr.ptr<#ptr.generic_space>15}16 17/// Tests the the `from_ptr` folder.18// CHECK-LABEL: @test_from_ptr_019// CHECK-SAME: (%[[MEM_REF:.*]]: memref<f32, #ptr.generic_space>)20func.func @test_from_ptr_0(%mr: memref<f32, #ptr.generic_space>) -> memref<f32, #ptr.generic_space> {21 // CHECK-NOT: ptr.to_ptr22 // CHECK-NOT: ptr.get_metadata23 // CHECK-NOT: ptr.from_ptr24 // CHECK: return %[[MEM_REF]]25 %ptr = ptr.to_ptr %mr : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>26 %mda = ptr.get_metadata %mr : memref<f32, #ptr.generic_space>27 %res = ptr.from_ptr %ptr metadata %mda : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>28 return %res : memref<f32, #ptr.generic_space>29}30 31/// Check the op doesn't fold because folding a ptr-type with metadata requires knowing the origin of the metadata.32// CHECK-LABEL: @test_from_ptr_133// CHECK-SAME: (%[[MEM_REF:.*]]: memref<f32, #ptr.generic_space>)34func.func @test_from_ptr_1(%mr: memref<f32, #ptr.generic_space>) -> memref<f32, #ptr.generic_space> {35 // CHECK: ptr.to_ptr36 // CHECK: ptr.from_ptr37 %ptr = ptr.to_ptr %mr : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>38 %res = ptr.from_ptr %ptr : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>39 return %res : memref<f32, #ptr.generic_space>40}41 42/// Check that the ops cannot be folded because the metadata cannot be guaranteed to be the same.43// CHECK-LABEL: @test_from_ptr_244func.func @test_from_ptr_2(%mr: memref<f32, #ptr.generic_space>, %md: !ptr.ptr_metadata<memref<f32, #ptr.generic_space>>) -> memref<f32, #ptr.generic_space> {45 // CHECK: ptr.to_ptr46 // CHECK: ptr.from_ptr47 %ptr = ptr.to_ptr %mr : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>48 %res = ptr.from_ptr %ptr metadata %md : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>49 return %res : memref<f32, #ptr.generic_space>50}51 52// Check the folding of `to_ptr -> from_ptr` chains.53// CHECK-LABEL: @test_from_ptr_354// CHECK-SAME: (%[[MEM_REF:.*]]: memref<f32, #ptr.generic_space>)55func.func @test_from_ptr_3(%mr0: memref<f32, #ptr.generic_space>) -> memref<f32, #ptr.generic_space> {56 // CHECK-NOT: ptr.to_ptr57 // CHECK-NOT: ptr.from_ptr58 // CHECK: return %[[MEM_REF]]59 %mda = ptr.get_metadata %mr0 : memref<f32, #ptr.generic_space>60 %ptr0 = ptr.to_ptr %mr0 : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>61 %mrf0 = ptr.from_ptr %ptr0 metadata %mda : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>62 %ptr1 = ptr.to_ptr %mrf0 : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>63 %mrf1 = ptr.from_ptr %ptr1 metadata %mda : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>64 return %mrf1 : memref<f32, #ptr.generic_space>65}66 67/// Tests the the `to_ptr` folder.68// CHECK-LABEL: @test_to_ptr_069// CHECK-SAME: (%[[PTR:.*]]: !ptr.ptr<#ptr.generic_space>70func.func @test_to_ptr_0(%ptr: !ptr.ptr<#ptr.generic_space>, %md: !ptr.ptr_metadata<memref<f32, #ptr.generic_space>>) -> !ptr.ptr<#ptr.generic_space> {71 // CHECK: return %[[PTR]]72 // CHECK-NOT: ptr.from_ptr73 // CHECK-NOT: ptr.to_ptr74 %mrf = ptr.from_ptr %ptr metadata %md : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>75 %res = ptr.to_ptr %mrf : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>76 return %res : !ptr.ptr<#ptr.generic_space>77}78 79// CHECK-LABEL: @test_to_ptr_180// CHECK-SAME: (%[[PTR:.*]]: !ptr.ptr<#ptr.generic_space>)81func.func @test_to_ptr_1(%ptr: !ptr.ptr<#ptr.generic_space>) -> !ptr.ptr<#ptr.generic_space> {82 // CHECK-NOT: ptr.from_ptr83 // CHECK-NOT: ptr.to_ptr84 // CHECK: return %[[PTR]]85 %mrf = ptr.from_ptr %ptr : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>86 %res = ptr.to_ptr %mrf : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>87 return %res : !ptr.ptr<#ptr.generic_space>88}89 90// Check the folding of `from_ptr -> to_ptr` chains.91// CHECK-LABEL: @test_to_ptr_292// CHECK-SAME: (%[[PTR:.*]]: !ptr.ptr<#ptr.generic_space>93func.func @test_to_ptr_2(%ptr0: !ptr.ptr<#ptr.generic_space>) -> !ptr.ptr<#ptr.generic_space> {94 // CHECK-NOT: ptr.from_ptr95 // CHECK-NOT: ptr.to_ptr96 // CHECK: return %[[PTR]]97 %mrf0 = ptr.from_ptr %ptr0 : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>98 %ptr1 = ptr.to_ptr %mrf0 : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>99 %mrf1 = ptr.from_ptr %ptr1 : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>100 %ptr2 = ptr.to_ptr %mrf1 : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>101 %mrf2 = ptr.from_ptr %ptr2 : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>102 %res = ptr.to_ptr %mrf2 : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>103 return %res : !ptr.ptr<#ptr.generic_space>104}105 106// Check the folding of chains with different metadata.107// CHECK-LABEL: @test_cast_chain_folding108// CHECK-SAME: (%[[MEM_REF:.*]]: memref<f32, #ptr.generic_space>109func.func @test_cast_chain_folding(%mr: memref<f32, #ptr.generic_space>, %md: !ptr.ptr_metadata<memref<f32, #ptr.generic_space>>) -> memref<f32, #ptr.generic_space> {110 // CHECK-NOT: ptr.to_ptr111 // CHECK-NOT: ptr.from_ptr112 // CHECK: return %[[MEM_REF]]113 %ptr1 = ptr.to_ptr %mr : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>114 %memrefWithOtherMd = ptr.from_ptr %ptr1 metadata %md : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>115 %ptr = ptr.to_ptr %memrefWithOtherMd : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>116 %mda = ptr.get_metadata %mr : memref<f32, #ptr.generic_space>117 // The chain can be folded because: the ptr always has the same value because118 // `to_ptr` is a loss-less cast and %mda comes from the original memref.119 %res = ptr.from_ptr %ptr metadata %mda : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>120 return %res : memref<f32, #ptr.generic_space>121}122