xref: /llvm-project/mlir/test/Dialect/Tosa/constant-reciprocal-fold.mlir (revision d84d418e2adc421c98e484ab3b09e2f4f3e5c1ef)
1// RUN: mlir-opt --split-input-file --tosa-layerwise-constant-fold %s | FileCheck %s
2
3// CHECK-LABEL: @reciprocal_fold_single_valued
4func.func @reciprocal_fold_single_valued() -> tensor<f32> {
5  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}2.5{{0*}}e-01{{.*}}tensor<f32>
6  // CHECK-NOT: tosa.reciprocal
7  // CHECK: return [[RES]]
8  %0 = "tosa.const"() {value = dense<4.0> : tensor<f32>} : () -> tensor<f32>
9  %1 = "tosa.reciprocal"(%0) : (tensor<f32>) -> tensor<f32>
10  return %1 : tensor<f32>
11}
12
13// CHECK-LABEL: @reciprocal_fold_splat
14func.func @reciprocal_fold_splat() -> tensor<12x7xf32> {
15  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}2.5{{0*}}e-01{{.*}}tensor<12x7xf32>
16  // CHECK-NOT: tosa.reciprocal
17  // CHECK: return [[RES]]
18  %0 = "tosa.const"() {value = dense<4.0> : tensor<12x7xf32>} : () -> tensor<12x7xf32>
19  %1 = "tosa.reciprocal"(%0) : (tensor<12x7xf32>) -> tensor<12x7xf32>
20  return %1 : tensor<12x7xf32>
21}
22
23// CHECK-LABEL: @reciprocal_div_zero
24func.func @reciprocal_div_zero() -> tensor<f32> {
25  // 0x7F800000 is the value for +infinity
26  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}0x7F800000
27  // CHECK-NOT: tosa.reciprocal
28  // CHECK: return [[RES]]
29  %0 = "tosa.const"() {value = dense<0.0> : tensor<f32>} : () -> tensor<f32>
30  %1 = "tosa.reciprocal"(%0) : (tensor<f32>) -> tensor<f32>
31  return %1 : tensor<f32>
32}
33
34// CHECK-LABEL: @reciprocal_div_neg_zero
35func.func @reciprocal_div_neg_zero() -> tensor<f32> {
36  // 0xFF800000 is the value for -infinity
37  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}0xFF800000
38  // CHECK-NOT: tosa.reciprocal
39  // CHECK: return [[RES]]
40  %0 = "tosa.const"() {value = dense<-0.0> : tensor<f32>} : () -> tensor<f32>
41  %1 = "tosa.reciprocal"(%0) : (tensor<f32>) -> tensor<f32>
42  return %1 : tensor<f32>
43}
44
45// CHECK-LABEL: @reciprocal_div_nan
46func.func @reciprocal_div_nan() -> tensor<f32> {
47  // 0x7FC00000 is the value for NAN
48  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}0x7FC00000
49  // CHECK-NOT: tosa.reciprocal
50  // CHECK: return [[RES]]
51  %0 = "tosa.const"() {value = dense<0x7FC00000> : tensor<f32>} : () -> tensor<f32>
52  %1 = "tosa.reciprocal"(%0) : (tensor<f32>) -> tensor<f32>
53  return %1 : tensor<f32>
54}
55
56// CHECK-LABEL: @reciprocal_div_infinity
57func.func @reciprocal_div_infinity() -> tensor<f32> {
58  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}<0.{{0*}}e+00>
59  // CHECK-NOT: tosa.reciprocal
60  // CHECK: return [[RES]]
61  %0 = "tosa.const"() {value = dense<0x7F800000> : tensor<f32>} : () -> tensor<f32>
62  %1 = "tosa.reciprocal"(%0) : (tensor<f32>) -> tensor<f32>
63  return %1 : tensor<f32>
64}
65
66// CHECK-LABEL: @reciprocal_div_neg_infinity
67func.func @reciprocal_div_neg_infinity() -> tensor<f32> {
68  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}<-0.{{0*}}e+00>
69  // CHECK-NOT: tosa.reciprocal
70  // CHECK: return [[RES]]
71  %0 = "tosa.const"() {value = dense<0xFF800000> : tensor<f32>} : () -> tensor<f32>
72  %1 = "tosa.reciprocal"(%0) : (tensor<f32>) -> tensor<f32>
73  return %1 : tensor<f32>
74}
75
76// CHECK-LABEL: @reciprocal_div_underflow
77func.func @reciprocal_div_underflow() -> tensor<2xf16> {
78  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}-0.{{0*}}e+00, 0.{{0*}}e+00
79  // CHECK-NOT: tosa.reciprocal
80  // CHECK: return [[RES]]
81  %0 = "tosa.const"() {value = dense<[-6.0e+15, 6.0e+15]> : tensor<2xf16>} : () -> tensor<2xf16>
82  %1 = "tosa.reciprocal"(%0) : (tensor<2xf16>) -> tensor<2xf16>
83  return %1 : tensor<2xf16>
84}
85
86// CHECK-LABEL: @reciprocal_div_overflow
87func.func @reciprocal_div_overflow() -> tensor<2xf16> {
88  // CHECK: [[RES:]] ={{.*}}tosa.const{{.*}}0x7C00, 0xFC00
89  // CHECK-NOT: tosa.reciprocal
90  // CHECK: return [[RES]]
91  %0 = "tosa.const"() {value = dense<[0.0000001, -0.0000001]> : tensor<2xf16>} : () -> tensor<2xf16>
92  %1 = "tosa.reciprocal"(%0) : (tensor<2xf16>) -> tensor<2xf16>
93  return %1 : tensor<2xf16>
94}
95
96// CHECK-LABEL: @reciprocal_no_fold
97// The folding optimization works only intra-procedurally, so we won't be able
98// to fold anything here
99func.func @reciprocal_no_fold(%arg0: tensor<?x?xf32>) -> tensor<?x?xf32> {
100  // CHECK: tosa.reciprocal
101  // CHECK-NEXT: return
102  %0 = "tosa.reciprocal"(%arg0) : (tensor<?x?xf32>) -> tensor<?x?xf32>
103  return %0 : tensor<?x?xf32>
104}
105
106// CHECK-LABEL: @reciprocal_fold
107func.func @reciprocal_fold() -> tensor<4x6xf32> {
108  // CHECK: [[RES:]] ={{.*}}tosa.const
109  // CHECK-SAME{LITERAL}: [[5.68828249, 11.4416485, 1.6880486, 0.680272102, -0.875350117, 0.342313349],
110  // CHECK-SAME{LITERAL}:  [-4.81231928, 0.698080301, 0.65432179, -82.6446304, -4.33651352, -0.747551739],
111  // CHECK-SAME{LITERAL}:  [-12.4378109, 13.140605, 1.89501607, 0.885582745, 4.08830738, 1.4396776],
112  // CHECK-SAME{LITERAL}:  [2.02880907, -1.53280187, 0.552730501, 7.15819644, 0.64495325, -0.973709881]]
113  // CHECK-NOT: tosa.reciprocal
114  // CHECK: return [[RES]]
115  %0 = "tosa.const"() { value = dense<[
116                        [ 0.1758,  0.0874,  0.5924,  1.4700, -1.1424,  2.9213],
117                        [-0.2078,  1.4325,  1.5283, -0.0121, -0.2306, -1.3377],
118                        [-0.0804,  0.0761,  0.5277,  1.1292,  0.2446,  0.6946],
119                        [ 0.4929, -0.6524,  1.8092,  0.1397,  1.5505, -1.0270]]>
120                        : tensor<4x6xf32>
121                      } : () -> tensor<4x6xf32>
122  %1 = "tosa.reciprocal"(%0) : (tensor<4x6xf32>) -> tensor<4x6xf32>
123  return %1 : tensor<4x6xf32>
124}
125
126// CHECK-LABEL: @reciprocal_of_const_sparse
127// Sparse tensors are currently not supported
128func.func @reciprocal_of_const_sparse() -> tensor<32xbf16> {
129  // CHECK: tosa.const
130  // CHECK: tosa.reciprocal
131    %0 = "tosa.const"() { value = sparse<
132          [[0], [3], [11], [17], [20], [23], [25], [30], [31]],
133          [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]>
134          : tensor<32xbf16> } : () -> tensor<32xbf16>
135    %1 = "tosa.reciprocal"(%0) : (tensor<32xbf16>) -> tensor<32xbf16>
136    return %1 : tensor<32xbf16>
137}
138