340 lines · plain
1// RUN: mlir-opt %s -canonicalize="test-convergence" | FileCheck %s2 3// CHECK-LABEL: func @create_of_real_and_imag4// CHECK-SAME: (%[[CPLX:.*]]: complex<f32>)5func.func @create_of_real_and_imag(%cplx: complex<f32>) -> complex<f32> {6 // CHECK-NEXT: return %[[CPLX]] : complex<f32>7 %real = complex.re %cplx : complex<f32>8 %imag = complex.im %cplx : complex<f32>9 %complex = complex.create %real, %imag : complex<f32>10 return %complex : complex<f32>11}12 13// CHECK-LABEL: func @create_of_real_and_imag_different_operand14// CHECK-SAME: (%[[CPLX:.*]]: complex<f32>, %[[CPLX2:.*]]: complex<f32>)15func.func @create_of_real_and_imag_different_operand(16 %cplx: complex<f32>, %cplx2 : complex<f32>) -> complex<f32> {17 // CHECK-NEXT: %[[REAL:.*]] = complex.re %[[CPLX]] : complex<f32>18 // CHECK-NEXT: %[[IMAG:.*]] = complex.im %[[CPLX2]] : complex<f32>19 // CHECK-NEXT: %[[COMPLEX:.*]] = complex.create %[[REAL]], %[[IMAG]] : complex<f32>20 %real = complex.re %cplx : complex<f32>21 %imag = complex.im %cplx2 : complex<f32>22 %complex = complex.create %real, %imag : complex<f32>23 return %complex: complex<f32>24}25 26// CHECK-LABEL: func @real_of_const(27func.func @real_of_const() -> f32 {28 // CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f3229 // CHECK-NEXT: return %[[CST]] : f3230 %complex = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>31 %1 = complex.re %complex : complex<f32>32 return %1 : f3233}34 35// CHECK-LABEL: func @real_of_create_op(36func.func @real_of_create_op() -> f32 {37 // CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f3238 // CHECK-NEXT: return %[[CST]] : f3239 %real = arith.constant 1.0 : f3240 %imag = arith.constant 0.0 : f3241 %complex = complex.create %real, %imag : complex<f32>42 %1 = complex.re %complex : complex<f32>43 return %1 : f3244}45 46// CHECK-LABEL: func @imag_of_const(47func.func @imag_of_const() -> f32 {48 // CHECK: %[[CST:.*]] = arith.constant 0.000000e+00 : f3249 // CHECK-NEXT: return %[[CST]] : f3250 %complex = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>51 %1 = complex.im %complex : complex<f32>52 return %1 : f3253}54 55// CHECK-LABEL: func @imag_of_create_op(56func.func @imag_of_create_op() -> f32 {57 // CHECK: %[[CST:.*]] = arith.constant 0.000000e+00 : f3258 // CHECK-NEXT: return %[[CST]] : f3259 %real = arith.constant 1.0 : f3260 %imag = arith.constant 0.0 : f3261 %complex = complex.create %real, %imag : complex<f32>62 %1 = complex.im %complex : complex<f32>63 return %1 : f3264}65 66// CHECK-LABEL: func @complex_add_sub_lhs67func.func @complex_add_sub_lhs() -> complex<f32> {68 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>69 %complex2 = complex.constant [0.0 : f32, 2.0 : f32] : complex<f32>70 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>71 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>72 %sub = complex.sub %complex1, %complex2 : complex<f32>73 %add = complex.add %sub, %complex2 : complex<f32>74 return %add : complex<f32>75}76 77// CHECK-LABEL: func @complex_add_sub_rhs78func.func @complex_add_sub_rhs() -> complex<f32> {79 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>80 %complex2 = complex.constant [0.0 : f32, 2.0 : f32] : complex<f32>81 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>82 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>83 %sub = complex.sub %complex1, %complex2 : complex<f32>84 %add = complex.add %complex2, %sub : complex<f32>85 return %add : complex<f32>86}87 88// CHECK-LABEL: func @complex_neg_neg89func.func @complex_neg_neg() -> complex<f32> {90 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>91 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>92 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>93 %neg1 = complex.neg %complex1 : complex<f32>94 %neg2 = complex.neg %neg1 : complex<f32>95 return %neg2 : complex<f32>96}97 98// CHECK-LABEL: func @complex_log_exp99func.func @complex_log_exp() -> complex<f32> {100 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>101 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>102 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>103 %exp = complex.exp %complex1 : complex<f32>104 %log = complex.log %exp : complex<f32>105 return %log : complex<f32>106}107 108// CHECK-LABEL: func @complex_exp_log109func.func @complex_exp_log() -> complex<f32> {110 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>111 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>112 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>113 %log = complex.log %complex1 : complex<f32>114 %exp = complex.exp %log : complex<f32>115 return %exp : complex<f32>116}117 118// CHECK-LABEL: func @complex_conj_conj119func.func @complex_conj_conj() -> complex<f32> {120 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>121 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>122 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>123 %conj1 = complex.conj %complex1 : complex<f32>124 %conj2 = complex.conj %conj1 : complex<f32>125 return %conj2 : complex<f32>126}127 128// CHECK-LABEL: func @complex_add_zero129func.func @complex_add_zero() -> complex<f32> {130 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>131 %complex2 = complex.constant [0.0 : f32, 0.0 : f32] : complex<f32>132 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>133 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>134 %add = complex.add %complex1, %complex2 : complex<f32>135 return %add : complex<f32>136}137 138// CHECK-LABEL: func @complex_sub_add_lhs139func.func @complex_sub_add_lhs() -> complex<f32> {140 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>141 %complex2 = complex.constant [0.0 : f32, 2.0 : f32] : complex<f32>142 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>143 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>144 %add = complex.add %complex1, %complex2 : complex<f32>145 %sub = complex.sub %add, %complex2 : complex<f32>146 return %sub : complex<f32>147}148 149// CHECK-LABEL: func @complex_sub_zero150func.func @complex_sub_zero() -> complex<f32> {151 %complex1 = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>152 %complex2 = complex.constant [0.0 : f32, 0.0 : f32] : complex<f32>153 // CHECK: %[[CPLX:.*]] = complex.constant [1.000000e+00 : f32, 0.000000e+00 : f32] : complex<f32>154 // CHECK-NEXT: return %[[CPLX:.*]] : complex<f32>155 %sub = complex.sub %complex1, %complex2 : complex<f32>156 return %sub : complex<f32>157}158 159// CHECK-LABEL: func @re_neg160// CHECK-SAME: (%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32)161func.func @re_neg(%arg0: f32, %arg1: f32) -> f32 {162 %create = complex.create %arg0, %arg1: complex<f32>163 // CHECK: %[[NEG:.*]] = arith.negf %[[ARG0]]164 %neg = complex.neg %create : complex<f32>165 %re = complex.re %neg : complex<f32>166 // CHECK-NEXT: return %[[NEG]]167 return %re : f32168}169 170// CHECK-LABEL: func @im_neg171// CHECK-SAME: (%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32)172func.func @im_neg(%arg0: f32, %arg1: f32) -> f32 {173 %create = complex.create %arg0, %arg1: complex<f32>174 // CHECK: %[[NEG:.*]] = arith.negf %[[ARG1]]175 %neg = complex.neg %create : complex<f32>176 %im = complex.im %neg : complex<f32>177 // CHECK-NEXT: return %[[NEG]]178 return %im : f32179}180 181// CHECK-LABEL: func @mul_one_f16182// CHECK-SAME: (%[[ARG0:.*]]: f16, %[[ARG1:.*]]: f16) -> complex<f16>183func.func @mul_one_f16(%arg0: f16, %arg1: f16) -> complex<f16> {184 %create = complex.create %arg0, %arg1: complex<f16> 185 %one = complex.constant [1.0 : f16, 0.0 : f16] : complex<f16>186 %mul = complex.mul %create, %one : complex<f16>187 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f16>188 // CHECK-NEXT: return %[[CREATE]]189 return %mul : complex<f16>190}191 192// CHECK-LABEL: func @mul_one_f32193// CHECK-SAME: (%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32) -> complex<f32>194func.func @mul_one_f32(%arg0: f32, %arg1: f32) -> complex<f32> {195 %create = complex.create %arg0, %arg1: complex<f32> 196 %one = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>197 %mul = complex.mul %create, %one : complex<f32>198 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f32>199 // CHECK-NEXT: return %[[CREATE]]200 return %mul : complex<f32>201}202 203// CHECK-LABEL: func @mul_one_f64204// CHECK-SAME: (%[[ARG0:.*]]: f64, %[[ARG1:.*]]: f64) -> complex<f64>205func.func @mul_one_f64(%arg0: f64, %arg1: f64) -> complex<f64> {206 %create = complex.create %arg0, %arg1: complex<f64> 207 %one = complex.constant [1.0 : f64, 0.0 : f64] : complex<f64>208 %mul = complex.mul %create, %one : complex<f64>209 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f64>210 // CHECK-NEXT: return %[[CREATE]]211 return %mul : complex<f64>212}213 214// CHECK-LABEL: func @mul_one_f80215// CHECK-SAME: (%[[ARG0:.*]]: f80, %[[ARG1:.*]]: f80) -> complex<f80>216func.func @mul_one_f80(%arg0: f80, %arg1: f80) -> complex<f80> {217 %create = complex.create %arg0, %arg1: complex<f80> 218 %one = complex.constant [1.0 : f80, 0.0 : f80] : complex<f80>219 %mul = complex.mul %create, %one : complex<f80>220 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f80>221 // CHECK-NEXT: return %[[CREATE]]222 return %mul : complex<f80>223}224 225// CHECK-LABEL: func @mul_one_f128226// CHECK-SAME: (%[[ARG0:.*]]: f128, %[[ARG1:.*]]: f128) -> complex<f128>227func.func @mul_one_f128(%arg0: f128, %arg1: f128) -> complex<f128> {228 %create = complex.create %arg0, %arg1: complex<f128> 229 %one = complex.constant [1.0 : f128, 0.0 : f128] : complex<f128>230 %mul = complex.mul %create, %one : complex<f128>231 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f128>232 // CHECK-NEXT: return %[[CREATE]]233 return %mul : complex<f128>234}235 236// CHECK-LABEL: func @fold_between_complex237// CHECK-SAME: %[[ARG0:.*]]: complex<f32>238func.func @fold_between_complex(%arg0 : complex<f32>) -> complex<f32> {239 %0 = complex.bitcast %arg0 : complex<f32> to i64240 %1 = complex.bitcast %0 : i64 to complex<f32>241 // CHECK: return %[[ARG0]] : complex<f32>242 func.return %1 : complex<f32>243}244 245// CHECK-LABEL: func @fold_between_i64246// CHECK-SAME: %[[ARG0:.*]]: i64247func.func @fold_between_i64(%arg0 : i64) -> i64 {248 %0 = complex.bitcast %arg0 : i64 to complex<f32>249 %1 = complex.bitcast %0 : complex<f32> to i64250 // CHECK: return %[[ARG0]] : i64251 func.return %1 : i64252}253 254// CHECK-LABEL: func @canon_arith_bitcast255// CHECK-SAME: %[[ARG0:.*]]: f64256func.func @canon_arith_bitcast(%arg0 : f64) -> i64 {257 %0 = complex.bitcast %arg0 : f64 to complex<f32>258 %1 = complex.bitcast %0 : complex<f32> to i64259 // CHECK: %[[R0:.+]] = arith.bitcast %[[ARG0]]260 // CHECK: return %[[R0]] : i64261 func.return %1 : i64262}263 264 265// CHECK-LABEL: func @double_bitcast266// CHECK-SAME: %[[ARG0:.*]]: f64267func.func @double_bitcast(%arg0 : f64) -> complex<f32> {268 // CHECK: %[[R0:.+]] = complex.bitcast %[[ARG0]]269 %0 = arith.bitcast %arg0 : f64 to i64270 %1 = complex.bitcast %0 : i64 to complex<f32>271 // CHECK: return %[[R0]] : complex<f32>272 func.return %1 : complex<f32>273}274 275// CHECK-LABEL: func @double_reverse_bitcast276// CHECK-SAME: %[[ARG0:.*]]: complex<f32>277func.func @double_reverse_bitcast(%arg0 : complex<f32>) -> f64 {278 // CHECK: %[[R0:.+]] = complex.bitcast %[[ARG0]]279 %0 = complex.bitcast %arg0 : complex<f32> to i64280 %1 = arith.bitcast %0 : i64 to f64281 // CHECK: return %[[R0]] : f64282 func.return %1 : f64283}284 285 286// CHECK-LABEL: func @div_one_f16287// CHECK-SAME: (%[[ARG0:.*]]: f16, %[[ARG1:.*]]: f16) -> complex<f16>288func.func @div_one_f16(%arg0: f16, %arg1: f16) -> complex<f16> {289 %create = complex.create %arg0, %arg1: complex<f16> 290 %one = complex.constant [1.0 : f16, 0.0 : f16] : complex<f16>291 %div = complex.div %create, %one : complex<f16>292 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f16>293 // CHECK-NEXT: return %[[CREATE]]294 return %div : complex<f16>295}296 297// CHECK-LABEL: func @div_one_f32298// CHECK-SAME: (%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32) -> complex<f32>299func.func @div_one_f32(%arg0: f32, %arg1: f32) -> complex<f32> {300 %create = complex.create %arg0, %arg1: complex<f32> 301 %one = complex.constant [1.0 : f32, 0.0 : f32] : complex<f32>302 %div = complex.div %create, %one : complex<f32>303 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f32>304 // CHECK-NEXT: return %[[CREATE]]305 return %div : complex<f32>306}307 308// CHECK-LABEL: func @div_one_f64309// CHECK-SAME: (%[[ARG0:.*]]: f64, %[[ARG1:.*]]: f64) -> complex<f64>310func.func @div_one_f64(%arg0: f64, %arg1: f64) -> complex<f64> {311 %create = complex.create %arg0, %arg1: complex<f64> 312 %one = complex.constant [1.0 : f64, 0.0 : f64] : complex<f64>313 %div = complex.div %create, %one : complex<f64>314 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f64>315 // CHECK-NEXT: return %[[CREATE]]316 return %div : complex<f64>317}318 319// CHECK-LABEL: func @div_one_f80320// CHECK-SAME: (%[[ARG0:.*]]: f80, %[[ARG1:.*]]: f80) -> complex<f80>321func.func @div_one_f80(%arg0: f80, %arg1: f80) -> complex<f80> {322 %create = complex.create %arg0, %arg1: complex<f80> 323 %one = complex.constant [1.0 : f80, 0.0 : f80] : complex<f80>324 %div = complex.div %create, %one : complex<f80>325 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f80>326 // CHECK-NEXT: return %[[CREATE]]327 return %div : complex<f80>328}329 330// CHECK-LABEL: func @div_one_f128331// CHECK-SAME: (%[[ARG0:.*]]: f128, %[[ARG1:.*]]: f128) -> complex<f128>332func.func @div_one_f128(%arg0: f128, %arg1: f128) -> complex<f128> {333 %create = complex.create %arg0, %arg1: complex<f128> 334 %one = complex.constant [1.0 : f128, 0.0 : f128] : complex<f128>335 %div = complex.div %create, %one : complex<f128>336 // CHECK: %[[CREATE:.*]] = complex.create %[[ARG0]], %[[ARG1]] : complex<f128>337 // CHECK-NEXT: return %[[CREATE]]338 return %div : complex<f128>339}340